1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <bluetooth/log.h>
20 
21 #include <cstdint>
22 #include <string>
23 #include <vector>
24 
25 #include "device/include/esco_parameters.h"
26 #include "internal_include/bt_target.h"
27 #include "macros.h"
28 #include "raw_address.h"
29 #include "stack/btm/sco_pkt_status.h"
30 #include "stack/include/btm_api_types.h"
31 
32 #define BTM_MSBC_CODE_SIZE 240
33 #define BTM_LC3_CODE_SIZE 480
34 
35 constexpr uint16_t kMaxScoLinks = static_cast<uint16_t>(BTM_MAX_SCO_LINKS);
36 
37 /* SCO-over-HCI audio related definitions */
38 namespace bluetooth::audio::sco {
39 
40 /* Initialize SCO-over-HCI socket (UIPC); the client is audio server */
41 void init();
42 
43 /* Open the socket when there is SCO connection open */
44 void open();
45 
46 /* Clean up the socket when the SCO connection is done */
47 void cleanup();
48 
49 /* Read PCM data from the socket (audio server) for SCO Tx */
50 size_t read(uint8_t* p_buf, uint32_t len);
51 
52 /* Write PCM data to the socket from SCO Rx */
53 size_t write(const uint8_t* buf, uint32_t len);
54 }  // namespace bluetooth::audio::sco
55 
56 /* SCO-over-HCI audio HFP WBS related definitions */
57 namespace bluetooth::audio::sco::wbs {
58 
59 /* Initialize struct used for storing WBS related information.
60  * Args:
61  *    pkt_size - Length of the SCO packet. It is determined based on the BT-USB
62  *    adapter's capability and alt mode setting. The value should be queried
63  *    from HAL interface. It will be used to determine the size of the SCO
64  *    packet buffer. Currently, the stack only supports 60 and 72.
65  * Returns:
66  *    The selected packet size. Will fallback to the typical mSBC packet
67  *    length(60) if the pkt_size argument is not supported.
68  */
69 size_t init(size_t pkt_size);
70 
71 /* Clean up when the SCO connection is done */
72 void cleanup();
73 
74 /* Fill in packet loss stats
75  * Args:
76  *    num_decoded_frames - Output argument for the number of decode frames
77  *    packet_loss_ratio - Output argument for the ratio of lost frames
78  * Returns:
79  *    False for invalid arguments or unreasonable stats. True otherwise.
80  */
81 bool fill_plc_stats(int* num_decoded_frames, double* packet_loss_ratio);
82 
83 /* Try to enqueue a packet to a buffer.
84  * Args:
85  *    data - Vector of received packet data bytes.
86  *    corrupted - If the current mSBC packet read is corrupted.
87  * Returns:
88  *    true if enqueued, false if it failed.
89  */
90 bool enqueue_packet(const std::vector<uint8_t>& data, bool corrupted);
91 
92 /* Try to decode mSBC frames from the packets in the buffer.
93  * Args:
94  *    output - Pointer to the decoded PCM bytes caller can read from.
95  * Returns:
96  *    The length of decoded bytes. 0 if failed.
97  */
98 size_t decode(const uint8_t** output);
99 
100 /* Try to encode PCM data into one SCO packet and put the packets in the buffer.
101  * Args:
102  *    data - Pointer to the input PCM bytes for the encoder to encode.
103  *    len - Length of the input data.
104  * Returns:
105  *    The length of input data that is encoded. 0 if failed.
106  */
107 size_t encode(int16_t* data, size_t len);
108 
109 /* Dequeue a SCO packet with encoded mSBC data if possible. The length of the
110  * packet is determined by the pkt_size set by the init().
111  * Args:
112  *    output - Pointer to output mSBC packets encoded by the encoder.
113  * Returns:
114  *    The length of dequeued packet. 0 if failed.
115  */
116 size_t dequeue_packet(const uint8_t** output);
117 
118 /* Get mSBC packets' status record.
119  * Returns:
120  *      Pointer to the record struct, nullptr if not valid.
121  */
122 tBTM_SCO_PKT_STATUS* get_pkt_status();
123 }  // namespace bluetooth::audio::sco::wbs
124 
125 /* SCO-over-HCI audio HFP SWB related definitions */
126 namespace bluetooth::audio::sco::swb {
127 
128 /* Initialize struct used for storing SWB related information.
129  * Args:
130  *    pkt_size - Length of the SCO packet. It is determined based on the BT-USB
131  *    adapter's capability and alt mode setting. The value should be queried
132  *    from HAL interface. It will be used to determine the size of the SCO
133  *    packet buffer. Currently, the stack only supports 60 and 72.
134  * Returns:
135  *    The selected packet size. Will fallback to the typical LC3 packet
136  *    length(60) if the pkt_size argument is not supported.
137  */
138 size_t init(size_t pkt_size);
139 
140 /* Clean up when the SCO connection is done */
141 void cleanup();
142 
143 /* Fill in packet loss stats
144  * Args:
145  *    num_decoded_frames - Output argument for the number of decode frames
146  *    packet_loss_ratio - Output argument for the ratio of lost frames
147  * Returns:
148  *    False for invalid arguments or unreasonable stats. True otherwise.
149  */
150 bool fill_plc_stats(int* num_decoded_frames, double* packet_loss_ratio);
151 
152 /* Try to enqueue a packet to a buffer.
153  * Args:
154  *    data - Vector of received packet data bytes.
155  *    corrupted - If the current LC3 packet read is corrupted.
156  * Returns:
157  *    true if enqueued, false if it failed.
158  */
159 bool enqueue_packet(const std::vector<uint8_t>& data, bool corrupted);
160 
161 /* Try to decode LC3 frames from the packets in the buffer.
162  * Args:
163  *    output - Pointer to the decoded PCM bytes caller can read from.
164  * Returns:
165  *    The length of decoded bytes. 0 if failed.
166  */
167 size_t decode(const uint8_t** output);
168 
169 /* Try to encode PCM data into one SCO packet and put the packets in the buffer.
170  * Args:
171  *    data - Pointer to the input PCM bytes for the encoder to encode.
172  *    len - Length of the input data.
173  * Returns:
174  *    The length of input data that is encoded. 0 if failed.
175  */
176 size_t encode(int16_t* data, size_t len);
177 
178 /* Dequeue a SCO packet with encoded LC3 data if possible. The length of the
179  * packet is determined by the pkt_size set by the init().
180  * Args:
181  *    output - Pointer to output LC3 packets encoded by the encoder.
182  * Returns:
183  *    The length of dequeued packet. 0 if failed.
184  */
185 size_t dequeue_packet(const uint8_t** output);
186 
187 /* Get LC3 packets' status record.
188  * Returns:
189  *      Pointer to the record struct, nullptr if not valid.
190  */
191 tBTM_SCO_PKT_STATUS* get_pkt_status();
192 }  // namespace bluetooth::audio::sco::swb
193 
194 /* Define the structures needed by sco */
195 typedef enum : uint16_t {
196   SCO_ST_UNUSED = 0,
197   SCO_ST_LISTENING = 1,
198   SCO_ST_W4_CONN_RSP = 2,
199   SCO_ST_CONNECTING = 3,
200   SCO_ST_CONNECTED = 4,
201   SCO_ST_DISCONNECTING = 5,
202   SCO_ST_PEND_UNPARK = 6,
203   SCO_ST_PEND_ROLECHANGE = 7,
204   SCO_ST_PEND_MODECHANGE = 8,
205 } tSCO_STATE;
206 
sco_state_text(const tSCO_STATE & state)207 inline std::string sco_state_text(const tSCO_STATE& state) {
208   switch (state) {
209     CASE_RETURN_TEXT(SCO_ST_UNUSED);
210     CASE_RETURN_TEXT(SCO_ST_LISTENING);
211     CASE_RETURN_TEXT(SCO_ST_W4_CONN_RSP);
212     CASE_RETURN_TEXT(SCO_ST_CONNECTING);
213     CASE_RETURN_TEXT(SCO_ST_CONNECTED);
214     CASE_RETURN_TEXT(SCO_ST_DISCONNECTING);
215     CASE_RETURN_TEXT(SCO_ST_PEND_UNPARK);
216     CASE_RETURN_TEXT(SCO_ST_PEND_ROLECHANGE);
217     CASE_RETURN_TEXT(SCO_ST_PEND_MODECHANGE);
218     default:
219       return std::string("unknown_sco_state: ") +
220        std::to_string(static_cast<uint16_t>(state));
221   }
222 }
223 
224 /* Define the structure that contains (e)SCO data */
225 typedef struct {
226   tBTM_ESCO_CBACK* p_esco_cback; /* Callback for eSCO events     */
227   enh_esco_params_t setup;
228   tBTM_ESCO_DATA data; /* Connection complete information */
229   uint8_t hci_status;
230 } tBTM_ESCO_INFO;
231 
232 /* Define the structure used for SCO Management */
233 typedef struct {
234   tBTM_ESCO_INFO esco;    /* Current settings             */
235   tBTM_SCO_CB* p_conn_cb; /* Callback for when connected  */
236   tBTM_SCO_CB* p_disc_cb; /* Callback for when disconnect */
237   tSCO_STATE state;       /* The state of the SCO link    */
238 
239   uint16_t hci_handle;    /* HCI Handle                   */
240  public:
is_active__anon9a185c020308241   bool is_active() const { return state != SCO_ST_UNUSED; }
is_inband__anon9a185c020308242   bool is_inband() const {
243     return esco.setup.input_data_path == ESCO_DATA_PATH_HCI;
244   }
get_codec_type__anon9a185c020308245   tBTM_SCO_CODEC_TYPE get_codec_type() const {
246     switch (esco.setup.coding_format) {
247       case ESCO_CODING_FORMAT_CVSD:
248         return BTM_SCO_CODEC_CVSD;
249       case ESCO_CODING_FORMAT_MSBC:
250         return BTM_SCO_CODEC_MSBC;
251       case ESCO_CODING_FORMAT_LC3:
252         return BTM_SCO_CODEC_LC3;
253       default:
254         return BTM_SCO_CODEC_NONE;
255     }
256   }
Handle__anon9a185c020308257   uint16_t Handle() const { return hci_handle; }
258 
259   bool is_orig;           /* true if the originator       */
260   bool rem_bd_known;      /* true if remote BD addr known */
261 
262 } tSCO_CONN;
263 
264 /* SCO Management control block */
265 struct tSCO_CB {
266   tSCO_CONN sco_db[BTM_MAX_SCO_LINKS];
267   enh_esco_params_t def_esco_parms;
268   bool esco_supported;        /* true if 1.2 cntlr AND supports eSCO links */
269 
get_sco_connection_from_indextSCO_CB270   tSCO_CONN* get_sco_connection_from_index(uint16_t index) {
271     return (index < kMaxScoLinks) ? (&sco_db[index]) : nullptr;
272   }
273 
get_sco_connection_from_handletSCO_CB274   tSCO_CONN* get_sco_connection_from_handle(uint16_t handle) {
275     tSCO_CONN* p_sco = sco_db;
276     for (uint16_t xx = 0; xx < kMaxScoLinks; xx++, p_sco++) {
277       if (p_sco->hci_handle == handle) {
278         return p_sco;
279       }
280     }
281     return nullptr;
282   }
283 
284   void Init();
285 
286   void Free();
287 
get_indextSCO_CB288   uint16_t get_index(const tSCO_CONN* p_sco) const {
289     bluetooth::log::assert_that(p_sco != nullptr,
290                                 "assert failed: p_sco != nullptr");
291     const tSCO_CONN* p = sco_db;
292     for (uint16_t xx = 0; xx < kMaxScoLinks; xx++, p++) {
293       if (p_sco == p) {
294         return xx;
295       }
296     }
297     return 0xffff;
298   }
299 };
300 
301 void btm_sco_chk_pend_rolechange(uint16_t hci_handle);
302 void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle);
303 
304 /* Send a SCO packet */
305 void btm_send_sco_packet(std::vector<uint8_t> data);
306 
307 bool btm_peer_supports_esco_2m_phy(RawAddress remote_bda);
308 bool btm_peer_supports_esco_3m_phy(RawAddress remote_bda);
309 bool btm_peer_supports_esco_ev3(RawAddress remote_bda);
310