1 /* 2 * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA 3 * - www.ehima.com 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #pragma once 19 20 #include <map> 21 #include <memory> 22 #include <optional> 23 #include <tuple> 24 #include <vector> 25 26 #ifdef __ANDROID__ 27 #include <android/sysprop/BluetoothProperties.sysprop.h> 28 #endif 29 30 #include "audio_hal_client/audio_hal_client.h" 31 #include "bt_types.h" 32 #include "bta_groups.h" 33 #include "btm_iso_api_types.h" 34 #include "gatt_api.h" 35 #include "gd/common/strings.h" 36 #include "le_audio_log_history.h" 37 #include "le_audio_types.h" 38 #include "osi/include/alarm.h" 39 #include "osi/include/properties.h" 40 #include "raw_address.h" 41 42 namespace le_audio { 43 44 // Maps to BluetoothProfile#LE_AUDIO 45 #define LE_AUDIO_PROFILE_CONSTANT 22 46 47 /* Enums */ 48 enum class DeviceConnectState : uint8_t { 49 /* Initial state */ 50 DISCONNECTED, 51 /* When ACL connected, encrypted, CCC registered and initial characteristics 52 read is completed */ 53 CONNECTED, 54 /* Used when device is unbonding (RemoveDevice() API is called) */ 55 REMOVING, 56 /* Disconnecting */ 57 DISCONNECTING, 58 /* Disconnecting for recover - after that we want direct connect to be 59 initiated */ 60 DISCONNECTING_AND_RECOVER, 61 /* Device will be removed after scheduled action is finished: One of such 62 * action is taking Stream to IDLE 63 */ 64 PENDING_REMOVAL, 65 /* 2 states below are used when user creates connection. Connect API is 66 called. */ 67 CONNECTING_BY_USER, 68 /* Always used after CONNECTING_BY_USER */ 69 CONNECTED_BY_USER_GETTING_READY, 70 /* 2 states are used when autoconnect was used for the connection.*/ 71 CONNECTING_AUTOCONNECT, 72 /* Always used after CONNECTING_AUTOCONNECT */ 73 CONNECTED_AUTOCONNECT_GETTING_READY, 74 }; 75 76 std::ostream& operator<<(std::ostream& os, const DeviceConnectState& state); 77 78 /* Class definitions */ 79 80 /* LeAudioDevice class represents GATT server device with ASCS, PAC services as 81 * mandatory. Device may contain multiple ASEs, PACs, audio locations. ASEs from 82 * multiple devices may be formed in group. 83 * 84 * Device is created after connection or after storage restoration. 85 * 86 * Active device means that device has at least one ASE which will participate 87 * in any state transition of state machine. ASEs and devices will be activated 88 * according to requested by upper context type. 89 */ 90 class LeAudioDevice { 91 public: 92 RawAddress address_; 93 94 DeviceConnectState connection_state_; 95 bool known_service_handles_; 96 bool notify_connected_after_read_; 97 bool closing_stream_for_disconnection_; 98 bool autoconnect_flag_; 99 uint16_t conn_id_; 100 uint16_t mtu_; 101 bool encrypted_; 102 int group_id_; 103 bool csis_member_; 104 std::bitset<16> tmap_role_; 105 106 uint8_t audio_directions_; 107 types::AudioLocations snk_audio_locations_; 108 types::AudioLocations src_audio_locations_; 109 110 types::PublishedAudioCapabilities snk_pacs_; 111 types::PublishedAudioCapabilities src_pacs_; 112 113 struct types::hdl_pair snk_audio_locations_hdls_; 114 struct types::hdl_pair src_audio_locations_hdls_; 115 struct types::hdl_pair audio_avail_hdls_; 116 struct types::hdl_pair audio_supp_cont_hdls_; 117 std::vector<struct types::ase> ases_; 118 struct types::hdl_pair ctp_hdls_; 119 uint16_t tmap_role_hdl_; 120 121 alarm_t* link_quality_timer; 122 uint16_t link_quality_timer_data; 123 124 LeAudioDevice(const RawAddress& address_, DeviceConnectState state, 125 int group_id = bluetooth::groups::kGroupUnknown) address_(address_)126 : address_(address_), 127 connection_state_(state), 128 known_service_handles_(false), 129 notify_connected_after_read_(false), 130 closing_stream_for_disconnection_(false), 131 autoconnect_flag_(false), 132 conn_id_(GATT_INVALID_CONN_ID), 133 mtu_(0), 134 encrypted_(false), 135 group_id_(group_id), 136 csis_member_(false), 137 audio_directions_(0), 138 link_quality_timer(nullptr) {} 139 ~LeAudioDevice(void); 140 141 void SetConnectionState(DeviceConnectState state); 142 DeviceConnectState GetConnectionState(void); 143 void ClearPACs(void); 144 void RegisterPACs(std::vector<struct types::acs_ac_record>* apr_db, 145 std::vector<struct types::acs_ac_record>* apr); 146 struct types::ase* GetAseByValHandle(uint16_t val_hdl); 147 int GetAseCount(uint8_t direction); 148 struct types::ase* GetFirstActiveAse(void); 149 struct types::ase* GetFirstActiveAseByDirection(uint8_t direction); 150 struct types::ase* GetNextActiveAseWithSameDirection( 151 struct types::ase* base_ase); 152 struct types::ase* GetNextActiveAseWithDifferentDirection( 153 struct types::ase* base_ase); 154 struct types::ase* GetFirstActiveAseByDataPathState( 155 types::AudioStreamDataPathState state); 156 struct types::ase* GetFirstInactiveAse(uint8_t direction, 157 bool reconnect = false); 158 struct types::ase* GetFirstAseWithState(uint8_t direction, 159 types::AseState state); 160 struct types::ase* GetNextActiveAse(struct types::ase* ase); 161 struct types::ase* GetAseToMatchBidirectionCis(struct types::ase* ase); 162 types::BidirectAsesPair GetAsesByCisConnHdl(uint16_t conn_hdl); 163 types::BidirectAsesPair GetAsesByCisId(uint8_t cis_id); 164 bool HaveActiveAse(void); 165 bool HaveAllActiveAsesSameState(types::AseState state); 166 bool HaveAnyUnconfiguredAses(void); 167 bool IsReadyToCreateStream(void); 168 bool IsReadyToSuspendStream(void); 169 bool HaveAllActiveAsesCisEst(void); 170 bool HaveAnyCisConnected(void); 171 bool HasCisId(uint8_t id); 172 uint8_t GetMatchingBidirectionCisId(const struct types::ase* base_ase); 173 const struct types::acs_ac_record* GetCodecConfigurationSupportedPac( 174 uint8_t direction, const set_configurations::CodecCapabilitySetting& 175 codec_capability_setting); 176 uint8_t GetLc3SupportedChannelCount(uint8_t direction); 177 uint8_t GetPhyBitmask(void); 178 bool ConfigureAses( 179 const le_audio::set_configurations::SetConfiguration& ent, 180 types::LeAudioContextType context_type, 181 uint8_t* number_of_already_active_group_ase, 182 types::BidirectionalPair<types::AudioLocations>& 183 group_audio_locations_out, 184 const types::BidirectionalPair<types::AudioContexts>& 185 metadata_context_types, 186 const types::BidirectionalPair<std::vector<uint8_t>>& ccid_lists, 187 bool reuse_cis_id); 188 void SetSupportedContexts(types::AudioContexts snk_contexts, 189 types::AudioContexts src_contexts); 190 inline types::AudioContexts GetAvailableContexts( 191 int direction = (types::kLeAudioDirectionSink | 192 types::kLeAudioDirectionSource)) { 193 return avail_contexts_.get(direction); 194 } 195 types::AudioContexts SetAvailableContexts(types::AudioContexts snk_cont_val, 196 types::AudioContexts src_cont_val); 197 void DeactivateAllAses(void); 198 bool ActivateConfiguredAses(types::LeAudioContextType context_type); 199 200 void PrintDebugState(void); 201 void DumpPacsDebugState(std::stringstream& stream); 202 void Dump(int fd); 203 204 void DisconnectAcl(void); 205 std::vector<uint8_t> GetMetadata(types::AudioContexts context_type, 206 const std::vector<uint8_t>& ccid_list); 207 bool IsMetadataChanged( 208 const types::BidirectionalPair<types::AudioContexts>& context_types, 209 const types::BidirectionalPair<std::vector<uint8_t>>& ccid_lists); 210 211 private: 212 types::BidirectionalPair<types::AudioContexts> avail_contexts_; 213 types::BidirectionalPair<types::AudioContexts> supp_contexts_; 214 215 void DumpPacsDebugState(std::stringstream& stream, 216 types::PublishedAudioCapabilities pacs); 217 }; 218 219 /* LeAudioDevices class represents a wraper helper over all devices in le audio 220 * implementation. It allows to operate on device from a list (vector container) 221 * using determinants like address, connection id etc. 222 */ 223 class LeAudioDevices { 224 public: 225 void Add(const RawAddress& address, le_audio::DeviceConnectState state, 226 int group_id = bluetooth::groups::kGroupUnknown); 227 void Remove(const RawAddress& address); 228 LeAudioDevice* FindByAddress(const RawAddress& address); 229 std::shared_ptr<LeAudioDevice> GetByAddress(const RawAddress& address); 230 LeAudioDevice* FindByConnId(uint16_t conn_id); 231 LeAudioDevice* FindByCisConnHdl(uint8_t cig_id, uint16_t conn_hdl); 232 void SetInitialGroupAutoconnectState(int group_id, int gatt_if, 233 tBTM_BLE_CONN_TYPE reconnection_mode, 234 bool current_dev_autoconnect_flag); 235 size_t Size(void); 236 void Dump(int fd, int group_id); 237 void Cleanup(tGATT_IF client_if); 238 239 private: 240 std::vector<std::shared_ptr<LeAudioDevice>> leAudioDevices_; 241 }; 242 243 /* LeAudioDeviceGroup class represents group of LeAudioDevices and allows to 244 * perform operations on them. Group states are ASE states due to nature of 245 * group which operates finally of ASEs. 246 * 247 * Group is created after adding a node to new group id (which is not on list). 248 */ 249 250 class LeAudioDeviceGroup { 251 public: 252 const int group_id_; 253 bool enabled_; 254 types::CigState cig_state_; 255 256 struct stream_configuration stream_conf; 257 258 uint8_t audio_directions_; 259 types::AudioLocations snk_audio_locations_; 260 types::AudioLocations src_audio_locations_; 261 262 /* Whether LE Audio is preferred for OUTPUT_ONLY and DUPLEX cases */ 263 bool is_output_preference_le_audio; 264 bool is_duplex_preference_le_audio; 265 266 std::vector<struct types::cis> cises_; LeAudioDeviceGroup(const int group_id)267 explicit LeAudioDeviceGroup(const int group_id) 268 : group_id_(group_id), 269 enabled_(true), 270 cig_state_(types::CigState::NONE), 271 stream_conf({}), 272 audio_directions_(0), 273 transport_latency_mtos_us_(0), 274 transport_latency_stom_us_(0), 275 configuration_context_type_(types::LeAudioContextType::UNINITIALIZED), 276 metadata_context_type_({.sink = types::AudioContexts( 277 types::LeAudioContextType::UNINITIALIZED), 278 .source = types::AudioContexts( 279 types::LeAudioContextType::UNINITIALIZED)}), 280 group_available_contexts_(types::LeAudioContextType::UNINITIALIZED), 281 pending_group_available_contexts_change_( 282 types::LeAudioContextType::UNINITIALIZED), 283 target_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE), 284 current_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) { 285 #ifdef __ANDROID__ 286 // 22 maps to BluetoothProfile#LE_AUDIO 287 is_output_preference_le_audio = android::sysprop::BluetoothProperties:: 288 getDefaultOutputOnlyAudioProfile() == 289 LE_AUDIO_PROFILE_CONSTANT; 290 is_duplex_preference_le_audio = 291 android::sysprop::BluetoothProperties::getDefaultDuplexAudioProfile() == 292 LE_AUDIO_PROFILE_CONSTANT; 293 #else 294 is_output_preference_le_audio = true; 295 is_duplex_preference_le_audio = true; 296 #endif 297 } 298 ~LeAudioDeviceGroup(void); 299 300 void AddNode(const std::shared_ptr<LeAudioDevice>& leAudioDevice); 301 void RemoveNode(const std::shared_ptr<LeAudioDevice>& leAudioDevice); 302 bool IsEmpty(void); 303 bool IsAnyDeviceConnected(void); 304 int Size(void); 305 int NumOfConnected( 306 types::LeAudioContextType context_type = types::LeAudioContextType::RFU); 307 bool Activate(types::LeAudioContextType context_type); 308 void Deactivate(void); 309 types::CigState GetCigState(void); 310 void SetCigState(le_audio::types::CigState state); 311 void CigClearCis(void); 312 void ClearSinksFromConfiguration(void); 313 void ClearSourcesFromConfiguration(void); 314 void Cleanup(void); 315 LeAudioDevice* GetFirstDevice(void); 316 LeAudioDevice* GetFirstDeviceWithActiveContext( 317 types::LeAudioContextType context_type); 318 le_audio::types::LeAudioConfigurationStrategy GetGroupStrategy( 319 int expected_group_size); 320 int GetAseCount(uint8_t direction); 321 LeAudioDevice* GetNextDevice(LeAudioDevice* leAudioDevice); 322 LeAudioDevice* GetNextDeviceWithActiveContext( 323 LeAudioDevice* leAudioDevice, types::LeAudioContextType context_type); 324 LeAudioDevice* GetFirstActiveDevice(void); 325 LeAudioDevice* GetNextActiveDevice(LeAudioDevice* leAudioDevice); 326 LeAudioDevice* GetFirstActiveDeviceByDataPathState( 327 types::AudioStreamDataPathState data_path_state); 328 LeAudioDevice* GetNextActiveDeviceByDataPathState( 329 LeAudioDevice* leAudioDevice, 330 types::AudioStreamDataPathState data_path_state); 331 bool IsDeviceInTheGroup(LeAudioDevice* leAudioDevice); 332 bool HaveAllActiveDevicesAsesTheSameState(types::AseState state); 333 bool HaveAnyActiveDeviceInUnconfiguredState(); 334 bool IsGroupStreamReady(void); 335 bool IsGroupReadyToCreateStream(void); 336 bool IsGroupReadyToSuspendStream(void); 337 bool HaveAllCisesDisconnected(void); 338 uint8_t GetFirstFreeCisId(void); 339 uint8_t GetFirstFreeCisId(types::CisType cis_type); 340 void CigGenerateCisIds(types::LeAudioContextType context_type); 341 bool CigAssignCisIds(LeAudioDevice* leAudioDevice); 342 void CigAssignCisConnHandles(const std::vector<uint16_t>& conn_handles); 343 void CigAssignCisConnHandlesToAses(LeAudioDevice* leAudioDevice); 344 void CigAssignCisConnHandlesToAses(void); 345 void CigUnassignCis(LeAudioDevice* leAudioDevice); 346 bool Configure(types::LeAudioContextType context_type, 347 const types::BidirectionalPair<types::AudioContexts>& 348 metadata_context_types, 349 types::BidirectionalPair<std::vector<uint8_t>> ccid_lists = { 350 .sink = {}, .source = {}}); 351 uint32_t GetSduInterval(uint8_t direction); 352 uint8_t GetSCA(void); 353 uint8_t GetPacking(void); 354 uint8_t GetFraming(void); 355 uint16_t GetMaxTransportLatencyStom(void); 356 uint16_t GetMaxTransportLatencyMtos(void); 357 void SetTransportLatency(uint8_t direction, uint32_t transport_latency_us); 358 uint8_t GetRtn(uint8_t direction, uint8_t cis_id); 359 uint16_t GetMaxSduSize(uint8_t direction, uint8_t cis_id); 360 uint8_t GetPhyBitmask(uint8_t direction); 361 uint8_t GetTargetPhy(uint8_t direction); 362 bool GetPresentationDelay(uint32_t* delay, uint8_t direction); 363 uint16_t GetRemoteDelay(uint8_t direction); 364 bool UpdateAudioContextTypeAvailability(types::AudioContexts contexts); 365 void UpdateAudioContextTypeAvailability(void); 366 bool ReloadAudioLocations(void); 367 bool ReloadAudioDirections(void); 368 const set_configurations::AudioSetConfiguration* GetActiveConfiguration(void); 369 bool IsPendingConfiguration(void); 370 void SetPendingConfiguration(void); 371 void ClearPendingConfiguration(void); 372 void AddToAllowListNotConnectedGroupMembers(int gatt_if); 373 void Disable(int gatt_if); 374 void Enable(int gatt_if, tBTM_BLE_CONN_TYPE reconnection_mode); 375 bool IsEnabled(void); 376 bool IsConfigurationSupported( 377 LeAudioDevice* leAudioDevice, 378 const set_configurations::AudioSetConfiguration* audio_set_conf); 379 std::optional<LeAudioCodecConfiguration> GetCodecConfigurationByDirection( 380 types::LeAudioContextType group_context_type, uint8_t direction) const; 381 bool IsContextSupported(types::LeAudioContextType group_context_type); 382 bool IsMetadataChanged( 383 const types::BidirectionalPair<types::AudioContexts>& context_types, 384 const types::BidirectionalPair<std::vector<uint8_t>>& ccid_lists); 385 void CreateStreamVectorForOffloader(uint8_t direction); 386 void StreamOffloaderUpdated(uint8_t direction); 387 GetState(void)388 inline types::AseState GetState(void) const { return current_state_; } SetState(types::AseState state)389 void SetState(types::AseState state) { 390 LOG(INFO) << __func__ << " current state: " << current_state_ 391 << " new state: " << state; 392 LeAudioLogHistory::Get()->AddLogHistory( 393 kLogStateMachineTag, group_id_, RawAddress::kEmpty, kLogStateChangedOp, 394 bluetooth::common::ToString(current_state_) + "->" + 395 bluetooth::common::ToString(state)); 396 current_state_ = state; 397 } 398 GetTargetState(void)399 inline types::AseState GetTargetState(void) const { return target_state_; } SetTargetState(types::AseState state)400 void SetTargetState(types::AseState state) { 401 LOG(INFO) << __func__ << " target state: " << target_state_ 402 << " new target state: " << state; 403 LeAudioLogHistory::Get()->AddLogHistory( 404 kLogStateMachineTag, group_id_, RawAddress::kEmpty, 405 kLogTargetStateChangedOp, 406 bluetooth::common::ToString(target_state_) + "->" + 407 bluetooth::common::ToString(state)); 408 target_state_ = state; 409 } 410 411 /* Returns context types for which support was recently added or removed */ GetPendingAvailableContextsChange()412 inline types::AudioContexts GetPendingAvailableContextsChange() const { 413 return pending_group_available_contexts_change_; 414 } 415 416 /* Set which context types were recently added or removed */ SetPendingAvailableContextsChange(types::AudioContexts audio_contexts)417 inline void SetPendingAvailableContextsChange( 418 types::AudioContexts audio_contexts) { 419 pending_group_available_contexts_change_ = audio_contexts; 420 } 421 ClearPendingAvailableContextsChange()422 inline void ClearPendingAvailableContextsChange() { 423 pending_group_available_contexts_change_.clear(); 424 } 425 GetConfigurationContextType(void)426 inline types::LeAudioContextType GetConfigurationContextType(void) const { 427 return configuration_context_type_; 428 } 429 GetMetadataContexts()430 inline types::BidirectionalPair<types::AudioContexts> GetMetadataContexts() 431 const { 432 return metadata_context_type_; 433 } 434 GetAvailableContexts(void)435 inline types::AudioContexts GetAvailableContexts(void) { 436 return group_available_contexts_; 437 } 438 439 bool IsInTransition(void); 440 bool IsStreaming(void); 441 bool IsReleasingOrIdle(void); 442 443 void PrintDebugState(void); 444 void Dump(int fd, int active_group_id); 445 446 private: 447 uint32_t transport_latency_mtos_us_; 448 uint32_t transport_latency_stom_us_; 449 450 const set_configurations::AudioSetConfiguration* 451 FindFirstSupportedConfiguration(types::LeAudioContextType context_type); 452 bool ConfigureAses( 453 const set_configurations::AudioSetConfiguration* audio_set_conf, 454 types::LeAudioContextType context_type, 455 const types::BidirectionalPair<types::AudioContexts>& 456 metadata_context_types, 457 const types::BidirectionalPair<std::vector<uint8_t>>& ccid_lists); 458 bool IsConfigurationSupported( 459 const set_configurations::AudioSetConfiguration* audio_set_configuration, 460 types::LeAudioContextType context_type, 461 types::LeAudioConfigurationStrategy required_snk_strategy); 462 uint32_t GetTransportLatencyUs(uint8_t direction); 463 464 /* Current configuration and metadata context types */ 465 types::LeAudioContextType configuration_context_type_; 466 types::BidirectionalPair<types::AudioContexts> metadata_context_type_; 467 468 /* Mask of contexts that the whole group can handle at it's current state 469 * It's being updated each time group members connect, disconnect or their 470 * individual available audio contexts are changed. 471 */ 472 types::AudioContexts group_available_contexts_; 473 474 /* A temporary mask for bits which were either added or removed when the 475 * group available context type changes. It usually means we should refresh 476 * our group configuration capabilities to clear this. 477 */ 478 types::AudioContexts pending_group_available_contexts_change_; 479 480 /* Possible configuration cache - refreshed on each group context availability 481 * change 482 */ 483 std::map<types::LeAudioContextType, 484 const set_configurations::AudioSetConfiguration*> 485 available_context_to_configuration_map; 486 487 types::AseState target_state_; 488 types::AseState current_state_; 489 std::vector<std::weak_ptr<LeAudioDevice>> leAudioDevices_; 490 }; 491 492 /* LeAudioDeviceGroup class represents a wraper helper over all device groups in 493 * le audio implementation. It allows to operate on device group from a list 494 * (vector container) using determinants like id. 495 */ 496 class LeAudioDeviceGroups { 497 public: 498 LeAudioDeviceGroup* Add(int group_id); 499 void Remove(const int group_id); 500 LeAudioDeviceGroup* FindById(int group_id); 501 std::vector<int> GetGroupsIds(void); 502 size_t Size(); 503 bool IsAnyInTransition(); 504 void Cleanup(void); 505 void Dump(int fd, int active_group_id); 506 507 private: 508 std::vector<std::unique_ptr<LeAudioDeviceGroup>> groups_; 509 }; 510 } // namespace le_audio 511