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 <memory>
21 #include <utility>  // for std::pair
22 #include <vector>
23 
24 #include "audio_hal_client/audio_hal_client.h"
25 #include "bta_groups.h"
26 #include "gatt_api.h"
27 #include "gmap_client.h"
28 #include "le_audio_types.h"
29 #include "osi/include/alarm.h"
30 #include "types/raw_address.h"
31 
32 namespace bluetooth::le_audio {
33 
34 // Maps to BluetoothProfile#LE_AUDIO
35 #define LE_AUDIO_PROFILE_CONSTANT 22
36 #define LE_AUDIO_INVALID_CIS_HANDLE 0xFFFF
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   /* Disconnecting for recover - after that we want direct connect to be
50      initiated */
51   DISCONNECTING_AND_RECOVER,
52   /* 2 states below are used when user creates connection. Connect API is
53      called. */
54   CONNECTING_BY_USER,
55   /* Always used after CONNECTING_BY_USER */
56   CONNECTED_BY_USER_GETTING_READY,
57   /* 2 states are used when autoconnect was used for the connection.*/
58   CONNECTING_AUTOCONNECT,
59   /* Always used after CONNECTING_AUTOCONNECT */
60   CONNECTED_AUTOCONNECT_GETTING_READY,
61 };
62 
63 std::ostream& operator<<(std::ostream& os, const DeviceConnectState& state);
64 
65 /* Class definitions */
66 
67 /* LeAudioDevice class represents GATT server device with ASCS, PAC services as
68  * mandatory. Device may contain multiple ASEs, PACs, audio locations. ASEs from
69  * multiple devices may be formed in group.
70  *
71  * Device is created after connection or after storage restoration.
72  *
73  * Active device means that device has at least one ASE which will participate
74  * in any state transition of state machine. ASEs and devices will be activated
75  * according to requested by upper context type.
76  */
77 class LeAudioDevice {
78 public:
79   RawAddress address_;
80 
81   DeviceConnectState connection_state_;
82   bool known_service_handles_;
83   bool notify_connected_after_read_;
84   bool closing_stream_for_disconnection_;
85   bool autoconnect_flag_;
86   tCONN_ID conn_id_;
87   uint16_t mtu_;
88   bool encrypted_;
89   int group_id_;
90   bool csis_member_;
91   int cis_failed_to_be_established_retry_cnt_;
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   std::string model_name_;
109   bool allowlist_flag_;
110   bool acl_asymmetric_;
111   bool acl_phy_update_done_;
112   std::unique_ptr<GmapClient> gmap_client_;
113 
114   alarm_t* link_quality_timer;
115   uint16_t link_quality_timer_data;
116 
117   LeAudioDevice(const RawAddress& address, DeviceConnectState state,
118                 int group_id = bluetooth::groups::kGroupUnknown)
address_(address)119       : address_(address),
120         connection_state_(state),
121         known_service_handles_(false),
122         notify_connected_after_read_(false),
123         closing_stream_for_disconnection_(false),
124         autoconnect_flag_(false),
125         conn_id_(GATT_INVALID_CONN_ID),
126         mtu_(0),
127         encrypted_(false),
128         group_id_(group_id),
129         csis_member_(false),
130         cis_failed_to_be_established_retry_cnt_(0),
131         audio_directions_(0),
132         model_name_(""),
133         allowlist_flag_(false),
134         acl_asymmetric_(false),
135         acl_phy_update_done_(false),
136         link_quality_timer(nullptr),
137         dsa_({{DsaMode::DISABLED},
138               types::DataPathState::IDLE,
139               LE_AUDIO_INVALID_CIS_HANDLE,
140               false}) {}
141   ~LeAudioDevice(void);
142 
143   void SetConnectionState(DeviceConnectState state);
144   DeviceConnectState GetConnectionState(void);
145   void ClearPACs(void);
146   void RegisterPACs(std::vector<struct types::acs_ac_record>* apr_db,
147                     std::vector<struct types::acs_ac_record>* apr);
148   struct types::ase* GetAseByValHandle(uint16_t val_hdl);
149   int GetAseCount(uint8_t direction);
150   struct types::ase* GetFirstActiveAse(void);
151   struct types::ase* GetFirstActiveAseByDirection(uint8_t direction);
152   struct types::ase* GetNextActiveAseWithSameDirection(struct types::ase* base_ase);
153   struct types::ase* GetNextActiveAseWithDifferentDirection(struct types::ase* base_ase);
154   struct types::ase* GetFirstActiveAseByCisAndDataPathState(types::CisState cis_state,
155                                                             types::DataPathState data_path_state);
156   struct types::ase* GetFirstInactiveAse(uint8_t direction, bool reconnect = false);
157   struct types::ase* GetFirstAseWithState(uint8_t direction, types::AseState state);
158   struct types::ase* GetNextActiveAse(struct types::ase* ase);
159   struct types::ase* GetAseToMatchBidirectionCis(struct types::ase* ase);
160   types::BidirectionalPair<struct types::ase*> GetAsesByCisConnHdl(uint16_t conn_hdl);
161   types::BidirectionalPair<struct types::ase*> GetAsesByCisId(uint8_t cis_id);
162   bool HaveActiveAse(void);
163   bool HaveAllActiveAsesSameState(types::AseState state);
164   bool HaveAllActiveAsesSameDataPathState(types::DataPathState state) const;
165   bool HaveAnyUnconfiguredAses(void);
166   bool HaveAnyStreamingAses(void);
167   bool HaveAnyReleasingAse(void);
168   bool IsReadyToCreateStream(void);
IsReadyToStream(void)169   bool IsReadyToStream(void) const {
170     return HaveAllActiveAsesCisEst() &&
171            HaveAllActiveAsesSameDataPathState(types::DataPathState::CONFIGURED);
172   }
173   bool IsReadyToSuspendStream(void);
174   bool HaveAllActiveAsesCisEst(void) const;
175   bool HaveAnyCisConnected(void);
176   uint8_t GetSupportedAudioChannelCounts(uint8_t direction) const;
177   uint8_t GetPhyBitmask(void) const;
178   uint8_t GetPreferredPhyBitmask(uint8_t preferred_phy) const;
179   bool IsAudioSetConfigurationSupported(
180           const set_configurations::AudioSetConfiguration* audio_set_conf) const;
181   bool ConfigureAses(const set_configurations::AudioSetConfiguration* audio_set_conf,
182                      uint8_t group_size, uint8_t direction, types::LeAudioContextType context_type,
183                      uint8_t* number_of_already_active_group_ase,
184                      types::AudioLocations& group_audio_locations_out,
185                      const types::AudioContexts& metadata_context_types,
186                      const std::vector<uint8_t>& ccid_lists, bool reuse_cis_id);
187 
188   inline types::AudioContexts GetSupportedContexts(
189           int direction = types::kLeAudioDirectionBoth) const {
190     log::assert_that(direction <= (types::kLeAudioDirectionBoth), "Invalid direction used.");
191 
192     if (direction < types::kLeAudioDirectionBoth) {
193       return supp_contexts_.get(direction);
194     } else {
195       return types::get_bidirectional(supp_contexts_);
196     }
197   }
SetSupportedContexts(types::BidirectionalPair<types::AudioContexts> contexts)198   inline void SetSupportedContexts(types::BidirectionalPair<types::AudioContexts> contexts) {
199     supp_contexts_ = contexts;
200   }
201 
202   inline types::AudioContexts GetAvailableContexts(
203           int direction = types::kLeAudioDirectionBoth) const {
204     log::assert_that(direction <= (types::kLeAudioDirectionBoth), "Invalid direction used.");
205 
206     if (direction < types::kLeAudioDirectionBoth) {
207       return avail_contexts_.get(direction);
208     } else {
209       return types::get_bidirectional(avail_contexts_);
210     }
211   }
212   void SetAvailableContexts(types::BidirectionalPair<types::AudioContexts> cont_val);
213 
214   void DeactivateAllAses(void);
215   bool ActivateConfiguredAses(
216           types::LeAudioContextType context_type,
217           const types::BidirectionalPair<types::AudioContexts>& metadata_context_types,
218           types::BidirectionalPair<std::vector<uint8_t>> ccid_lists);
219   void SetMetadataToAse(struct types::ase* ase, const types::AudioContexts& metadata_context_types,
220                         const std::vector<uint8_t>& ccid_lists);
221 
222   void PrintDebugState(void);
223   void DumpPacsDebugState(std::stringstream& stream);
224   void Dump(std::stringstream& stream);
225 
226   void DisconnectAcl(void);
227   std::vector<uint8_t> GetMetadata(types::AudioContexts context_type,
228                                    const std::vector<uint8_t>& ccid_list);
229   bool IsMetadataChanged(const types::BidirectionalPair<types::AudioContexts>& context_types,
230                          const types::BidirectionalPair<std::vector<uint8_t>>& ccid_lists);
231 
232   void GetDeviceModelName(void);
233   void UpdateDeviceAllowlistFlag(void);
234   DsaModes GetDsaModes(void);
235   bool DsaReducedSduSizeSupported();
236   types::DataPathState GetDsaDataPathState(void);
237   void SetDsaDataPathState(types::DataPathState state);
238   uint16_t GetDsaCisHandle(void);
239   void SetDsaCisHandle(uint16_t cis_handle);
240 
241 private:
242   types::BidirectionalPair<types::AudioContexts> avail_contexts_;
243   types::BidirectionalPair<types::AudioContexts> supp_contexts_;
244   struct {
245     DsaModes modes;
246     types::DataPathState state;
247     uint16_t cis_handle;
248     bool reduced_sdu;  // TODO: Remove when earbud implementations move to approved DSA 2.0 standard
249   } dsa_;
250 
251   static constexpr char kLeAudioDeviceAllowListProp[] = "persist.bluetooth.leaudio.allow_list";
252 
253   void DumpPacsDebugState(std::stringstream& stream, types::PublishedAudioCapabilities pacs);
254   void ParseHeadtrackingCodec(const struct types::acs_ac_record& pac);
255 };
256 
257 /* LeAudioDevices class represents a wraper helper over all devices in le audio
258  * implementation. It allows to operate on device from a list (vector container)
259  * using determinants like address, connection id etc.
260  */
261 class LeAudioDevices {
262 public:
263   void Add(const RawAddress& address, bluetooth::le_audio::DeviceConnectState state,
264            int group_id = bluetooth::groups::kGroupUnknown);
265   void Remove(const RawAddress& address);
266   LeAudioDevice* FindByAddress(const RawAddress& address) const;
267   std::shared_ptr<LeAudioDevice> GetByAddress(const RawAddress& address) const;
268   LeAudioDevice* FindByConnId(tCONN_ID conn_id) const;
269   LeAudioDevice* FindByCisConnHdl(uint8_t cig_id, uint16_t conn_hdl) const;
270   void SetInitialGroupAutoconnectState(int group_id, int gatt_if,
271                                        tBTM_BLE_CONN_TYPE reconnection_mode,
272                                        bool current_dev_autoconnect_flag);
273   size_t Size(void) const;
274   void Dump(std::stringstream& stream, int group_id) const;
275   void Cleanup(tGATT_IF client_if);
276 
277 private:
278   std::vector<std::shared_ptr<LeAudioDevice>> leAudioDevices_;
279 };
280 
281 }  // namespace bluetooth::le_audio
282