1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "bta/bta_hf_client_co.h"
8 #include "hci/hci_audio.h"
9 #include "btc_hf_client.h"
10 #include "osi/allocator.h"
11 #include <string.h>
12 
13 #if (BTA_HF_INCLUDED == TRUE)
14 
15 #if (BTM_SCO_HCI_INCLUDED == TRUE)
16 
17 #include "oi_codec_sbc.h"
18 #include "oi_status.h"
19 #include "sbc_encoder.h"
20 
21 #if (PLC_INCLUDED == TRUE)
22 #include "sbc_plc.h"
23 
24 typedef struct {
25     bool first_good_frame_found;
26     sbc_plc_state_t plc_state;
27     int16_t sbc_plc_out[SBC_FS];
28 } bta_hf_ct_plc_t;
29 
30 #if HFP_DYNAMIC_MEMORY == FALSE
31 static bta_hf_ct_plc_t bta_hf_ct_plc;
32 #else
33 static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
34 #define bta_hf_ct_plc (*bta_hf_ct_plc_ptr)
35 #endif
36 
37 #endif  ///(PLC_INCLUDED == TRUE)
38 
39 
40 #define HF_SBC_DEC_CONTEXT_DATA_LEN     (CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS))
41 #define HF_SBC_DEC_RAW_DATA_SIZE        240
42 #define HF_SBC_ENC_RAW_DATA_SIZE        240
43 
44 /* BTA-HF-CO control block to map bdaddr to BTA handle */
45 typedef struct
46 {
47     OI_CODEC_SBC_DECODER_CONTEXT    decoder_context;
48     OI_UINT32                       decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
49     OI_INT16                        decode_raw_data[HF_SBC_DEC_RAW_DATA_SIZE];
50 
51     SBC_ENC_PARAMS                  encoder;
52 
53     UINT8                           sequence_number;
54     bool                            is_bad_frame;
55     bool                            decode_first_pkt;
56     OI_BYTE                         decode_msbc_data[BTM_MSBC_FRAME_SIZE];
57     bool                            encode_first_pkt;
58     OI_BYTE                         encode_msbc_data[BTM_MSBC_FRAME_SIZE];
59 } bta_hf_client_co_cb_t;
60 
61 #if HFP_DYNAMIC_MEMORY == FALSE
62 static bta_hf_client_co_cb_t bta_hf_client_co_cb;
63 #else
64 static bta_hf_client_co_cb_t *bta_hf_client_co_cb_ptr;
65 #define bta_hf_client_co_cb (*bta_hf_client_co_cb_ptr)
66 #endif /* HFP_DYNAMIC_MEMORY == FALSE */
67 
68 static UINT8 hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
69 static UINT8 hf_inout_pkt_size = 0;
70 
71 /*******************************************************************************
72 **
73 ** Function         bta_hf_client_co_audio_state
74 **
75 ** Description      This function is called by the HF CLIENT before the audio connection
76 **                  is brought up, after it comes up, and after it goes down.
77 **
78 ** Parameters       handle - handle of the AG instance
79 **                  state - Audio state
80 **                  codec - if WBS support is compiled in, codec to going to be used is provided
81 **                      and when in SCO_STATE_SETUP, BTM_I2SPCMConfig() must be called with
82 **                      the correct platform parameters.
83 **                      in the other states codec type should not be ignored
84 **
85 ** Returns          void
86 **
87 *******************************************************************************/
bta_hf_client_co_audio_state(UINT16 handle,UINT8 state,tBTA_HFP_PEER_CODEC codec)88 void bta_hf_client_co_audio_state(UINT16 handle, UINT8 state, tBTA_HFP_PEER_CODEC codec)
89 {
90     switch (state)
91     {
92     case SCO_STATE_ON:
93     case SCO_STATE_OFF:
94     case SCO_STATE_OFF_TRANSFER:
95     case SCO_STATE_SETUP:
96     default:
97         break;
98     }
99 }
100 
101 /*******************************************************************************
102 **
103 ** Function         bta_hf_client_sco_co_init
104 **
105 ** Description      This function can be used by the phone to initialize audio
106 **                  codec or for other initialization purposes before SCO connection
107 **                  is opened.
108 **
109 **
110 ** Returns          Void.
111 **
112 *******************************************************************************/
bta_hf_client_sco_co_init(UINT32 rx_bw,UINT32 tx_bw,tBTA_HFP_CODEC_INFO * p_codec_info,UINT8 app_id)113 tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
114         tBTA_HFP_CODEC_INFO *p_codec_info, UINT8 app_id)
115 {
116     APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %d, codec %d", __FUNCTION__, rx_bw, tx_bw,
117                      p_codec_info->codec_type);
118     return BTA_HFP_SCO_ROUTE_HCI;
119 }
120 
121 /*******************************************************************************
122  **
123  ** Function       bta_hf_dec_init
124  **
125  ** Description    Initialize decoding task
126  **
127  ** Returns        void
128  **
129  *******************************************************************************/
bta_hf_dec_init(void)130 static void bta_hf_dec_init(void) {
131 #if (PLC_INCLUDED == TRUE)
132     sbc_plc_init(&(bta_hf_ct_plc.plc_state));
133 #endif  ///(PLC_INCLUDED == TRUE)
134 
135     OI_STATUS status;
136 
137     status = OI_CODEC_SBC_DecoderReset(&bta_hf_client_co_cb.decoder_context, bta_hf_client_co_cb.decoder_context_data,
138                                        HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE);
139     if (!OI_SUCCESS(status)) {
140         APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
141     }
142 }
143 
144 /*******************************************************************************
145  **
146  ** Function       bta_hf_enc_init
147  **
148  ** Description    Initialize encoding task
149  **
150  ** Returns        void
151  **
152  *******************************************************************************/
bta_hf_enc_init(void)153 static void bta_hf_enc_init(void) {
154     bta_hf_client_co_cb.sequence_number = 0;
155     bta_hf_client_co_cb.decode_first_pkt = true;
156     bta_hf_client_co_cb.encode_first_pkt = true;
157     bta_hf_client_co_cb.is_bad_frame =  false;
158 
159     bta_hf_client_co_cb.encoder.sbc_mode = SBC_MODE_MSBC;
160     bta_hf_client_co_cb.encoder.s16NumOfBlocks    = 15;
161     bta_hf_client_co_cb.encoder.s16NumOfSubBands  = 8;
162     bta_hf_client_co_cb.encoder.s16AllocationMethod = SBC_LOUDNESS;
163     bta_hf_client_co_cb.encoder.s16BitPool   = 26;
164     bta_hf_client_co_cb.encoder.s16ChannelMode = SBC_MONO;
165     bta_hf_client_co_cb.encoder.s16NumOfChannels = 1;
166     bta_hf_client_co_cb.encoder.s16SamplingFreq = SBC_sf16000;
167 
168     SBC_Encoder_Init(&(bta_hf_client_co_cb.encoder));
169 }
170 
171 /*******************************************************************************
172 **
173 ** Function         bta_hf_client_sco_co_open
174 **
175 ** Description      This function is executed when a SCO connection is open.
176 **
177 **
178 ** Returns          void
179 **
180 *******************************************************************************/
bta_hf_client_sco_co_open(UINT16 handle,UINT8 air_mode,UINT8 inout_pkt_size,UINT16 event)181 void bta_hf_client_sco_co_open(UINT16 handle, UINT8 air_mode, UINT8 inout_pkt_size, UINT16 event)
182 {
183     APPL_TRACE_EVENT("%s hdl %x, pkt_sz %u, event %u", __FUNCTION__, handle,
184                      inout_pkt_size, event);
185 
186     hf_air_mode = air_mode;
187     hf_inout_pkt_size = inout_pkt_size;
188 
189     if (air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
190 #if (HFP_DYNAMIC_MEMORY == TRUE)
191         bta_hf_client_co_cb_ptr = osi_calloc(sizeof(bta_hf_client_co_cb_t));
192         if (!bta_hf_client_co_cb_ptr) {
193             APPL_TRACE_ERROR("%s allocate failed", __FUNCTION__);
194             goto error_exit;
195         }
196 
197 #if (PLC_INCLUDED == TRUE)
198         bta_hf_ct_plc_ptr = (bta_hf_ct_plc_t *)osi_calloc(sizeof(bta_hf_ct_plc_t));
199             if (!bta_hf_ct_plc_ptr) {
200             APPL_TRACE_ERROR("%s malloc fail.", __FUNCTION__);
201             goto error_exit;
202         }
203 #endif  ///(PLC_INCLUDED == TRUE)
204 
205 #endif  /// (HFP_DYNAMIC_MEMORY == TRUE)
206 
207         bta_hf_dec_init();
208         bta_hf_enc_init();
209 
210         return;
211     } else {
212         return;
213         // Nothing to do
214     }
215 
216 #if (HFP_DYNAMIC_MEMORY == TRUE)
217 error_exit:;
218     hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
219     hf_inout_pkt_size = 0;
220 
221     if (bta_hf_client_co_cb_ptr) {
222         osi_free(bta_hf_client_co_cb_ptr);
223         bta_hf_client_co_cb_ptr = NULL;
224     }
225 
226 #if (PLC_INCLUDED == TRUE)
227     if (bta_hf_ct_plc_ptr) {
228         osi_free(bta_hf_ct_plc_ptr);
229         bta_hf_ct_plc_ptr = NULL;
230     }
231 #endif  ///(PLC_INCLUDED == TRUE)
232 #endif  /// (HFP_DYNAMIC_MEMORY == TRUE)
233     return;
234 }
235 
236 /*******************************************************************************
237 **
238 ** Function         bta_hf_client_sco_co_close
239 **
240 ** Description      This function is called when a SCO connection is closed
241 **
242 **
243 ** Returns          void
244 **
245 *******************************************************************************/
bta_hf_client_sco_co_close(void)246 void bta_hf_client_sco_co_close(void)
247 {
248     APPL_TRACE_EVENT("%s", __FUNCTION__);
249 
250     if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
251 #if (PLC_INCLUDED == TRUE)
252         sbc_plc_deinit(&(bta_hf_ct_plc.plc_state));
253         bta_hf_ct_plc.first_good_frame_found = FALSE;
254 
255 #if (HFP_DYNAMIC_MEMORY == TRUE)
256         osi_free(bta_hf_ct_plc_ptr);
257         bta_hf_ct_plc_ptr = NULL;
258 #endif  /// (HFP_DYNAMIC_MEMORY == TRUE)
259 
260 #endif  ///(PLC_INCLUDED == TRUE)
261 
262 #if (HFP_DYNAMIC_MEMORY == TRUE)
263         osi_free(bta_hf_client_co_cb_ptr);
264         bta_hf_client_co_cb_ptr = NULL;
265 #endif /* HFP_DYNAMIC_MEMORY == TRUE */
266     } else {
267         // Nothing to do
268     }
269 
270     hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
271     hf_inout_pkt_size = 0;
272 }
273 
274 /*******************************************************************************
275 **
276 ** Function         bta_hf_client_h2_header
277 **
278 ** Description      This function is called to fill in H2 header
279 **
280 ** Returns          void
281 **
282 *******************************************************************************/
bta_hf_client_h2_header(UINT16 * p_buf)283 static void bta_hf_client_h2_header(UINT16 *p_buf)
284 {
285     // H2: Header with synchronization word and sequence number
286 #define BTA_HF_H2_HEADER                0x0801
287 #define BTA_HF_H2_HEADER_BIT0_MASK   (1 << 0)
288 #define BTA_HF_H2_HEADER_BIT1_MASK   (1 << 1)
289 #define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
290 #define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
291 #define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
292 #define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
293 
294     UINT16 h2_header = BTA_HF_H2_HEADER;
295     UINT8 h2_header_sn0 = bta_hf_client_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT0_MASK;
296     UINT8 h2_header_sn1 = bta_hf_client_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT1_MASK;
297     h2_header |= (h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET1
298                 | h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET2
299                 | h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 - 1)
300                 | h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 - 1)
301                 );
302 
303     bta_hf_client_co_cb.sequence_number++;
304     *p_buf = h2_header;
305 }
306 
307 /*******************************************************************************
308 **
309 ** Function         bta_hf_client_sco_co_out_data
310 **
311 ** Description      This function is called to send SCO data over HCI.
312 **
313 ** Returns          number of bytes got from application
314 **
315 *******************************************************************************/
bta_hf_client_sco_co_out_data(UINT8 * p_buf)316 uint32_t bta_hf_client_sco_co_out_data(UINT8 *p_buf)
317 {
318     if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
319         // CVSD
320         uint32_t hf_raw_pkt_size = hf_inout_pkt_size;
321         return btc_hf_client_outgoing_data_cb_to_app(p_buf, hf_raw_pkt_size);
322     } else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
323         // mSBC
324 #if (HFP_DYNAMIC_MEMORY == TRUE)
325         if(bta_hf_client_co_cb_ptr == NULL) {
326             return 0;
327         }
328 #endif /* HFP_DYNAMIC_MEMORY == TRUE */
329         if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
330             if (bta_hf_client_co_cb.encode_first_pkt){
331                 UINT32 size = btc_hf_client_outgoing_data_cb_to_app((UINT8 *)bta_hf_client_co_cb.encoder.as16PcmBuffer, HF_SBC_ENC_RAW_DATA_SIZE);
332                 if (size != HF_SBC_ENC_RAW_DATA_SIZE){
333                     return 0;
334                 }
335 
336                 bta_hf_client_h2_header((UINT16 *)bta_hf_client_co_cb.encode_msbc_data);
337                 bta_hf_client_co_cb.encoder.pu8Packet = bta_hf_client_co_cb.encode_msbc_data + 2;
338 
339                 SBC_Encoder(&bta_hf_client_co_cb.encoder);
340                 memcpy(p_buf, bta_hf_client_co_cb.encode_msbc_data, hf_inout_pkt_size);
341                 bta_hf_client_co_cb.encode_first_pkt = !bta_hf_client_co_cb.encode_first_pkt;
342                 return hf_inout_pkt_size;
343             } else {
344                 memcpy(p_buf, bta_hf_client_co_cb.encode_msbc_data + hf_inout_pkt_size, hf_inout_pkt_size);
345                 bta_hf_client_co_cb.encode_first_pkt = !bta_hf_client_co_cb.encode_first_pkt;
346                 return hf_inout_pkt_size;
347             }
348 
349         } else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
350             UINT32 size = btc_hf_client_outgoing_data_cb_to_app((UINT8 *)bta_hf_client_co_cb.encoder.as16PcmBuffer, HF_SBC_ENC_RAW_DATA_SIZE);
351             if (size != HF_SBC_ENC_RAW_DATA_SIZE){
352                 return 0;
353             }
354 
355             bta_hf_client_h2_header((UINT16 *)p_buf);
356             bta_hf_client_co_cb.encoder.pu8Packet = p_buf + 2;
357 
358             SBC_Encoder(&bta_hf_client_co_cb.encoder);
359             return hf_inout_pkt_size;
360         } else {
361             //Never run to here.
362         }
363 
364 
365 
366     } else {
367         APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
368     }
369     return 0;
370 }
371 
372 /*******************************************************************************
373 **
374 ** Function         bta_hf_client_decode_msbc_frame
375 **
376 ** Description      This function is called decode a mSBC frame
377 **
378 ** Returns          void
379 **
380 *******************************************************************************/
bta_hf_client_decode_msbc_frame(UINT8 ** data,UINT8 * length,BOOLEAN is_bad_frame)381 static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame){
382     OI_STATUS status;
383     const OI_BYTE *zero_signal_frame_data;
384     UINT8 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
385     UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
386 
387     if (is_bad_frame){
388         status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
389     } else {
390         status = OI_CODEC_SBC_DecodeFrame(&bta_hf_client_co_cb.decoder_context, (const OI_BYTE **)data,
391                                           (OI_UINT32 *)length,
392                                           (OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
393                                           (OI_UINT32 *)&sbc_raw_data_size);
394     }
395 
396 // PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
397 #if (PLC_INCLUDED == TRUE)
398     switch(status){
399         case OI_OK:
400             bta_hf_ct_plc.first_good_frame_found = TRUE;
401             sbc_plc_good_frame(&(bta_hf_ct_plc.plc_state), (int16_t *)bta_hf_client_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
402         case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
403         case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
404         case OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA:
405             break;
406         case OI_CODEC_SBC_NO_SYNCWORD:
407         case OI_CODEC_SBC_CHECKSUM_MISMATCH:
408             if (!bta_hf_ct_plc.first_good_frame_found) {
409                 break;
410             }
411             zero_signal_frame_data = sbc_plc_zero_signal_frame();
412             sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
413             status = OI_CODEC_SBC_DecodeFrame(&bta_hf_client_co_cb.decoder_context, &zero_signal_frame_data,
414                                                 (OI_UINT32 *)&zero_signal_frame_len,
415                                                 (OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
416                                                 (OI_UINT32 *)&sbc_raw_data_size);
417             sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), bta_hf_client_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
418             APPL_TRACE_DEBUG("bad frame, using PLC to fix it.");
419             break;
420         case OI_STATUS_INVALID_PARAMETERS:
421             // This caused by corrupt frames.
422             // The codec apparently does not recover from this.
423             // Re-initialize the codec.
424             APPL_TRACE_ERROR("Frame decode error: OI_STATUS_INVALID_PARAMETERS");
425 
426             if (!OI_SUCCESS(OI_CODEC_SBC_DecoderReset(&bta_hf_client_co_cb.decoder_context, bta_hf_client_co_cb.decoder_context_data,
427                                        HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE))) {
428                 APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
429             }
430             break;
431         default:
432             APPL_TRACE_ERROR("Frame decode error: %d", status);
433             break;
434     }
435 #endif  ///(PLC_INCLUDED == TRUE)
436 
437     if (OI_SUCCESS(status)){
438         btc_hf_client_incoming_data_cb_to_app((const uint8_t *)(bta_hf_ct_plc.sbc_plc_out), sbc_raw_data_size);
439     }
440 }
441 
442 /*******************************************************************************
443 **
444 ** Function         bta_hf_client_sco_co_in_data
445 **
446 ** Description      This function is called to send incoming SCO data to application.
447 **
448 ** Returns          void
449 **
450 *******************************************************************************/
bta_hf_client_sco_co_in_data(BT_HDR * p_buf,tBTM_SCO_DATA_FLAG status)451 void bta_hf_client_sco_co_in_data(BT_HDR  *p_buf, tBTM_SCO_DATA_FLAG status)
452 {
453     UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
454     UINT8 pkt_size = 0;
455 
456     STREAM_SKIP_UINT16(p);
457     STREAM_TO_UINT8 (pkt_size, p);
458 
459     if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
460         // CVSD
461         if(status != BTM_SCO_DATA_CORRECT){
462             APPL_TRACE_DEBUG("%s: not a correct frame(%d).", __func__, status);
463         }
464         btc_hf_client_incoming_data_cb_to_app(p, pkt_size);
465     } else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
466         // mSBC
467         UINT8 *data = NULL;
468 
469         if (pkt_size != hf_inout_pkt_size) {
470             bta_hf_client_co_cb.is_bad_frame = true;
471         }
472         if (status != BTM_SCO_DATA_CORRECT) {
473             bta_hf_client_co_cb.is_bad_frame = true;
474         }
475         if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
476             if (bta_hf_client_co_cb.decode_first_pkt){
477                 if (!bta_hf_client_co_cb.is_bad_frame){
478                     memcpy(bta_hf_client_co_cb.decode_msbc_data, p, pkt_size);
479                 }
480             } else {
481                 if (!bta_hf_client_co_cb.is_bad_frame){
482                     memcpy(bta_hf_client_co_cb.decode_msbc_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
483                 }
484 
485                 data = bta_hf_client_co_cb.decode_msbc_data;
486                 bta_hf_client_decode_msbc_frame(&data, &pkt_size, bta_hf_client_co_cb.is_bad_frame);
487                 bta_hf_client_co_cb.is_bad_frame = false;
488             }
489             bta_hf_client_co_cb.decode_first_pkt = !bta_hf_client_co_cb.decode_first_pkt;
490 
491         } else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
492             data = p;
493             bta_hf_client_decode_msbc_frame(&data, &pkt_size, bta_hf_client_co_cb.is_bad_frame);
494             bta_hf_client_co_cb.is_bad_frame = false;
495         } else {
496             //Never run to here.
497         }
498     } else {
499         APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
500     }
501 }
502 
503 #endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
504 
505 #endif /* #if (BTA_HF_INCLUDED == TRUE) */
506