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