Merge branch 'bugfix/ai_review_hfp_v5.4' into 'release/v5.4'

fix(bt): Fix the critical issues related to HFP from AI review report (v5.4)

See merge request espressif/esp-idf!50009
This commit is contained in:
Jiang Jiang Jian
2026-06-26 14:08:19 +08:00
10 changed files with 62 additions and 11 deletions

View File

@@ -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));
#endif
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),
p_bta_dm_pcm_cb->src_sps, (INT32 *) &(p_bta_dm_pcm_cb->cur_pos), p_bta_dm_pcm_cb->overlap_area);
} else {

View File

@@ -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;
}
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] == ';') {
val.str[dst] = '\0';
break;
@@ -925,6 +925,9 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
src++;
dst++;
}
if (dst >= BTA_AG_AT_MAX_LEN) {
val.str[BTA_AG_AT_MAX_LEN] = '\0';
}
}
break;
}

View File

@@ -811,6 +811,7 @@ static void bta_ag_sco_event(tBTA_AG_SCB *p_scb, UINT8 event)
}
} else {
osi_free(p_buf);
break;
}
} else {
osi_free(p_buf);

View File

@@ -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);
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]);
bta_sys_remove_uuid(bta_ag_uuid[i]);
}

View File

@@ -300,6 +300,14 @@ void bta_hf_client_scb_disable(void)
{
APPL_TRACE_DEBUG("%s", __FUNCTION__);
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();
if (bta_hf_client_cb.p_cback) {

View File

@@ -570,6 +570,7 @@ static void bta_hf_client_sco_event(UINT8 event)
}
} else {
osi_free(p_buf);
break;
}
} else {
osi_free(p_buf);

View File

@@ -204,7 +204,10 @@ void bta_hf_client_del_record(tBTA_HF_CLIENT_DATA *p_data)
if (bta_hf_client_cb.sdp_handle != 0) {
SDP_DeleteRecord(bta_hf_client_cb.sdp_handle);
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);
bta_sys_remove_uuid(UUID_SERVCLASS_HF_HANDSFREE);
}

View File

@@ -265,16 +265,18 @@ static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad
{
OI_STATUS status;
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;
if (is_bad_frame) {
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
} else {
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_UINT32 *)&sbc_raw_data_size);
*length = (UINT8)frame_len;
}
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
@@ -301,7 +303,7 @@ static void bta_ag_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad
zero_signal_frame_data = sbc_plc_zero_signal_frame();
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,
(OI_UINT32 *)&zero_signal_frame_len,
&zero_signal_frame_len,
(OI_INT16 *)bta_ag_co_cb.decode_raw_data,
(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);
@@ -572,6 +574,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);
}
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_co_cb.is_bad_frame = false;
}

View File

@@ -159,6 +159,14 @@ do {
************************************************************************************/
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) {
if (bdcmp(bd_addr->address, hf_local_param.btc_hf_cb[i].connected_bda.address) == 0) {
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)
{
#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) {
if (hf_local_param.initialized &&
hf_local_param.btc_hf_cb[idx].connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED) {
if (hf_local_param.btc_hf_cb[idx].connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED) {
return idx;
}
}
@@ -192,6 +207,14 @@ static int btc_hf_latest_connected_idx(void)
{
struct timespec now, conn_time_delta;
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);
conn_time_delta.tv_sec = now.tv_sec;

View File

@@ -385,16 +385,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){
OI_STATUS status;
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;
if (is_bad_frame){
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
} else {
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_UINT32 *)&sbc_raw_data_size);
*length = (UINT8)frame_len;
}
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
@@ -416,7 +418,7 @@ static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN
zero_signal_frame_data = sbc_plc_zero_signal_frame();
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,
(OI_UINT32 *)&zero_signal_frame_len,
&zero_signal_frame_len,
(OI_INT16 *)bta_hf_client_co_cb.decode_raw_data,
(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);
@@ -488,6 +490,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;
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_co_cb.is_bad_frame = false;
}