fix(ble/bluedroid): Fix incorrect state issue when unregistering BLE GATTC application

This commit is contained in:
zhanghaipeng 2024-07-30 11:47:26 +08:00
parent c4fc74a6de
commit f88ac25595
4 changed files with 31 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -55,7 +55,10 @@ esp_bluedroid_status_t esp_bluedroid_get_status(void);
esp_err_t esp_bluedroid_enable(void); esp_err_t esp_bluedroid_enable(void);
/** /**
* @brief Disable bluetooth, must prior to esp_bluedroid_deinit(). * @brief Disable Bluetooth, must be called prior to esp_bluedroid_deinit().
*
* @note Before calling this API, ensure that all activities related to
* the application, such as connections, scans, etc., are properly closed.
* *
* @return * @return
* - ESP_OK : Succeed * - ESP_OK : Succeed

View File

@ -299,10 +299,14 @@ esp_err_t esp_ble_gattc_app_register(uint16_t app_id);
/** /**
* @brief This function is called to unregister an application * @brief This function is called to unregister an application
* from GATTC module. * from the GATTC module.
* *
* @param[in] gattc_if: Gatt client access interface. * @param[in] gattc_if: Gatt client access interface.
* *
* @note Before calling this API, ensure that all activities
* related to the application, such as connections, scans, ADV,
* are properly closed.
*
* @return * @return
* - ESP_OK: success * - ESP_OK: success
* - other: failed * - other: failed
@ -608,7 +612,7 @@ esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id,
* *
* @param[in] gattc_if: Gatt client access interface. * @param[in] gattc_if: Gatt client access interface.
* @param[in] conn_id : connection ID. * @param[in] conn_id : connection ID.
* @param[in] handle : characteritic handle to read. * @param[in] handle : characteristic handle to read.
* @param[in] auth_req : authenticate request type * @param[in] auth_req : authenticate request type
* *
* @return * @return

View File

@ -63,7 +63,7 @@ static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op,
tGATT_CL_COMPLETE *p_data); tGATT_CL_COMPLETE *p_data);
static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb); static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb);
static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda); static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested); static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data); static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
@ -154,7 +154,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
APPL_TRACE_DEBUG("bta_gattc_disable"); APPL_TRACE_DEBUG("bta_gattc_disable");
if (p_cb->state != BTA_GATTC_STATE_ENABLED) { if (p_cb->state != BTA_GATTC_STATE_ENABLED) {
APPL_TRACE_ERROR("not enabled or disable in pogress"); APPL_TRACE_ERROR("not enabled or disable in progress");
return; return;
} }
@ -227,7 +227,7 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) { if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) {
p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT; p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT;
p_buf->client_if = p_cb->cl_rcb[i].client_if; p_buf->client_if = p_cb->cl_rcb[i].client_if;
APPL_TRACE_DEBUG("GATTC getbuf sucess.\n"); APPL_TRACE_DEBUG("GATTC getbuf success.\n");
bta_sys_sendmsg(p_buf); bta_sys_sendmsg(p_buf);
status = BTA_GATT_OK; status = BTA_GATT_OK;
} else { } else {
@ -841,6 +841,9 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
(* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data); (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data);
} }
// Please note that BTA_GATTC_CLOSE_EVT will run in the BTC task.
// because bta_gattc_deregister_cmpl did not execute as expected(this is a known issue),
// we will run it again in bta_gattc_clcb_dealloc_by_conn_id.
if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) { if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
bta_gattc_deregister_cmpl(p_clreg); bta_gattc_deregister_cmpl(p_clreg);
} }
@ -1672,7 +1675,7 @@ void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
** Returns void ** Returns void
** **
*******************************************************************************/ *******************************************************************************/
static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
{ {
tBTA_GATTC_CB *p_cb = &bta_gattc_cb; tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
tBTA_GATTC_IF client_if = p_clreg->client_if; tBTA_GATTC_IF client_if = p_clreg->client_if;
@ -2118,7 +2121,7 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
bta_gattc_proc_other_indication(p_clcb, op, p_data, &notify); bta_gattc_proc_other_indication(p_clcb, op, p_data, &notify);
} }
} else if (op == GATTC_OPTYPE_INDICATION) { } else if (op == GATTC_OPTYPE_INDICATION) {
/* no one intersted and need ack? */ /* no one interested and need ack? */
APPL_TRACE_DEBUG("%s no one interested, ack now", __func__); APPL_TRACE_DEBUG("%s no one interested, ack now", __func__);
GATTC_SendHandleValueConfirm(conn_id, handle); GATTC_SendHandleValueConfirm(conn_id, handle);
} }
@ -2235,7 +2238,7 @@ static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYP
** **
** Function bta_gattc_init_clcb_conn ** Function bta_gattc_init_clcb_conn
** **
** Description Initaite a BTA CLCB connection ** Description Initiate a BTA CLCB connection
** **
** Returns void ** Returns void
** **
@ -2252,7 +2255,7 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
return; return;
} }
/* initaite a new connection here */ /* initiate a new connection here */
if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) { if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) {
gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;

View File

@ -160,7 +160,7 @@ UINT8 bta_gattc_num_reg_app(void)
** **
** Function bta_gattc_find_clcb_by_cif ** Function bta_gattc_find_clcb_by_cif
** **
** Description get clcb by client interface and remote bd adddress ** Description get clcb by client interface and remote bd address
** **
** Returns pointer to the clcb ** Returns pointer to the clcb
** **
@ -322,12 +322,18 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
} }
} }
extern void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id) void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id)
{ {
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
if (p_clcb) { if (p_clcb) {
tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb;
bta_gattc_clcb_dealloc(p_clcb); bta_gattc_clcb_dealloc(p_clcb);
// there is a workaround: if there is no connect, we will reset it.
if (p_clreg && p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
bta_gattc_deregister_cmpl(p_clreg);
}
} }
} }
@ -517,7 +523,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1); cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1);
memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len); memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len);
} else { } else {
APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__); APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__);
return FALSE; return FALSE;
} }
} else { } else {
@ -525,7 +531,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA)); memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA));
memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA)); memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA));
} else { } else {
APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__); APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__);
return FALSE; return FALSE;
} }
} }
@ -919,7 +925,7 @@ BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
** **
** Function bta_gattc_find_int_conn_clcb ** Function bta_gattc_find_int_conn_clcb
** **
** Description try to locate a clcb when an internal connecion event arrives. ** Description try to locate a clcb when an internal connection event arrives.
** **
** Returns pointer to the clcb ** Returns pointer to the clcb
** **