From d70379935655f24cd204b0687f535ec0beb403bf Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Tue, 30 Jul 2024 11:47:26 +0800 Subject: [PATCH] fix(ble/bluedroid): Fix incorrect state issue when unregistering BLE GATTC application --- .../bluedroid/api/include/api/esp_bt_main.h | 7 +++++-- .../bluedroid/api/include/api/esp_gattc_api.h | 8 ++++++-- .../bt/host/bluedroid/bta/gatt/bta_gattc_act.c | 17 ++++++++++------- .../host/bluedroid/bta/gatt/bta_gattc_utils.c | 14 ++++++++++---- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h index b13ae94d0eaf..a626ec655135 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h @@ -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 */ @@ -55,7 +55,10 @@ esp_bluedroid_status_t esp_bluedroid_get_status(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 * - ESP_OK : Succeed diff --git a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h index 13bf16a32815..0c274e203216 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h @@ -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 - * from GATTC module. + * from the GATTC module. * * @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 * - ESP_OK: success * - 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] 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 * * @return diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index b2302fa469fd..543b9b04bf41 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -63,7 +63,7 @@ static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data); 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_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); @@ -154,7 +154,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb) APPL_TRACE_DEBUG("bta_gattc_disable"); 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; } @@ -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) { p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT; 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); status = BTA_GATT_OK; } 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); } + // 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) { 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 ** *******************************************************************************/ -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_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, ¬ify); } } 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__); 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 ** -** Description Initaite a BTA CLCB connection +** Description Initiate a BTA CLCB connection ** ** Returns void ** @@ -2252,7 +2255,7 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda) 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) { gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index 2265e28293c5..b47a9d973345 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -160,7 +160,7 @@ UINT8 bta_gattc_num_reg_app(void) ** ** 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 ** @@ -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) { tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (p_clcb) { + tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb; 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); memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len); } 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; } } 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)); memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA)); } 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; } } @@ -919,7 +925,7 @@ BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda) ** ** 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 **