Merge branch 'bugfix/bta_disable_not_run_v5.5' into 'release/v5.5'

fix(bt/bluedroid): fixed BTA event dispatch race during module disable (v5.5)

See merge request espressif/esp-idf!51976
This commit is contained in:
Wang Meng Yang
2026-08-24 17:29:10 +08:00
16 changed files with 23 additions and 13 deletions
@@ -2015,6 +2015,7 @@ void bta_av_dereg_comp(tBTA_AV_DATA *p_data)
#endif
if (p_cb->disabling) {
bta_sys_deregister(BTA_ID_AV);
p_cb->disabling = FALSE;
bta_av_cb.features = 0;
}
@@ -87,7 +87,6 @@ void BTA_AvDisable(void)
{
BT_HDR *p_buf;
bta_sys_deregister(BTA_ID_AV);
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
p_buf->event = BTA_AV_API_DISABLE_EVT;
bta_sys_sendmsg(p_buf);
@@ -175,6 +175,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
if (p_cb->state != BTA_GATTC_STATE_DISABLING) {
p_cb->state = BTA_GATTC_STATE_DISABLED;
memset(p_cb, 0, sizeof(tBTA_GATTC_CB));
bta_sys_deregister(BTA_ID_GATTC);
}
}
@@ -1844,6 +1845,7 @@ void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
if (bta_gattc_num_reg_app() == 0 && p_cb->state == BTA_GATTC_STATE_DISABLING) {
p_cb->state = BTA_GATTC_STATE_DISABLED;
bta_sys_deregister(BTA_ID_GATTC);
}
}
@@ -65,7 +65,6 @@ void BTA_GATTC_Disable(void)
p_buf->event = BTA_GATTC_API_DISABLE_EVT;
bta_sys_sendmsg(p_buf);
}
bta_sys_deregister(BTA_ID_GATTC);
}
@@ -159,6 +159,8 @@ void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
} else {
APPL_TRACE_ERROR("GATTS not enabled");
}
bta_sys_deregister(BTA_ID_GATTS);
}
/*******************************************************************************
@@ -66,7 +66,6 @@ void BTA_GATTS_Disable(void)
p_buf->event = BTA_GATTS_API_DISABLE_EVT;
bta_sys_sendmsg(p_buf);
}
bta_sys_deregister(BTA_ID_GATTS);
}
@@ -148,6 +148,8 @@ void bta_hd_api_disable(void)
APPL_TRACE_ERROR("%s: Failed to deregister HID device (%d)", __func__, ret);
}
bta_sys_deregister(BTA_ID_HD);
(*bta_hd_cb.p_cback)(BTA_HD_DISABLE_EVT, (tBTA_HD *)&status);
memset(&bta_hd_cb, 0, sizeof(tBTA_HD_CB));
@@ -492,7 +492,7 @@ void bta_ag_scb_dealloc(tBTA_AG_SCB *p_scb)
memset(p_scb, 0, sizeof(tBTA_AG_SCB));
p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
/* If all scbs are deallocated, callback with disable event */
if (!bta_sys_is_register (BTA_ID_AG)) {
if (bta_ag_cb.disabling) {
for (idx = 0; idx < BTA_AG_NUM_SCB; idx++) {
if (bta_ag_cb.scb[idx].in_use) {
allocated = TRUE;
@@ -500,6 +500,8 @@ void bta_ag_scb_dealloc(tBTA_AG_SCB *p_scb)
}
}
if (!allocated) {
bta_ag_cb.disabling = FALSE;
bta_sys_deregister(BTA_ID_AG);
(*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
}
}
@@ -822,8 +824,7 @@ static void bta_ag_api_disable(tBTA_AG_DATA *p_data)
APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ...");
return;
}
/* De-register with BTA system manager */
bta_sys_deregister(BTA_ID_AG);
bta_ag_cb.disabling = TRUE;
for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
if (p_scb->in_use) {
@@ -834,6 +835,8 @@ static void bta_ag_api_disable(tBTA_AG_DATA *p_data)
if (!do_dereg) {
/* Done, send callback evt to app */
bta_ag_cb.disabling = FALSE;
bta_sys_deregister(BTA_ID_AG);
(*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
}
bta_sys_collision_register (BTA_ID_AG, NULL);
@@ -367,6 +367,7 @@ typedef struct
tBTA_AG_CBACK *p_cback; /* application callback */
tBTA_AG_PARSE_MODE parse_mode; /* parse/pass-through mode */
BOOLEAN msbc_enabled;
BOOLEAN disabling;
} tBTA_AG_CB;
/*****************************************************************************
@@ -323,6 +323,7 @@ void bta_hf_client_scb_disable(void)
bta_hf_client_at_reset();
bta_hf_client_scb_init();
bta_sys_deregister(BTA_ID_HS);
if (bta_hf_client_cb.p_cback) {
(*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_DISABLE_EVT, NULL);
@@ -487,9 +488,6 @@ static void bta_hf_client_api_disable(tBTA_HF_CLIENT_DATA *p_data)
return;
}
/* De-register with BTA system manager */
bta_sys_deregister(BTA_ID_HS);
bta_hf_client_sm_execute(BTA_HF_CLIENT_API_DEREGISTER_EVT, p_data);
bta_sys_collision_register (BTA_ID_HS, NULL);
@@ -93,7 +93,6 @@ void BTA_HhDisable(void)
{
BT_HDR *p_buf;
bta_sys_deregister(BTA_ID_HH);
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR))) != NULL) {
p_buf->event = BTA_HH_API_DISABLE_EVT;
bta_sys_sendmsg(p_buf);
@@ -481,6 +481,8 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
}
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
bta_sys_deregister(BTA_ID_HH);
if (bta_hh_cb.p_cback) {
tBTA_HH data = {0};
data.status = status;
@@ -767,6 +767,8 @@ void bta_jv_disable (tBTA_JV_MSG *p_data)
bta_jv_cb.pm_cb[i].handle = BTA_JV_PM_HANDLE_CLEAR;
}
bta_sys_deregister(BTA_ID_JV);
if (p_data->disable.p_cback) {
p_data->disable.p_cback(BTA_JV_DISABLE_EVT, (tBTA_JV *)&evt_data, NULL);
}
@@ -284,8 +284,6 @@ void bta_pba_client_api_disable(tBTA_PBA_CLIENT_DATA *p_data)
if (!bta_sys_is_register(BTA_ID_PBC)) {
return;
}
/* deregister with BTA system manager */
bta_sys_deregister(BTA_ID_PBC);
/* close all connections */
for (int i = 0; i < PBA_CLIENT_MAX_CONNECTION; ++i) {
@@ -297,6 +295,7 @@ void bta_pba_client_api_disable(tBTA_PBA_CLIENT_DATA *p_data)
/* store and clear callback function */
tBTA_PBA_CLIENT_CBACK *p_cback = bta_pba_client_cb.p_cback;
bta_pba_client_cb.p_cback = NULL;
bta_sys_deregister(BTA_ID_PBC);
if(p_cback) {
p_cback(BTA_PBA_CLIENT_DISABLE_EVT, NULL);
@@ -653,6 +653,8 @@ void bta_sdp_disable(tBTA_SDP_MSG *p_data)
}
}
bta_sys_deregister(BTA_ID_SDP);
if (dm_cbk) {
dm_cbk(BTA_SDP_DISABLE_EVT, &bta_sdp, NULL);
}
@@ -513,7 +513,7 @@ void bta_sys_event(void * param)
id = (UINT8) (p_msg->event >> 8);
/* verify id and call subsystem event handler */
if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
if ((id < BTA_ID_MAX) && bta_sys_cb.is_reg[id] && (bta_sys_cb.reg[id] != NULL)) {
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
} else {
APPL_TRACE_WARNING("BTA got unregistered event id %d\n", id);