1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2012 Broadcom Corporation
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 
19 #define LOG_TAG "bt_btc_bta_ag"
20 
21 #include "btc_hf_ag.h"
22 #include "bta_ag_int.h"
23 #include "bta/bta_api.h"
24 #include "bta/bta_ag_api.h"
25 #include "bta/bta_ag_co.h"
26 #include "bta/bta_dm_co.h"
27 #include "common/bt_target.h"
28 #include "hci/hci_audio.h"
29 #include "osi/allocator.h"
30 #include <string.h>
31 
32 #if (BTA_AG_INCLUDED == TRUE)
33 
34 /*******************************************************************************
35  *                                 CONST
36 ********************************************************************************/
37 #if (BTM_SCO_HCI_INCLUDED == TRUE)
38 #include "oi_codec_sbc.h"
39 #include "oi_status.h"
40 #include "sbc_encoder.h"
41 
42 #if (PLC_INCLUDED == TRUE)
43 #include "sbc_plc.h"
44 typedef struct {
45     bool first_good_frame_found;
46     sbc_plc_state_t plc_state;
47     int16_t sbc_plc_out[SBC_FS];
48 } bta_hf_ct_plc_t;
49 #if HFP_DYNAMIC_MEMORY == FALSE
50 static bta_hf_ct_plc_t bta_hf_ct_plc;
51 #else
52 static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
53 #define bta_hf_ct_plc (*bta_hf_ct_plc_ptr)
54 #endif  ///HFP_DYNAMIC_MEMORY == FALSE
55 #endif  ///(PLC_INCLUDED == TRUE)
56 
57 #define HF_SBC_DEC_CONTEXT_DATA_LEN     (CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS))
58 #define HF_SBC_DEC_RAW_DATA_SIZE        240
59 #define HF_SBC_ENC_RAW_DATA_SIZE        240
60 
61 /* BTA-AG-CO control block to map bdaddr to BTA handle */
62 typedef struct
63 {
64     OI_CODEC_SBC_DECODER_CONTEXT    decoder_context;
65     OI_UINT32                       decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
66     OI_INT16                        decode_raw_data[HF_SBC_DEC_RAW_DATA_SIZE];
67 
68     SBC_ENC_PARAMS                  encoder;
69 
70     UINT8                           sequence_number;
71     bool                            is_bad_frame;
72     bool                            decode_first_pkt;
73     OI_BYTE                         decode_msbc_data[BTM_MSBC_FRAME_SIZE];
74     bool                            encode_first_pkt;
75     OI_BYTE                         encode_msbc_data[BTM_MSBC_FRAME_SIZE];
76 } bta_ag_co_cb_t;
77 
78 #if HFP_DYNAMIC_MEMORY == FALSE
79 static bta_ag_co_cb_t bta_ag_co_cb;
80 #else
81 static bta_ag_co_cb_t *bta_ag_co_cb_ptr;
82 #define bta_ag_co_cb (*bta_ag_co_cb_ptr)
83 #endif /* HFP_DYNAMIC_MEMORY == FALSE */
84 
85 static UINT8 hf_air_mode = BTM_SCO_AIR_MODE_TRANSPNT;
86 static UINT8 hf_inout_pkt_size = 0;
87 
88 /* =========================================================================
89 *                   AG pass-through mode handle
90 *===========================================================================*/
91 /*******************************************************************************
92  **
93  ** Function         bta_ag_co_tx_write
94  **
95  ** Description      This function is called by the AG to send data to the
96  **                  phone when the AG is configured for AT command pass-through.
97  **                  The implementation of this function must copy the data to
98  **                  the phones memory.
99  **
100  ** Returns          void
101  **
102  *******************************************************************************/
bta_ag_co_tx_write(UINT16 handle,UNUSED_ATTR UINT8 * p_data,UINT16 len)103 void bta_ag_co_tx_write(UINT16 handle, UNUSED_ATTR UINT8 * p_data, UINT16 len)
104 {
105     BTIF_TRACE_DEBUG( "bta_ag_co_tx_write: handle: %d, len: %d", handle, len );
106 }
107 
108 /******************************************************************************
109 **
110 ** Function         bta_ag_ci_rx_write
111 **
112 ** Description      This function is called to send data to the AG when the AG
113 **                  is configured for AT command pass-through. The function
114 **                  copies data to an event buffer and sends it.
115 **
116 ** Returns          void
117 **
118 ******************************************************************************/
bta_ag_ci_rx_write(UINT16 handle,char * p_data,UINT16 len)119 void bta_ag_ci_rx_write(UINT16 handle, char *p_data, UINT16 len)
120 {
121     tBTA_AG_CI_RX_WRITE *p_buf;
122     UINT16 len_remaining = len;
123     char *p_data_area;
124 
125     if (len > (BT_DEFAULT_BUFFER_SIZE - sizeof(tBTA_AG_CI_RX_WRITE) - 1)) {
126         len = BT_DEFAULT_BUFFER_SIZE - sizeof(tBTA_AG_CI_RX_WRITE) - 1;
127     }
128 
129     while (len_remaining) {
130         if (len_remaining < len) {
131             len = len_remaining;
132         }
133         if ((p_buf = (tBTA_AG_CI_RX_WRITE *) osi_malloc((UINT16)(sizeof(tBTA_AG_CI_RX_WRITE) + len + 1))) != NULL) {
134             p_buf->hdr.event = BTA_AG_CI_RX_WRITE_EVT;
135             p_buf->hdr.layer_specific = handle;
136             p_data_area = (char *)(p_buf+1);        /* Point to data area after header */
137             strncpy(p_data_area, p_data, len);
138             p_data_area[len] = 0;
139             bta_sys_sendmsg(p_buf);
140         } else {
141             APPL_TRACE_ERROR("ERROR: Unable to allocate buffer to hold AT response code. len=%i", len);
142             break;
143         }
144         len_remaining-=len;
145         p_data+=len;
146     }
147 }
148 
149 /******************************************************************************
150 **
151 ** Function         bta_ag_ci_slc_ready
152 **
153 ** Description      This function is called to notify AG that SLC is up at
154 **                  the application. This funcion is only used when the app
155 **                  is running in pass-through mode.
156 **
157 ** Returns          void
158 **
159 ******************************************************************************/
bta_ag_ci_slc_ready(UINT16 handle)160 void bta_ag_ci_slc_ready(UINT16 handle)
161 {
162     tBTA_AG_DATA *p_buf;
163     if ((p_buf = (tBTA_AG_DATA *)osi_malloc(sizeof(tBTA_AG_DATA))) != NULL) {
164         p_buf->hdr.event = BTA_AG_CI_SLC_READY_EVT;
165         p_buf->hdr.layer_specific = handle;
166         bta_sys_sendmsg(p_buf);
167     }
168 }
169 
170 /*******************************************************************************
171  *                        H2 & DEC
172 ********************************************************************************/
173 /*******************************************************************************
174 **
175 ** Function         bta_ag_h2_header
176 **
177 ** Description      This function is called to fill in H2 header
178 **
179 ** Returns          void
180 **
181 *******************************************************************************/
bta_ag_h2_header(UINT16 * p_buf)182 static void bta_ag_h2_header(UINT16 *p_buf)
183 {
184     // H2: Header with synchronization word and sequence number
185 #define BTA_HF_H2_HEADER                0x0801
186 #define BTA_HF_H2_HEADER_BIT0_MASK   (1 << 0)
187 #define BTA_HF_H2_HEADER_BIT1_MASK   (1 << 1)
188 #define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
189 #define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
190 #define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
191 #define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
192 
193     UINT16 h2_header = BTA_HF_H2_HEADER;
194     UINT8 h2_header_sn0 = bta_ag_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT0_MASK;
195     UINT8 h2_header_sn1 = bta_ag_co_cb.sequence_number & BTA_HF_H2_HEADER_BIT1_MASK;
196     h2_header |= (h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET1
197                 | h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET2
198                 | h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 - 1)
199                 | h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 - 1)
200                 );
201     bta_ag_co_cb.sequence_number++;
202     *p_buf = h2_header;
203 }
204 
205 /*******************************************************************************
206  **
207  ** Function       bta_hf_dec_init
208  **
209  ** Description    Initialize decoding task
210  **
211  ** Returns        void
212  **
213  *******************************************************************************/
bta_hf_dec_init(void)214 static void bta_hf_dec_init(void)
215 {
216 #if (PLC_INCLUDED == TRUE)
217     sbc_plc_init(&(bta_hf_ct_plc.plc_state));
218 #endif  ///(PLC_INCLUDED == TRUE)
219 
220     OI_STATUS status = OI_CODEC_SBC_DecoderReset(&bta_ag_co_cb.decoder_context, bta_ag_co_cb.decoder_context_data,
221                                        HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE);
222     if (!OI_SUCCESS(status)) {
223         APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
224     }
225 }
226 
227 /*******************************************************************************
228  **
229  ** Function       bta_hf_enc_init
230  **
231  ** Description    Initialize encoding task for mSBC
232  **
233  ** Returns        void
234  **
235  *******************************************************************************/
bta_hf_enc_init(void)236 static void bta_hf_enc_init(void)
237 {
238     bta_ag_co_cb.sequence_number = 0;
239     bta_ag_co_cb.decode_first_pkt = true;
240     bta_ag_co_cb.encode_first_pkt = true;
241     bta_ag_co_cb.is_bad_frame =  false;
242 
243     bta_ag_co_cb.encoder.sbc_mode = SBC_MODE_MSBC;
244     bta_ag_co_cb.encoder.s16NumOfBlocks    = 15;
245     bta_ag_co_cb.encoder.s16NumOfSubBands  = 8;
246     bta_ag_co_cb.encoder.s16AllocationMethod = SBC_LOUDNESS;
247     bta_ag_co_cb.encoder.s16BitPool   = 26;
248     bta_ag_co_cb.encoder.s16ChannelMode = SBC_MONO;
249     bta_ag_co_cb.encoder.s16NumOfChannels = 1;
250     bta_ag_co_cb.encoder.s16SamplingFreq = SBC_sf16000;
251 
252     SBC_Encoder_Init(&(bta_ag_co_cb.encoder));
253 }
254 
255 /*******************************************************************************
256 **
257 ** Function         bta_ag_decode_msbc_frame
258 **
259 ** Description      This function is called decode a mSBC frame
260 **
261 ** Returns          void
262 **
263 *******************************************************************************/
bta_ag_decode_msbc_frame(UINT8 ** data,UINT8 * length,BOOLEAN is_bad_frame)264 static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame)
265 {
266     OI_STATUS status;
267     const OI_BYTE *zero_signal_frame_data;
268     UINT8 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
269     UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
270 
271     if (is_bad_frame) {
272         status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
273     } else {
274         status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, (const OI_BYTE **)data,
275                                           (OI_UINT32 *)length,
276                                           (OI_INT16 *)bta_ag_co_cb.decode_raw_data,
277                                           (OI_UINT32 *)&sbc_raw_data_size);
278     }
279 
280 // PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
281 #if (PLC_INCLUDED == TRUE)
282     switch(status) {
283         case OI_OK:
284         {
285             bta_hf_ct_plc.first_good_frame_found = TRUE;
286             sbc_plc_good_frame(&(bta_hf_ct_plc.plc_state), (int16_t *)bta_ag_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
287         }
288 
289         case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
290         case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
291         case OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA:
292             break;
293 
294         case OI_CODEC_SBC_NO_SYNCWORD:
295         case OI_CODEC_SBC_CHECKSUM_MISMATCH:
296         {
297             if (!bta_hf_ct_plc.first_good_frame_found) {
298                 break;
299             }
300             zero_signal_frame_data = sbc_plc_zero_signal_frame();
301             sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
302             status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, &zero_signal_frame_data,
303                                                 (OI_UINT32 *)&zero_signal_frame_len,
304                                                 (OI_INT16 *)bta_ag_co_cb.decode_raw_data,
305                                                 (OI_UINT32 *)&sbc_raw_data_size);
306             sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), bta_ag_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
307             APPL_TRACE_DEBUG("bad frame, using PLC to fix it.");
308             break;
309         }
310 
311         case OI_STATUS_INVALID_PARAMETERS:
312         {
313             // This caused by corrupt frames.
314             // The codec apparently does not recover from this.
315             // Re-initialize the codec.
316             APPL_TRACE_ERROR("Frame decode error: OI_STATUS_INVALID_PARAMETERS");
317 
318             if (!OI_SUCCESS(OI_CODEC_SBC_DecoderReset(&bta_ag_co_cb.decoder_context, bta_ag_co_cb.decoder_context_data,
319                                        HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE))) {
320                 APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
321             }
322             break;
323         }
324 
325         default:
326             APPL_TRACE_ERROR("Frame decode error: %d", status);
327             break;
328     }
329 #endif  ///(PLC_INCLUDED == TRUE)
330 
331     if (OI_SUCCESS(status)) {
332         btc_hf_incoming_data_cb_to_app((const uint8_t *)(bta_hf_ct_plc.sbc_plc_out), sbc_raw_data_size);
333     }
334 }
335 
336 /*******************************************************************************
337  *                       BTA AG SCO CO FUNCITONS
338 ********************************************************************************/
339 /*******************************************************************************
340 **
341 ** Function         bta_ag_sco_audio_state
342 **
343 ** Description      This function is called by the AG before the audio connection
344 **                  is brought up, after it comes up, and after it goes down.
345 **
346 ** Parameters       handle - handle of the AG instance
347 **                  state - Audio state
348 **                  codec - if WBS support is compiled in, codec to going to be used is provided
349 **                      and when in SCO_STATE_SETUP, BTM_I2SPCMConfig() must be called with
350 **                      the correct platform parameters.
351 **                      in the other states codec type should not be ignored
352 **
353 ** Returns          void
354 **
355 *******************************************************************************/
356 #if (BTM_WBS_INCLUDED == TRUE)
bta_ag_sco_audio_state(UINT16 handle,UINT8 app_id,UINT8 state,tBTA_AG_PEER_CODEC codec)357 void bta_ag_sco_audio_state(UINT16 handle, UINT8 app_id, UINT8 state, tBTA_AG_PEER_CODEC codec)
358 #else
359 void bta_ag_sco_audio_state(UINT16 handle, UINT8 app_id, UINT8 state)
360 #endif
361 {
362     BTIF_TRACE_DEBUG("bta_ag_sco_audio_state: handle %d, state %d", handle, state);
363     switch (state) {
364         case SCO_STATE_ON:
365         case SCO_STATE_OFF:
366         case SCO_STATE_OFF_TRANSFER:
367         case SCO_STATE_SETUP:
368         default:
369             break;
370     }
371 }
372 
373 /*******************************************************************************
374 **
375 ** Function         bta_ag_sco_co_init
376 **
377 ** Description      Set default data path for SCO/eSCO.
378 **
379 **
380 ** Returns          Void.
381 **
382 *******************************************************************************/
bta_ag_sco_co_init(UINT32 rx_bw,UINT32 tx_bw,tBTA_HFP_CODEC_INFO * p_codec_info,UINT8 app_id)383 tBTA_HFP_SCO_ROUTE_TYPE bta_ag_sco_co_init(UINT32 rx_bw, UINT32 tx_bw, tBTA_HFP_CODEC_INFO *p_codec_info, UINT8 app_id)
384 {
385     APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %d, codec %d", __FUNCTION__, rx_bw, tx_bw, p_codec_info->codec_type);
386     return BTA_HFP_SCO_ROUTE_HCI;
387 }
388 
389 /*******************************************************************************
390 **
391 ** Function         bta_ag_sco_co_open
392 **
393 ** Description      This function is executed by AG when a service level connection
394 **                  is opened.
395 **
396 **
397 ** Returns          void
398 **
399 *******************************************************************************/
bta_ag_sco_co_open(UINT16 handle,tBTM_SCO_AIR_MODE_TYPE air_mode,UINT8 inout_pkt_size,UINT16 event)400 void bta_ag_sco_co_open(UINT16 handle, tBTM_SCO_AIR_MODE_TYPE air_mode, UINT8 inout_pkt_size, UINT16 event)
401 {
402     APPL_TRACE_EVENT("%s hdl %x, pkt_sz %u, event %u", __FUNCTION__, handle, inout_pkt_size, event);
403     hf_air_mode = air_mode;
404     hf_inout_pkt_size = inout_pkt_size;
405 
406     if (air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
407 #if (HFP_DYNAMIC_MEMORY == TRUE)
408         bta_ag_co_cb_ptr = osi_calloc(sizeof(bta_ag_co_cb_t));
409         if (!bta_ag_co_cb_ptr) {
410             APPL_TRACE_ERROR("%s allocate failed", __FUNCTION__);
411             goto error_exit;
412         }
413 #if (PLC_INCLUDED == TRUE)
414         bta_hf_ct_plc_ptr = (bta_hf_ct_plc_t *)osi_calloc(sizeof(bta_hf_ct_plc_t));
415         if (!bta_hf_ct_plc_ptr) {
416             APPL_TRACE_ERROR("%s malloc fail.", __FUNCTION__);
417             goto error_exit;
418         }
419 #endif  ///(PLC_INCLUDED == TRUE)
420 #endif  /// (HFP_DYNAMIC_MEMORY == TRUE)
421         bta_hf_dec_init();
422         bta_hf_enc_init();
423         return;
424     } else {
425         return; // Nothing to do
426     }
427 
428 #if (HFP_DYNAMIC_MEMORY == TRUE)
429 error_exit:;
430     hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
431     hf_inout_pkt_size = 0;
432     if (bta_ag_co_cb_ptr) {
433         osi_free(bta_ag_co_cb_ptr);
434         bta_ag_co_cb_ptr = NULL;
435     }
436 #if (PLC_INCLUDED == TRUE)
437     if (bta_hf_ct_plc_ptr) {
438         osi_free(bta_hf_ct_plc_ptr);
439         bta_hf_ct_plc_ptr = NULL;
440     }
441 #endif  ///(PLC_INCLUDED == TRUE)
442 #endif  /// (HFP_DYNAMIC_MEMORY == TRUE)
443     return;
444 }
445 
446 /*******************************************************************************
447 **
448 ** Function         bta_ag_sco_co_close
449 **
450 ** Description      Nothing but print some log.
451 **
452 ** Returns          void
453 **
454 *******************************************************************************/
bta_ag_sco_co_close(void)455 void bta_ag_sco_co_close(void)
456 {
457     APPL_TRACE_EVENT("%s", __FUNCTION__);
458     if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
459 #if (PLC_INCLUDED == TRUE)
460         sbc_plc_deinit(&(bta_hf_ct_plc.plc_state));
461         bta_hf_ct_plc.first_good_frame_found = FALSE;
462 #if (HFP_DYNAMIC_MEMORY == TRUE)
463         osi_free(bta_hf_ct_plc_ptr);
464         bta_hf_ct_plc_ptr = NULL;
465 #endif  /// (HFP_DYNAMIC_MEMORY == TRUE)
466 #endif  ///(PLC_INCLUDED == TRUE)
467 
468 #if (HFP_DYNAMIC_MEMORY == TRUE)
469         osi_free(bta_ag_co_cb_ptr);
470         bta_ag_co_cb_ptr = NULL;
471 #endif /* HFP_DYNAMIC_MEMORY == TRUE */
472     } else {
473         // Nothing to do
474     }
475     hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN;
476     hf_inout_pkt_size = 0;
477 }
478 
479 /*******************************************************************************
480 **
481 ** Function         bta_ag_sco_co_out_data
482 **
483 ** Description      This function is called to send SCO data over HCI.
484 **
485 ** Returns          number of bytes got from application
486 **
487 *******************************************************************************/
bta_ag_sco_co_out_data(UINT8 * p_buf)488 uint32_t bta_ag_sco_co_out_data(UINT8 *p_buf)
489 {
490     if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
491         // CVSD
492         uint32_t hf_raw_pkt_size = hf_inout_pkt_size;
493         return btc_hf_outgoing_data_cb_to_app(p_buf, hf_raw_pkt_size);
494     } else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
495         // mSBC
496         if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
497             if (bta_ag_co_cb.encode_first_pkt) {
498                 UINT32 size = btc_hf_outgoing_data_cb_to_app((UINT8 *)bta_ag_co_cb.encoder.as16PcmBuffer, HF_SBC_ENC_RAW_DATA_SIZE);
499                 if (size != HF_SBC_ENC_RAW_DATA_SIZE) {
500                     return 0;
501                 }
502                 bta_ag_h2_header((UINT16 *)bta_ag_co_cb.encode_msbc_data);
503                 bta_ag_co_cb.encoder.pu8Packet = bta_ag_co_cb.encode_msbc_data + 2;
504 
505                 SBC_Encoder(&bta_ag_co_cb.encoder);
506                 memcpy(p_buf, bta_ag_co_cb.encode_msbc_data, hf_inout_pkt_size);
507                 bta_ag_co_cb.encode_first_pkt = !bta_ag_co_cb.encode_first_pkt;
508                 return hf_inout_pkt_size;
509             } else {
510                 memcpy(p_buf, bta_ag_co_cb.encode_msbc_data + hf_inout_pkt_size, hf_inout_pkt_size);
511                 bta_ag_co_cb.encode_first_pkt = !bta_ag_co_cb.encode_first_pkt;
512                 return hf_inout_pkt_size;
513             }
514         } else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
515             UINT32 size = btc_hf_outgoing_data_cb_to_app((UINT8 *)bta_ag_co_cb.encoder.as16PcmBuffer, HF_SBC_ENC_RAW_DATA_SIZE);
516             if (size != HF_SBC_ENC_RAW_DATA_SIZE) {
517                 return 0;
518             }
519             bta_ag_h2_header((UINT16 *)p_buf);
520             bta_ag_co_cb.encoder.pu8Packet = p_buf + 2;
521 
522             SBC_Encoder(&bta_ag_co_cb.encoder);
523             return hf_inout_pkt_size;
524         } else {
525             //Never run to here.
526         }
527     } else {
528         APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
529     }
530     return 0;
531 }
532 
533 /*******************************************************************************
534 **
535 ** Function         bta_ag_sco_co_in_data
536 **
537 ** Description      This function is called to send incoming SCO data to application.
538 **
539 ** Returns          void
540 **
541 *******************************************************************************/
bta_ag_sco_co_in_data(BT_HDR * p_buf,tBTM_SCO_DATA_FLAG status)542 void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
543 {
544     UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
545     UINT8 pkt_size = 0;
546     STREAM_SKIP_UINT16(p);
547     STREAM_TO_UINT8(pkt_size, p);
548 
549     if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
550         // CVSD
551         if(status != BTM_SCO_DATA_CORRECT) {
552             APPL_TRACE_DEBUG("%s: not a correct frame(%d).", __func__, status);
553         }
554         btc_hf_incoming_data_cb_to_app(p, pkt_size);
555     } else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
556         // mSBC
557         UINT8 *data = NULL;
558         if (pkt_size != hf_inout_pkt_size) {
559             bta_ag_co_cb.is_bad_frame = true;
560         }
561         if (status != BTM_SCO_DATA_CORRECT) {
562             bta_ag_co_cb.is_bad_frame = true;
563         }
564         if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE / 2) {
565             if (bta_ag_co_cb.decode_first_pkt) {
566                 if (!bta_ag_co_cb.is_bad_frame) {
567                     memcpy(bta_ag_co_cb.decode_msbc_data, p, pkt_size);
568                 }
569             } else {
570                 if (!bta_ag_co_cb.is_bad_frame) {
571                     memcpy(bta_ag_co_cb.decode_msbc_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
572                 }
573                 data = bta_ag_co_cb.decode_msbc_data;
574                 bta_ag_decode_msbc_frame(&data, &pkt_size, bta_ag_co_cb.is_bad_frame);
575                 bta_ag_co_cb.is_bad_frame = false;
576             }
577             bta_ag_co_cb.decode_first_pkt = !bta_ag_co_cb.decode_first_pkt;
578         } else if (hf_inout_pkt_size == BTM_MSBC_FRAME_SIZE) {
579             data = p;
580             bta_ag_decode_msbc_frame(&data, &pkt_size, bta_ag_co_cb.is_bad_frame);
581             bta_ag_co_cb.is_bad_frame = false;
582         } else {
583             //Never run to here.
584         }
585     } else {
586         APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
587     }
588 }
589 #endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
590 #endif /* #if (BTA_AG_INCLUDED == TRUE) */
591