• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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