mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(bt): Fix the critical issues related to HFP from AI review report
HFP AG: - Fix mSBC EV3 second-packet payload length calculation to prevent OOB read and infinite loop - Add init/deinit guards in HF AG helper functions to avoid NULL deref - Return bt_status_t from btc_hf_ag_audio_data_send to avoid silent buffer leak on SLC failure - Break SCO CI data loop when SCO is not open to prevent CPU starvation - Guard BTM_FreeSCN(0) and reset SCN after free in bta_ag_del_records - Use OI_UINT32 for mSBC decode frame length to avoid stack corruption - Bound AT Dial command string copy to BTA_AG_AT_MAX_LEN HFP Client: - Check osi_calloc result before use when reassembling split mSBC frames - Use OI_UINT32 for mSBC decode frame length to avoid stack corruption - Free SDP db, collision/AT timers and queued AT cmds before scb reset on disable - Fix mSBC EV3 second-packet payload length calculation (same as AG) - Reject pcm_resample input smaller than overlap window (96 bytes) on filtered path - Break SCO CI data loop when SCO is not open to prevent CPU starvation - Guard BTM_FreeSCN(0) and reset SCN after free in bta_hf_client_del_record
This commit is contained in:
@@ -651,7 +651,7 @@ esp_err_t esp_hf_ag_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btc_hf_ag_audio_data_send(sync_conn_hdl, (uint8_t *)audio_buf, audio_buf->data, audio_buf->data_len)) {
|
if (btc_hf_ag_audio_data_send(sync_conn_hdl, (uint8_t *)audio_buf, audio_buf->data, audio_buf->data_len) == BT_STATUS_SUCCESS) {
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
|
|||||||
@@ -662,6 +662,9 @@ INT32 BTA_DmPcmResample (void *p_src, UINT32 in_bytes, void *p_dst)
|
|||||||
APPL_TRACE_DEBUG("bta_pcm_resample : insamples %d", (in_bytes / p_bta_dm_pcm_cb->divisor));
|
APPL_TRACE_DEBUG("bta_pcm_resample : insamples %d", (in_bytes / p_bta_dm_pcm_cb->divisor));
|
||||||
#endif
|
#endif
|
||||||
if (p_bta_dm_pcm_cb->can_be_filtered) {
|
if (p_bta_dm_pcm_cb->can_be_filtered) {
|
||||||
|
if (in_bytes < BTA_DM_PCM_OVERLAP_SIZE * 2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
out_sample = (*p_bta_dm_pcm_cb->filter) (p_src, p_dst, (in_bytes / p_bta_dm_pcm_cb->divisor),
|
out_sample = (*p_bta_dm_pcm_cb->filter) (p_src, p_dst, (in_bytes / p_bta_dm_pcm_cb->divisor),
|
||||||
p_bta_dm_pcm_cb->src_sps, (INT32 *) &(p_bta_dm_pcm_cb->cur_pos), p_bta_dm_pcm_cb->overlap_area);
|
p_bta_dm_pcm_cb->src_sps, (INT32 *) &(p_bta_dm_pcm_cb->cur_pos), p_bta_dm_pcm_cb->overlap_area);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -917,7 +917,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
|
|||||||
val.value = BTA_AG_HF_DIAL_NUM;
|
val.value = BTA_AG_HF_DIAL_NUM;
|
||||||
}
|
}
|
||||||
if (event != 0) {
|
if (event != 0) {
|
||||||
while ((val.str[dst] = p_arg[src]) != '\0') {
|
while (dst < BTA_AG_AT_MAX_LEN && (val.str[dst] = p_arg[src]) != '\0') {
|
||||||
if (val.str[dst] == ';') {
|
if (val.str[dst] == ';') {
|
||||||
val.str[dst] = '\0';
|
val.str[dst] = '\0';
|
||||||
break;
|
break;
|
||||||
@@ -925,6 +925,9 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
|
|||||||
src++;
|
src++;
|
||||||
dst++;
|
dst++;
|
||||||
}
|
}
|
||||||
|
if (dst >= BTA_AG_AT_MAX_LEN) {
|
||||||
|
val.str[BTA_AG_AT_MAX_LEN] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -846,6 +846,7 @@ static void bta_ag_sco_event(tBTA_AG_SCB *p_scb, UINT8 event)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
osi_free(p_buf);
|
osi_free(p_buf);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
osi_free(p_buf);
|
osi_free(p_buf);
|
||||||
@@ -1997,9 +1998,10 @@ static void bta_ag_sco_data_send_msbc(tBTA_AG_SCB *p_scb, BT_HDR *p_buf)
|
|||||||
p_buf3->offset = BTA_AG_BUFF_OFFSET_MIN;
|
p_buf3->offset = BTA_AG_BUFF_OFFSET_MIN;
|
||||||
p_buf3->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
|
p_buf3->len = BTA_AG_SCO_OUT_PKT_LEN_EV3;
|
||||||
UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
|
UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
|
||||||
memcpy(p_data3, p_data, BTA_AG_MSBC_FRAME_SIZE - BTA_AG_H2_HEADER_LEN - BTA_AG_SCO_OUT_PKT_LEN_EV3);
|
UINT16 rem_payload = BTA_AG_MSBC_FRAME_SIZE - (BTA_AG_SCO_OUT_PKT_LEN_EV3 - BTA_AG_H2_HEADER_LEN);
|
||||||
p_data += BTA_AG_MSBC_FRAME_SIZE - BTA_AG_H2_HEADER_LEN - BTA_AG_SCO_OUT_PKT_LEN_EV3;
|
memcpy(p_data3, p_data, rem_payload);
|
||||||
total_len -= BTA_AG_MSBC_FRAME_SIZE - BTA_AG_H2_HEADER_LEN - BTA_AG_SCO_OUT_PKT_LEN_EV3;
|
p_data += rem_payload;
|
||||||
|
total_len -= rem_payload;
|
||||||
bta_ag_write_sco_data(p_scb, p_buf2, p_buf3);
|
bta_ag_write_sco_data(p_scb, p_buf2, p_buf3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,7 +266,10 @@ void bta_ag_del_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
|||||||
SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
|
SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
|
||||||
bta_ag_cb.profile[i].sdp_handle = 0;
|
bta_ag_cb.profile[i].sdp_handle = 0;
|
||||||
}
|
}
|
||||||
BTM_FreeSCN(bta_ag_cb.profile[i].scn);
|
if (bta_ag_cb.profile[i].scn != 0) {
|
||||||
|
BTM_FreeSCN(bta_ag_cb.profile[i].scn);
|
||||||
|
bta_ag_cb.profile[i].scn = 0;
|
||||||
|
}
|
||||||
BTM_SecClrService(bta_ag_sec_id[i]);
|
BTM_SecClrService(bta_ag_sec_id[i]);
|
||||||
bta_sys_remove_uuid(bta_ag_uuid[i]);
|
bta_sys_remove_uuid(bta_ag_uuid[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,6 +314,14 @@ void bta_hf_client_scb_disable(void)
|
|||||||
bta_hf_client_cb.scb.p_sco_data = NULL;
|
bta_hf_client_cb.scb.p_sco_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bta_hf_client_cb.scb.p_disc_db != NULL) {
|
||||||
|
(void)SDP_CancelServiceSearch(bta_hf_client_cb.scb.p_disc_db);
|
||||||
|
bta_hf_client_free_db(NULL);
|
||||||
|
}
|
||||||
|
bta_hf_client_cb.scb.colli_tmr_on = FALSE;
|
||||||
|
bta_sys_free_timer(&bta_hf_client_cb.scb.colli_timer);
|
||||||
|
bta_hf_client_at_reset();
|
||||||
|
|
||||||
bta_hf_client_scb_init();
|
bta_hf_client_scb_init();
|
||||||
|
|
||||||
if (bta_hf_client_cb.p_cback) {
|
if (bta_hf_client_cb.p_cback) {
|
||||||
|
|||||||
@@ -557,9 +557,10 @@ static void bta_hf_client_sco_data_send_msbc(BT_HDR *p_buf, UINT16 out_pkt_len)
|
|||||||
p_buf3->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
|
p_buf3->offset = BTA_HF_CLIENT_BUFF_OFFSET_MIN;
|
||||||
p_buf3->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
|
p_buf3->len = BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
|
||||||
UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
|
UINT8 *p_data3 = (UINT8 *)(p_buf3 + 1) + p_buf3->offset;
|
||||||
memcpy(p_data3, p_data, BTA_HF_CLIENT_MSBC_FRAME_SIZE - BTA_HF_CLIENT_H2_HEADER_LEN - BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3);
|
UINT16 rem_payload = BTA_HF_CLIENT_MSBC_FRAME_SIZE - (BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3 - BTA_HF_CLIENT_H2_HEADER_LEN);
|
||||||
p_data += BTA_HF_CLIENT_MSBC_FRAME_SIZE - BTA_HF_CLIENT_H2_HEADER_LEN - BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
|
memcpy(p_data3, p_data, rem_payload);
|
||||||
total_len -= BTA_HF_CLIENT_MSBC_FRAME_SIZE - BTA_HF_CLIENT_H2_HEADER_LEN - BTA_HF_CLIENT_SCO_OUT_PKT_LEN_EV3;
|
p_data += rem_payload;
|
||||||
|
total_len -= rem_payload;
|
||||||
bta_hf_client_write_sco_data(p_buf2, p_buf3);
|
bta_hf_client_write_sco_data(p_buf2, p_buf3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -875,6 +876,7 @@ static void bta_hf_client_sco_event(UINT8 event)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
osi_free(p_buf);
|
osi_free(p_buf);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
osi_free(p_buf);
|
osi_free(p_buf);
|
||||||
|
|||||||
@@ -204,7 +204,10 @@ void bta_hf_client_del_record(tBTA_HF_CLIENT_DATA *p_data)
|
|||||||
if (bta_hf_client_cb.sdp_handle != 0) {
|
if (bta_hf_client_cb.sdp_handle != 0) {
|
||||||
SDP_DeleteRecord(bta_hf_client_cb.sdp_handle);
|
SDP_DeleteRecord(bta_hf_client_cb.sdp_handle);
|
||||||
bta_hf_client_cb.sdp_handle = 0;
|
bta_hf_client_cb.sdp_handle = 0;
|
||||||
BTM_FreeSCN(bta_hf_client_cb.scn);
|
if (bta_hf_client_cb.scn != 0) {
|
||||||
|
BTM_FreeSCN(bta_hf_client_cb.scn);
|
||||||
|
bta_hf_client_cb.scn = 0;
|
||||||
|
}
|
||||||
BTM_SecClrService(BTM_SEC_SERVICE_HF_HANDSFREE);
|
BTM_SecClrService(BTM_SEC_SERVICE_HF_HANDSFREE);
|
||||||
bta_sys_remove_uuid(UUID_SERVCLASS_HF_HANDSFREE);
|
bta_sys_remove_uuid(UUID_SERVCLASS_HF_HANDSFREE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,16 +293,18 @@ static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad
|
|||||||
{
|
{
|
||||||
OI_STATUS status;
|
OI_STATUS status;
|
||||||
const OI_BYTE *zero_signal_frame_data;
|
const OI_BYTE *zero_signal_frame_data;
|
||||||
UINT8 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
|
OI_UINT32 frame_len = *length;
|
||||||
|
OI_UINT32 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
|
||||||
UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
||||||
|
|
||||||
if (is_bad_frame) {
|
if (is_bad_frame) {
|
||||||
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
||||||
} else {
|
} else {
|
||||||
status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, (const OI_BYTE **)data,
|
status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, (const OI_BYTE **)data,
|
||||||
(OI_UINT32 *)length,
|
&frame_len,
|
||||||
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
|
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
|
||||||
(OI_UINT32 *)&sbc_raw_data_size);
|
(OI_UINT32 *)&sbc_raw_data_size);
|
||||||
|
*length = (UINT8)frame_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||||
@@ -329,7 +331,7 @@ static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad
|
|||||||
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
||||||
sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
||||||
status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, &zero_signal_frame_data,
|
status = OI_CODEC_SBC_DecodeFrame(&bta_ag_co_cb.decoder_context, &zero_signal_frame_data,
|
||||||
(OI_UINT32 *)&zero_signal_frame_len,
|
&zero_signal_frame_len,
|
||||||
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
|
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
|
||||||
(OI_UINT32 *)&sbc_raw_data_size);
|
(OI_UINT32 *)&sbc_raw_data_size);
|
||||||
sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), bta_ag_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
|
sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), bta_ag_co_cb.decode_raw_data, bta_hf_ct_plc.sbc_plc_out);
|
||||||
@@ -693,6 +695,7 @@ void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
|||||||
memcpy(bta_ag_co_cb.decode_msbc_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
|
memcpy(bta_ag_co_cb.decode_msbc_data + BTM_MSBC_FRAME_SIZE / 2, p, pkt_size);
|
||||||
}
|
}
|
||||||
data = bta_ag_co_cb.decode_msbc_data;
|
data = bta_ag_co_cb.decode_msbc_data;
|
||||||
|
pkt_size += BTM_MSBC_FRAME_SIZE / 2;
|
||||||
bta_ag_decode_msbc_frame(&data, &pkt_size, bta_ag_co_cb.is_bad_frame);
|
bta_ag_decode_msbc_frame(&data, &pkt_size, bta_ag_co_cb.is_bad_frame);
|
||||||
bta_ag_co_cb.is_bad_frame = false;
|
bta_ag_co_cb.is_bad_frame = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,6 +159,14 @@ do {
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
static int btc_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
|
static int btc_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
|
||||||
{
|
{
|
||||||
|
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||||
|
if (hf_local_param_ptr == NULL) {
|
||||||
|
return BTC_HF_INVALID_IDX;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (bd_addr == NULL || !hf_local_param.initialized || hf_local_param.btc_hf_cb == NULL) {
|
||||||
|
return BTC_HF_INVALID_IDX;
|
||||||
|
}
|
||||||
for (int i = 0; i < btc_max_hf_clients; ++i) {
|
for (int i = 0; i < btc_max_hf_clients; ++i) {
|
||||||
if (bdcmp(bd_addr->address, hf_local_param.btc_hf_cb[i].connected_bda.address) == 0) {
|
if (bdcmp(bd_addr->address, hf_local_param.btc_hf_cb[i].connected_bda.address) == 0) {
|
||||||
return i;
|
return i;
|
||||||
@@ -169,9 +177,16 @@ static int btc_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
|
|||||||
|
|
||||||
static int btc_hf_find_free_idx(void)
|
static int btc_hf_find_free_idx(void)
|
||||||
{
|
{
|
||||||
|
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||||
|
if (hf_local_param_ptr == NULL) {
|
||||||
|
return BTC_HF_INVALID_IDX;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!hf_local_param.initialized || hf_local_param.btc_hf_cb == NULL) {
|
||||||
|
return BTC_HF_INVALID_IDX;
|
||||||
|
}
|
||||||
for (int idx = 0; idx < btc_max_hf_clients; ++idx) {
|
for (int idx = 0; idx < btc_max_hf_clients; ++idx) {
|
||||||
if (hf_local_param.initialized &&
|
if (hf_local_param.btc_hf_cb[idx].connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED) {
|
||||||
hf_local_param.btc_hf_cb[idx].connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED) {
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,6 +207,14 @@ static int btc_hf_latest_connected_idx(void)
|
|||||||
{
|
{
|
||||||
struct timespec now, conn_time_delta;
|
struct timespec now, conn_time_delta;
|
||||||
int latest_conn_idx = BTC_HF_INVALID_IDX;
|
int latest_conn_idx = BTC_HF_INVALID_IDX;
|
||||||
|
#if HFP_DYNAMIC_MEMORY == TRUE
|
||||||
|
if (hf_local_param_ptr == NULL) {
|
||||||
|
return BTC_HF_INVALID_IDX;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!hf_local_param.initialized || hf_local_param.btc_hf_cb == NULL) {
|
||||||
|
return BTC_HF_INVALID_IDX;
|
||||||
|
}
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
conn_time_delta.tv_sec = now.tv_sec;
|
conn_time_delta.tv_sec = now.tv_sec;
|
||||||
|
|
||||||
@@ -938,7 +961,7 @@ bt_status_t btc_hf_ci_sco_data(void)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, uint8_t *p_data, uint8_t data_len)
|
bt_status_t btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, uint8_t *p_data, uint8_t data_len)
|
||||||
{
|
{
|
||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
|
#if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTA_HFP_EXT_CODEC == TRUE)
|
||||||
/* currently, sync_conn_hdl is not used */
|
/* currently, sync_conn_hdl is not used */
|
||||||
@@ -946,10 +969,10 @@ bool btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, ui
|
|||||||
CHECK_HF_SLC_CONNECTED(idx);
|
CHECK_HF_SLC_CONNECTED(idx);
|
||||||
if (idx != BTC_HF_INVALID_IDX) {
|
if (idx != BTC_HF_INVALID_IDX) {
|
||||||
BTA_AgAudioDataSend(hf_local_param.btc_hf_cb[idx].handle, p_buff_start, p_data, data_len);
|
BTA_AgAudioDataSend(hf_local_param.btc_hf_cb[idx].handle, p_buff_start, p_data, data_len);
|
||||||
return true;
|
return BT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return BT_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
|
|||||||
@@ -419,16 +419,18 @@ uint32_t bta_hf_client_sco_co_out_data(UINT8 *p_buf)
|
|||||||
static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame){
|
static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame){
|
||||||
OI_STATUS status;
|
OI_STATUS status;
|
||||||
const OI_BYTE *zero_signal_frame_data;
|
const OI_BYTE *zero_signal_frame_data;
|
||||||
UINT8 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
|
OI_UINT32 frame_len = *length;
|
||||||
|
OI_UINT32 zero_signal_frame_len = BTM_MSBC_FRAME_DATA_SIZE;
|
||||||
UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
UINT32 sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
||||||
|
|
||||||
if (is_bad_frame){
|
if (is_bad_frame){
|
||||||
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
||||||
} else {
|
} else {
|
||||||
status = OI_CODEC_SBC_DecodeFrame(&bta_hf_client_co_cb.decoder_context, (const OI_BYTE **)data,
|
status = OI_CODEC_SBC_DecodeFrame(&bta_hf_client_co_cb.decoder_context, (const OI_BYTE **)data,
|
||||||
(OI_UINT32 *)length,
|
&frame_len,
|
||||||
(OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
|
(OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
|
||||||
(OI_UINT32 *)&sbc_raw_data_size);
|
(OI_UINT32 *)&sbc_raw_data_size);
|
||||||
|
*length = (UINT8)frame_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||||
@@ -450,7 +452,7 @@ static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN
|
|||||||
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
||||||
sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
sbc_raw_data_size = HF_SBC_DEC_RAW_DATA_SIZE;
|
||||||
status = OI_CODEC_SBC_DecodeFrame(&bta_hf_client_co_cb.decoder_context, &zero_signal_frame_data,
|
status = OI_CODEC_SBC_DecodeFrame(&bta_hf_client_co_cb.decoder_context, &zero_signal_frame_data,
|
||||||
(OI_UINT32 *)&zero_signal_frame_len,
|
&zero_signal_frame_len,
|
||||||
(OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
|
(OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
|
||||||
(OI_UINT32 *)&sbc_raw_data_size);
|
(OI_UINT32 *)&sbc_raw_data_size);
|
||||||
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);
|
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);
|
||||||
@@ -523,6 +525,13 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
|||||||
osi_free(p_buf);
|
osi_free(p_buf);
|
||||||
} else {
|
} else {
|
||||||
BT_HDR *p_new_buf = osi_calloc(sizeof(BT_HDR) + BTM_MSBC_FRAME_SIZE);
|
BT_HDR *p_new_buf = osi_calloc(sizeof(BT_HDR) + BTM_MSBC_FRAME_SIZE);
|
||||||
|
if (p_new_buf == NULL) {
|
||||||
|
APPL_TRACE_ERROR("bta_hf_client_sco_co_in_data ENOMEM");
|
||||||
|
osi_free(p_buf);
|
||||||
|
bta_hf_client_co_cb.rx_first_pkt = !bta_hf_client_co_cb.rx_first_pkt;
|
||||||
|
bta_hf_client_co_cb.is_bad_frame = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
p_new_buf->offset = 0;
|
p_new_buf->offset = 0;
|
||||||
UINT8 *p_data = (UINT8 *)(p_new_buf + 1) + p_new_buf->offset;
|
UINT8 *p_data = (UINT8 *)(p_new_buf + 1) + p_new_buf->offset;
|
||||||
memcpy(p_data, bta_hf_client_co_cb.rx_half_msbc_data, BTM_MSBC_FRAME_SIZE / 2);
|
memcpy(p_data, bta_hf_client_co_cb.rx_half_msbc_data, BTM_MSBC_FRAME_SIZE / 2);
|
||||||
@@ -589,6 +598,7 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = bta_hf_client_co_cb.decode_msbc_data;
|
data = bta_hf_client_co_cb.decode_msbc_data;
|
||||||
|
pkt_size += BTM_MSBC_FRAME_SIZE / 2;
|
||||||
bta_hf_client_decode_msbc_frame(&data, &pkt_size, bta_hf_client_co_cb.is_bad_frame);
|
bta_hf_client_decode_msbc_frame(&data, &pkt_size, bta_hf_client_co_cb.is_bad_frame);
|
||||||
bta_hf_client_co_cb.is_bad_frame = false;
|
bta_hf_client_co_cb.is_bad_frame = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ void btc_hf_arg_deep_free(btc_msg_t *msg);
|
|||||||
|
|
||||||
bt_status_t btc_hf_ci_sco_data(void);
|
bt_status_t btc_hf_ci_sco_data(void);
|
||||||
|
|
||||||
bool btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, uint8_t *p_data, uint8_t data_len);
|
bt_status_t btc_hf_ag_audio_data_send(uint16_t sync_conn_hdl, uint8_t *p_buff_start, uint8_t *p_data, uint8_t data_len);
|
||||||
|
|
||||||
void btc_hf_get_profile_status(esp_hf_profile_status_t *param);
|
void btc_hf_get_profile_status(esp_hf_profile_status_t *param);
|
||||||
#endif // BTC_HF_INCLUDED == TRUE
|
#endif // BTC_HF_INCLUDED == TRUE
|
||||||
|
|||||||
Reference in New Issue
Block a user