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