• 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 #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