1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HFP_AG_AUDIO_CONNECTION_H
17 #define HFP_AG_AUDIO_CONNECTION_H
18 
19 #include <cstdint>
20 #include <map>
21 #include <optional>
22 #include <string>
23 #include <vector>
24 
25 #include "base_def.h"
26 #include "btm.h"
27 #include "btstack.h"
28 #include "hfp_ag_defines.h"
29 
30 namespace OHOS {
31 namespace bluetooth {
32 /**
33  * @brief Class for Audio connection required by AudioGateway.
34  */
35 class HfpAgAudioConnection {
36 public:
37     struct AudioDevice {
38         std::string addr {""};
39         uint8_t linkType {LINK_TYPE_SCO};
40         uint16_t handle {0};
41         int role {ROLE_INVALID};
42         int lastConnectResult {CONNECT_NONE};
43         int lastParam {SETTING_NONE};
44     };
45 
46     typedef struct {
47         uint8_t status {0};
48         uint16_t connectionHandle {0};
49         BtAddr addr {};
50     } HfpScoConnectionCompleteParam;
51 
52     typedef struct {
53         BtAddr addr {};
54         uint8_t linkType {0};
55     } HfpScoConnectionRequestParam;
56 
57     typedef struct {
58         uint8_t status {0};
59         uint16_t connectionHandle {0};
60         uint8_t reason {0};
61     } HfpScoDisconnectionCompleteParam;
62 
63     /**
64      * @brief Register audio callback, start listen.
65      */
66     static int Register();
67 
68     /**
69      * @brief Deregister audio callback, stop listen.
70      */
71     static int Deregister();
72 
73     /**
74      * @brief Set the Active Device.
75      *
76      * @param address Remote device address.
77      */
78     static void SetActiveDevice(const std::string &address);
79 
80     /**
81      * @brief Get the Active Device object.
82      *
83      * @return Returns remote device address.
84      */
85     static std::string GetActiveDevice();
86 
87     /**
88      * @brief Check if audio connection established;
89      *
90      * @return Returns <b>true</b> if audio connected; returns <b>false</b> if audio not connected.
91      */
92     static bool IsAudioConnected(const std::string &address);
93 
94     /**
95      * @brief Construct a new HfpAgAudioConnection object as default.
96      */
97     HfpAgAudioConnection() = default;
98 
99     /**
100      * @brief Destroy the HfpAgAudioConnection object as default.
101      */
102     ~HfpAgAudioConnection() = default;
103 
104     /**
105      * @brief Connect sco.
106      *
107      * @return Returns audio connect result.
108      */
109     int ConnectAudio() const;
110 
111     /**
112      * @brief Disconnect sco.
113      *
114      * @return Returns audio disconnect result.
115      */
116     int DisconnectAudio() const;
117 
118     /**
119      * @brief Accept sco connect request.
120      *
121      * @return Returns accept audio connect result.
122      */
123     int AcceptAudioConnection() const;
124 
125     /**
126      * @brief Reject sco connect request.
127      *
128      * @return Returns reject audio connect result.
129      */
130     int RejectAudioConnection() const;
131 
132     /**
133      * @brief Set the Remote Address.
134      *
135      * @param addr Remote device address.
136      */
137     void SetRemoteAddr(const std::string &addr);
138 
139     /**
140      * @brief Set the Support Features.
141      *
142      * @param escoSupport Esco support flag.
143      * @param inUseCodec Codec in use.
144      */
145     void SetSupportFeatures(bool escoSupport, bool escoS4Support, int inUseCodec);
146 
147 private:
148     /**
149      * @brief Connect complete callback.
150      *
151      * @param param Audio connection complete parameters.
152      * @param context Audio connection context.
153      */
154     static void OnConnectCompleted(const BtmScoConnectionCompleteParam *param, void *context);
155 
156     /**
157      * @brief Connection change callback.
158      *
159      * @param param Audio connection change parameters.
160      * @param context Audio connection context.
161      */
162     static void OnConnectionChanged(const BtmScoConnectionChangedParam *param, void *context);
163 
164     /**
165      * @brief Disconnect complete callback.
166      *
167      * @param param Audio disconnection complete parameters.
168      * @param context Audio connection context.
169      */
170     static void OnDisconnectCompleted(const BtmScoDisconnectionCompleteParam *param, void *context);
171 
172     /**
173      * @brief Connect request callback.
174      *
175      * @param param Audio connection request parameters.
176      * @param context Audio connection context.
177      */
178     static void OnConnectRequest(const BtmScoConnectionRequestParam *param, void *context);
179 
180     /**
181      * @brief Voice setting callback.
182      *
183      * @param status Write voice setting status.
184      * @param context Audio connection context.
185      */
186     static void OnWriteVoiceSettingCompleted(uint8_t status, void *context);
187 
188     /**
189      * @brief Process connect completed event on hfp thread.
190      *
191      * @param parameters connect completed parameters.
192      */
193     static void ProcessOnConnectCompleted(HfpScoConnectionCompleteParam parameters);
194 
195     /**
196      * @brief Process disconnect completed event on hfp thread.
197      *
198      * @param parameters disconnect completed parameters.
199      */
200     static void ProcessOnDisconnectCompleted(HfpScoDisconnectionCompleteParam parameters);
201 
202     /**
203      * @brief Process connect request event on hfp thread.
204      *
205      * @param parameters connect request parameters.
206      */
207     static void ProcessOnConnectRequest(HfpScoConnectionRequestParam parameters);
208 
209     /**
210      * @brief Process connect completed fail event on hfp thread.
211      *
212      * @param parameters connect completed parameters.
213      */
214     static void ProcessOnConnectCompletedFail(
215         std::vector<HfpAgAudioConnection::AudioDevice>::iterator dev, const std::string &address);
216 
217     /**
218      * @brief Convert bluetooth address to BtAddr.
219      *
220      * @param address Remote device address.
221      * @return Returns remote device address in stack.
222      */
223     static BtAddr ConvertToBtAddr(std::string address);
224 
225     /**
226      * @brief Get the Device By Addr object.
227      *
228      * @param addr Remote device address.
229      * @return Returns audio device or nullopt.
230      */
231     static std::vector<HfpAgAudioConnection::AudioDevice>::iterator GetDeviceByAddr(const std::string &addr);
232 
233     /**
234      * @brief Get the Device By Handle object.
235      *
236      * @param handle Remote device handle.
237      * @return Returns audio device or nullopt.
238      */
239     static std::vector<HfpAgAudioConnection::AudioDevice>::iterator GetDeviceByHandle(uint16_t handle);
240 
241     /**
242      * @brief Accept SCO by MSBC.
243      *
244      * @param btAddr Bt address.
245      * @return Returns accept SCO by MSBC result.
246      */
247     static int AcceptByMsbc(BtAddr btAddr);
248 
249     /**
250      * @brief Accept SCO by CVSD.
251      *
252      * @param dev Audio device.
253      * @param btAddr Bt address.
254      * @return Returns accept SCO by CVSD result.
255      */
256     int AcceptByCvsd(const AudioDevice &dev, BtAddr btAddr) const;
257 
258     /**
259      * @brief Connect SCO by MSBC.
260      *
261      * @param dev Audio device.
262      * @param btAddr Bt address.
263      * @return Returns connect SCO by MSBC result.
264      */
265     int ConnectByMsbc(AudioDevice &dev, BtAddr btAddr) const;
266 
267     /**
268      * @brief Connect SCO by CVSD.
269      *
270      * @param dev Audio device.
271      * @param btAddr Bt address.
272      * @param cvsdEscoFailed Flag for last connect status by cvsd.
273      * @return Returns connect SCO by CVSD result.
274      */
275     int ConnectByCvsd(AudioDevice &dev, BtAddr btAddr, bool cvsdEscoFailed) const;
276 
277     BT_DISALLOW_COPY_AND_ASSIGN(HfpAgAudioConnection);
278 
279     // Btm SCO callbacks
280     static BtmScoCallbacks g_cbs;
281 
282     // active device address
283     static std::string g_activeAddr;
284 
285     // device vectors
286     static std::vector<HfpAgAudioConnection::AudioDevice> g_audioDevices;
287 
288     // Packet types
289     static inline constexpr int PACKET_TYPE_HV1 = 0x00000001;
290     static inline constexpr int PACKET_TYPE_HV2 = 0x00000002;
291     static inline constexpr int PACKET_TYPE_HV3 = 0x00000004;
292     static inline constexpr int PACKET_TYPE_EV3 = 0x00000008;
293     static inline constexpr int PACKET_TYPE_EV4 = 0x00000010;
294     static inline constexpr int PACKET_TYPE_EV5 = 0x00000020;
295     static inline constexpr int PACKET_TYPE_NO_2_EV3 = 0x00000040;
296     static inline constexpr int PACKET_TYPE_NO_3_EV3 = 0x00000080;
297     static inline constexpr int PACKET_TYPE_NO_2_EV5 = 0x00000100;
298     static inline constexpr int PACKET_TYPE_NO_3_EV5 = 0x00000200;
299 
300     static inline constexpr int PACKET_TYPE_CVSD = PACKET_TYPE_HV1 | PACKET_TYPE_HV2 | PACKET_TYPE_HV3 |
301                                                    PACKET_TYPE_EV3 | PACKET_TYPE_EV4 | PACKET_TYPE_EV5 |
302                                                    PACKET_TYPE_NO_3_EV3 | PACKET_TYPE_NO_2_EV5 | PACKET_TYPE_NO_3_EV5;
303 
304     static inline constexpr int PACKET_TYPE_MSBC_T1 =
305         PACKET_TYPE_EV3 | PACKET_TYPE_NO_3_EV3 | PACKET_TYPE_NO_2_EV5 | PACKET_TYPE_NO_3_EV5 | PACKET_TYPE_NO_2_EV3;
306 
307     static inline constexpr int PACKET_TYPE_MSBC_T2 =
308         PACKET_TYPE_EV3 | PACKET_TYPE_NO_3_EV3 | PACKET_TYPE_NO_2_EV5 | PACKET_TYPE_NO_3_EV5;
309 
310     // Transmit&Receive bandwidth
311     static inline constexpr int TRANSMIT_BANDWIDTH = 0x00001f40;  // Decimal 8000, 64 kbits/sec
312     static inline constexpr int RECEIVE_BANDWIDTH = 0x00001f40;   // Decimal 8000, 64 kbits/sec
313 
314     // CVSD SCO settings
315     static inline constexpr int CVSD_SCO_PACKET_TYPE = PACKET_TYPE_HV1 | PACKET_TYPE_HV3;
316     static inline constexpr int CVSD_SCO_MAX_LATENCY = 0x0000ffff;
317     static inline constexpr int CVSD_SCO_RETRANSMISSION_EFFORT = 0x000000ff;
318 
319     // CVSD ESCO settings
320     static inline constexpr int CVSD_ESCO_MAX_LATENCY_S1 = 0x00000007;
321     static inline constexpr int CVSD_ESCO_MAX_LATENCY_S4 = 0x0000000C;
322     static inline constexpr int CVSD_ESCO_RETRANSMISSION_EFFORT_S1 = 0x00000001;
323     static inline constexpr int CVSD_ESCO_RETRANSMISSION_EFFORT_S4 = 0x00000002;
324 
325     // MSBC ESCO settings
326     static inline constexpr int CVSD_ESCO_PACKET_TYPE_S1 = PACKET_TYPE_CVSD;
327     static inline constexpr int CVSD_ESCO_PACKET_TYPE_S4 = PACKET_TYPE_CVSD;
328     static inline constexpr int MSBC_ESCO_PACKET_TYPE_T1 = PACKET_TYPE_MSBC_T1;
329     static inline constexpr int MSBC_ESCO_PACKET_TYPE_T2 = PACKET_TYPE_MSBC_T2;
330     static inline constexpr int MSBC_ESCO_MAX_LATENCY_T1 = 0x00000008;
331     static inline constexpr int MSBC_ESCO_MAX_LATENCY_T2 = 0x0000000D;
332     static inline constexpr int MSBC_ESCO_RETRANSMISSION_EFFORT = 0x00000002;
333 
334     // Voice settings
335     static inline constexpr int BTM_VOICE_SETTING_CVSD = 0x00000060;
336     static inline constexpr int BTM_VOICE_SETTING_TRANS = 0x00000063;
337 
338     // (e)sco parameter set
339     static inline constexpr int SETTING_NONE = 0x00000000;
340     static inline constexpr int MSBC_ESCO_T2 = 0x00000001;
341     static inline constexpr int MSBC_ESCO_T1 = 0x00000002;
342     static inline constexpr int CVSD_ESCO_S4 = 0x00000004;
343     static inline constexpr int CVSD_ESCO_S1 = 0x00000008;
344     static inline constexpr int CVSD_SCO = 0x00000010;
345 
346     // role type
347     static inline constexpr int ROLE_INVALID = 0x00000000;
348     static inline constexpr int ROLE_INITIATOR = 0x00000001;
349     static inline constexpr int ROLE_ACCEPTOR = 0x00000002;
350 
351     // connect result
352     static inline constexpr int CONNECT_NONE = 0x00000000;
353     static inline constexpr int CONNECT_SUCCESS = 0x00000001;
354     static inline constexpr int CONNECT_FAIL = 0x00000002;
355 
356     // HCI result
357     static inline constexpr int REJECT_DUE_TO_LIMITED_RESOURCES = 0x0000000D;
358     static inline constexpr int REMOTE_USER_TERMINATED_CONNECTION = 0x00000013;
359 
360     // The empty address
361     inline static const std::string NULL_ADDRESS {""};
362 
363     // MSBC ESCO T2 parameters set
364     static inline const BtmCreateEscoConnectionParam MSBC_T2_PARAM = {
365         {{0}, 0},
366         TRANSMIT_BANDWIDTH,
367         RECEIVE_BANDWIDTH,
368         CODEC_MSBC_T2,
369         MSBC_ESCO_MAX_LATENCY_T2,
370         MSBC_ESCO_PACKET_TYPE_T2,
371         MSBC_ESCO_RETRANSMISSION_EFFORT
372     };
373 
374     // MSBC ESCO T1 parameters set
375     static inline const BtmCreateEscoConnectionParam MSBC_T1_PARAM = {
376         {{0}, 0},
377         TRANSMIT_BANDWIDTH,
378         RECEIVE_BANDWIDTH,
379         CODEC_MSBC_T1,
380         MSBC_ESCO_MAX_LATENCY_T1,
381         MSBC_ESCO_PACKET_TYPE_T1,
382         MSBC_ESCO_RETRANSMISSION_EFFORT
383     };
384 
385     // CVSD ESCO S4 parameters set
386     static inline const BtmCreateEscoConnectionParam CVSD_ESCO_S4_PARAM = {
387         {{0}, 0},
388         TRANSMIT_BANDWIDTH,
389         RECEIVE_BANDWIDTH,
390         CODEC_CVSD,
391         CVSD_ESCO_MAX_LATENCY_S4,
392         CVSD_ESCO_PACKET_TYPE_S4,
393         CVSD_ESCO_RETRANSMISSION_EFFORT_S4
394     };
395 
396     // CVSD ESCO S1 parameters set
397     static inline const BtmCreateEscoConnectionParam CVSD_ESCO_S1_PARAM = {
398         {{0}, 0},
399         TRANSMIT_BANDWIDTH,
400         RECEIVE_BANDWIDTH,
401         CODEC_CVSD,
402         CVSD_ESCO_MAX_LATENCY_S1,
403         CVSD_ESCO_PACKET_TYPE_S1,
404         CVSD_ESCO_RETRANSMISSION_EFFORT_S1
405     };
406 
407     // CVSD SCO parameters set
408     static inline const BtmCreateScoConnectionParam CVSD_SCO_PARAM = {
409         {{0}, 0},
410         TRANSMIT_BANDWIDTH,
411         RECEIVE_BANDWIDTH,
412         CVSD_SCO_MAX_LATENCY,
413         BTM_VOICE_SETTING_CVSD,
414         CVSD_SCO_RETRANSMISSION_EFFORT,
415         CVSD_SCO_PACKET_TYPE
416     };
417 
418     std::string remoteAddr_ {""};
419     bool escoSupport_ {false};
420     bool escoS4Support_ {false};
421     int inUseCodec_ {HFP_AG_CODEC_CVSD};
422 };
423 }  // namespace bluetooth
424 }  // namespace OHOS
425 #endif // HFP_AG_AUDIO_CONNECTION_H