mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-11-02 18:42:47 +00:00
fix(nimble): guard GATT server context use after ble_gatts_stop()
This commit is contained in:
@@ -1872,20 +1872,28 @@ ble_gatts_free_svc_defs(void)
|
||||
}
|
||||
|
||||
|
||||
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
|
||||
static int
|
||||
ble_gatts_free_conn_clt_cfgs(struct ble_hs_conn *conn, void *arg)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
|
||||
struct ble_gatts_clt_cfg *clt_cfg;
|
||||
|
||||
while ((clt_cfg = STAILQ_FIRST(&conn->bhc_gatt_svr.clt_cfgs)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&conn->bhc_gatt_svr.clt_cfgs, next);
|
||||
ble_gatts_clt_cfg_free(clt_cfg);
|
||||
}
|
||||
#else
|
||||
/* The static build hands the connection a single block carved out of
|
||||
* ble_gatts_clt_cfg_pool rather than a list of nodes.
|
||||
*/
|
||||
if (conn->bhc_gatt_svr.clt_cfgs != NULL) {
|
||||
os_memblock_put(&ble_gatts_clt_cfg_pool, conn->bhc_gatt_svr.clt_cfgs);
|
||||
conn->bhc_gatt_svr.clt_cfgs = NULL;
|
||||
}
|
||||
#endif
|
||||
conn->bhc_gatt_svr.num_clt_cfgs = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ble_gatts_free_mem(void)
|
||||
@@ -1902,6 +1910,7 @@ ble_gatts_free_mem(void)
|
||||
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
|
||||
struct ble_gatts_svc_entry *entry;
|
||||
struct ble_gatts_clt_cfg *clt_cfg;
|
||||
#endif
|
||||
|
||||
/* Free per-connection CCCD nodes before freeing pool backing memory.
|
||||
* Per-connection nodes are copies allocated from the same pool as the
|
||||
@@ -1916,6 +1925,7 @@ ble_gatts_free_mem(void)
|
||||
ble_hs_conn_foreach(ble_gatts_free_conn_clt_cfgs, NULL);
|
||||
ble_hs_unlock_nested();
|
||||
|
||||
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
|
||||
/* free client configs memory */
|
||||
if (STAILQ_FIRST(&ble_gatts_clt_cfgs) != NULL) {
|
||||
clt_cfg = NULL;
|
||||
@@ -2425,7 +2435,15 @@ ble_gatts_rx_indicate_ack(uint16_t conn_handle, uint16_t chr_val_handle)
|
||||
int rc;
|
||||
#if MYNEWT_VAL(BLE_GATT_CACHING)
|
||||
uint16_t svc_change_handle;
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
if (ble_gatts_static_vars == NULL) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_GATT_CACHING)
|
||||
svc_change_handle = ble_svc_gatt_changed_handle();
|
||||
#endif
|
||||
|
||||
@@ -2528,6 +2546,12 @@ ble_gatts_chr_updated(uint16_t chr_val_handle)
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
if (ble_gatts_static_vars == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determine if notifications or indications are allowed for this
|
||||
* characteristic. If not, return immediately.
|
||||
*/
|
||||
@@ -2846,6 +2870,12 @@ void
|
||||
ble_gatts_tx_notifications(void)
|
||||
{
|
||||
uint16_t chr_val_handle;
|
||||
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
if (ble_gatts_static_vars == NULL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
|
||||
struct ble_gatts_clt_cfg *clt_cfg;
|
||||
STAILQ_FOREACH(clt_cfg, &ble_gatts_clt_cfgs, next) {
|
||||
@@ -2930,9 +2960,14 @@ ble_gatts_bonding_established(uint16_t conn_handle)
|
||||
oldest bond */
|
||||
#if (MYNEWT_VAL(BLE_STORE_MAX_BONDS) > 0)
|
||||
ble_hs_conn_addrs(conn, &addrs);
|
||||
new_idx = (last_conn_aware_state_index + 1) %
|
||||
MYNEWT_VAL(BLE_STORE_MAX_BONDS);
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
/* last_conn_aware_state_index lives in the context released by
|
||||
* ble_gatts_stop(); there is no aware state cache left to update.
|
||||
*/
|
||||
if (ble_gatts_static_vars == NULL) {
|
||||
ble_hs_unlock();
|
||||
return;
|
||||
}
|
||||
if (ble_gatts_conn_aware_states == NULL) {
|
||||
ble_gatts_conn_aware_states = nimble_platform_mem_calloc(1, sizeof(struct ble_gatts_aware_state) * MYNEWT_VAL(BLE_STORE_MAX_BONDS));
|
||||
if (ble_gatts_conn_aware_states == NULL) {
|
||||
@@ -2942,6 +2977,8 @@ ble_gatts_bonding_established(uint16_t conn_handle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
new_idx = (last_conn_aware_state_index + 1) %
|
||||
MYNEWT_VAL(BLE_STORE_MAX_BONDS);
|
||||
memset(&ble_gatts_conn_aware_states[new_idx], 0,
|
||||
sizeof(struct ble_gatts_aware_state));
|
||||
memcpy(ble_gatts_conn_aware_states[new_idx].peer_id_addr,
|
||||
@@ -3191,6 +3228,17 @@ ble_gatts_find_svc_entry(const ble_uuid_t *uuid)
|
||||
struct ble_gatts_svc_entry *entry;
|
||||
int i;
|
||||
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
/* The service table lives inside the dynamically allocated context, which
|
||||
* is released by ble_gatts_stop(). Lookups can still arrive from the
|
||||
* application (e.g. from a disconnect callback) after that point.
|
||||
*/
|
||||
if (ble_gatts_static_vars == NULL) {
|
||||
BLE_HS_LOG(ERROR, "gatts svc lookup after stop: ctx=NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ble_gatts_num_svc_entries; i++) {
|
||||
entry = ble_gatts_svc_entries + i;
|
||||
if (ble_uuid_cmp(uuid, entry->svc->uuid) == 0) {
|
||||
@@ -3835,6 +3883,11 @@ void ble_gatts_free_svcs(void)
|
||||
int
|
||||
ble_gatts_svc_set_visibility(uint16_t handle, int visible)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_STATIC_TO_DYNAMIC)
|
||||
if (ble_gatts_static_vars == NULL) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
#endif
|
||||
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
|
||||
struct ble_gatts_svc_entry *entry;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user