fix(nimble): Resolve host lock assert issue

This commit is contained in:
Rahul Tank
2026-04-01 11:09:45 +05:30
parent 50075787b2
commit 1022de21ca
11 changed files with 101 additions and 33 deletions
+2
View File
@@ -789,10 +789,12 @@ ble_att_get_default_bearer_cid(uint16_t conn_handle) {
struct ble_hs_conn * conn;
uint16_t default_cid = 0;
ble_hs_lock_nested();
conn = ble_hs_conn_find(conn_handle);
if (conn != NULL) {
default_cid = conn->default_cid;
}
ble_hs_unlock_nested();
return default_cid;
#endif
+12 -2
View File
@@ -550,8 +550,10 @@ uint16_t
ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op)
{
uint16_t default_cid;
uint16_t cid;
struct ble_eatt * eatt;
ble_hs_lock_nested();
default_cid = ble_att_get_default_bearer_cid(conn_handle);
if (default_cid) {
eatt = ble_eatt_find(conn_handle, default_cid);
@@ -559,11 +561,16 @@ ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op)
eatt = ble_eatt_find_not_busy(conn_handle);
}
if (!eatt) {
return BLE_L2CAP_CID_ATT;
cid = BLE_L2CAP_CID_ATT;
goto done;
}
eatt->client_op = op;
return eatt->chan->scid;
cid = eatt->chan->scid;
done:
ble_hs_unlock_nested();
return cid;
}
@@ -572,8 +579,10 @@ ble_eatt_release_chan(uint16_t conn_handle, uint8_t op)
{
struct ble_eatt *eatt;
ble_hs_lock_nested();
eatt = ble_eatt_find_by_conn_handle_and_busy_op(conn_handle, op);
if (!eatt) {
ble_hs_unlock_nested();
BLE_EATT_LOG_DEBUG("ble_eatt_release_chan:"
"EATT not found for conn_handle 0x%04x, operation 0x%02x\n",
conn_handle, op);
@@ -581,6 +590,7 @@ ble_eatt_release_chan(uint16_t conn_handle, uint8_t op)
}
eatt->client_op = 0;
ble_hs_unlock_nested();
}
int
+16 -8
View File
@@ -437,7 +437,9 @@ static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry);
static struct ble_gap_update_entry *
ble_gap_update_entry_find(uint16_t conn_handle,
struct ble_gap_update_entry **out_prev);
#endif
#if NIMBLE_BLE_CONNECT
static void
ble_gap_update_l2cap_cb(uint16_t conn_handle, int status, void *arg);
#endif
@@ -971,7 +973,7 @@ ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
int ble_gap_get_local_used_addr(ble_addr_t *addr)
{
uint8_t own_addr_type = 0;
const uint8_t *out_id_addr;
uint8_t out_id_addr[BLE_DEV_ADDR_LEN];
int rc;
if (addr == NULL) {
@@ -980,7 +982,7 @@ int ble_gap_get_local_used_addr(ble_addr_t *addr)
own_addr_type = ble_gap_slave[0].our_addr_type;
rc = ble_hs_id_addr(own_addr_type, &out_id_addr,NULL);
rc = ble_hs_id_copy_addr(own_addr_type, out_id_addr, NULL);
if (rc == 0) {
addr->type = own_addr_type;
@@ -2466,8 +2468,10 @@ ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_
/* remove any sync_lost event from queue */
ble_npl_eventq_remove(ble_hs_evq_get(), &psync->lost_ev);
/* Free the memory occupied by psync as it is no longer needed */
/* ble_hs_periodic_sync_free() requires host lock. */
ble_hs_lock();
ble_hs_periodic_sync_free(psync);
ble_hs_unlock();
ble_gap_event_listener_call(&event);
if (cb) {
@@ -5383,8 +5387,10 @@ ble_gap_npl_sync_lost(struct ble_npl_event *ev)
event.periodic_sync_lost.sync_handle = psync->sync_handle;
event.periodic_sync_lost.reason = BLE_HS_EDONE;
/* Free the memory occupied by psync as it is no longer needed */
/* ble_hs_periodic_sync_free() requires host lock. */
ble_hs_lock();
ble_hs_periodic_sync_free(psync);
ble_hs_unlock();
ble_gap_event_listener_call(&event);
if (cb) {
@@ -8692,7 +8698,8 @@ ble_gap_reset_irk(void)
ble_addr_t oldest_peer_id_addr[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
struct ble_store_value_local_irk value_local_irk;
struct ble_store_key_local_irk key_local_irk;
uint8_t *local_id = NULL;
uint8_t local_id[BLE_DEV_ADDR_LEN];
int have_local_id;
int rc, num_peers;
uint8_t tmp_addr[6];
@@ -8706,10 +8713,11 @@ ble_gap_reset_irk(void)
memset(&key_local_irk, 0, sizeof key_local_irk);
memset(&value_local_irk, 0x0, sizeof value_local_irk);
ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL);
rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, local_id, NULL);
have_local_id = (rc == 0);
if (local_id) {
memcpy (key_local_irk.addr.val , local_id, BLE_DEV_ADDR_LEN);
if (have_local_id) {
memcpy(key_local_irk.addr.val, local_id, BLE_DEV_ADDR_LEN);
}
key_local_irk.addr.type = BLE_ADDR_PUBLIC;
+14 -8
View File
@@ -749,9 +749,15 @@ ble_hs_notifications_sched(void)
void
ble_hs_sched_reset(int reason)
{
BLE_HS_DBG_ASSERT(ble_hs_reset_reason == 0);
ble_hs_lock_nested();
if (ble_hs_reset_reason != 0) {
ble_hs_unlock_nested();
return;
}
ble_hs_reset_reason = reason;
ble_hs_unlock_nested();
ble_npl_eventq_put(ble_hs_evq, &ble_hs_ev_reset);
}
@@ -933,6 +939,13 @@ ble_hs_init(void)
ble_hs_reset_reason = 0;
ble_hs_enabled_state = BLE_HS_ENABLED_STATE_OFF;
rc = ble_npl_mutex_init(&ble_hs_mutex);
SYSINIT_PANIC_ASSERT(rc == 0);
#if MYNEWT_VAL(BLE_HS_DEBUG)
ble_hs_dbg_mutex_locked = 0;
#endif
#if NIMBLE_BLE_CONNECT
#if MYNEWT_VAL(BLE_GATTS)
ble_npl_event_init(&ble_hs_ev_tx_notifications, ble_hs_event_tx_notify,
@@ -1002,13 +1015,6 @@ ble_hs_init(void)
STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_hs_stats), "ble_hs");
SYSINIT_PANIC_ASSERT(rc == 0);
rc = ble_npl_mutex_init(&ble_hs_mutex);
SYSINIT_PANIC_ASSERT(rc == 0);
#if MYNEWT_VAL(BLE_HS_DEBUG)
ble_hs_dbg_mutex_locked = 0;
#endif
#ifdef MYNEWT
ble_hs_evq_set((struct ble_npl_eventq *)os_eventq_dflt_get());
#else
+10 -4
View File
@@ -78,7 +78,7 @@ ble_hs_conn_can_alloc(void)
int result;
ble_hs_lock();
ble_hs_lock_nested();
#if MYNEWT_VAL(BLE_GATTS)
result = ble_hs_conn_pool.mp_num_free >= 1 &&
@@ -89,7 +89,7 @@ ble_hs_conn_can_alloc(void)
ble_l2cap_chan_pool.mp_num_free >= BLE_HS_CONN_MIN_CHANS;
#endif
ble_hs_unlock();
ble_hs_unlock_nested();
return result;
}
@@ -504,13 +504,17 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn,
addrs->our_id_addr.type == BLE_ADDR_RANDOM) {
our_id_addr_val = conn->bhc_our_rnd_addr;
} else {
ble_hs_lock_nested();
rc = ble_hs_id_addr(addrs->our_id_addr.type, &our_id_addr_val, NULL);
ble_hs_unlock_nested();
if (rc != 0) {
return;
}
}
#else
ble_hs_lock_nested();
rc = ble_hs_id_addr(addrs->our_id_addr.type, &our_id_addr_val, NULL);
ble_hs_unlock_nested();
if (rc != 0) {
return;
}
@@ -535,14 +539,15 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn,
memcpy(bhc_peer_addr.val, conn->bhc_peer_addr.val, BLE_DEV_ADDR_LEN);
struct ble_hs_resolv_entry *rl = NULL;
ble_hs_lock_nested();
rl = ble_hs_resolv_list_find(bhc_peer_addr.val);
if (rl != NULL) {
memcpy(addrs->peer_id_addr.val, rl->rl_identity_addr, BLE_DEV_ADDR_LEN);
addrs->peer_id_addr.type = rl->rl_addr_type;
if (ble_host_rpa_enabled()) {
uint8_t *local_id = NULL;
rc = ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL);
const uint8_t *local_id = NULL;
rc = ble_hs_id_addr(BLE_ADDR_PUBLIC, &local_id, NULL);
/* RL is present: populate our id addr with public ID */
if (rc == 0 && local_id != NULL) {
@@ -554,6 +559,7 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn,
}
}
}
ble_hs_unlock_nested();
#endif
switch (conn->bhc_peer_addr.type) {
case BLE_ADDR_PUBLIC:
+6
View File
@@ -732,8 +732,10 @@ ble_hs_hci_evt_le_enh_conn_complete(uint8_t subevent, const void *data,
}
struct ble_hs_resolv_entry *rl = NULL;
ble_hs_lock();
ble_rpa_replace_peer_params_with_rl(evt.peer_addr,
&evt.peer_addr_type, &rl);
ble_hs_unlock();
#endif
evt.conn_itvl = le16toh(ev->conn_itvl);
evt.conn_latency = le16toh(ev->conn_latency);
@@ -804,8 +806,10 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, const void *data,
}
struct ble_hs_resolv_entry *rl = NULL;
ble_hs_lock();
ble_rpa_replace_peer_params_with_rl(evt.peer_addr,
&evt.peer_addr_type, &rl);
ble_hs_unlock();
#endif
evt.conn_itvl = le16toh(ev->conn_itvl);
evt.conn_latency = le16toh(ev->conn_latency);
@@ -930,6 +934,7 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len)
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
struct ble_hs_resolv_entry *rl = NULL;
ble_hs_lock();
rl = ble_hs_resolv_rpa_addr(desc.addr.val, desc.addr.type);
if (rl != NULL) {
@@ -939,6 +944,7 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len)
memcpy(desc.addr.val, rl->rl_identity_addr, BLE_DEV_ADDR_LEN);
desc.addr.type = rl->rl_addr_type;
}
ble_hs_unlock();
#endif
desc.length_data = rpt->data_len;
+2 -2
View File
@@ -330,14 +330,14 @@ ble_hs_id_copy_addr(uint8_t id_addr_type, uint8_t *out_id_addr,
const uint8_t *addr;
int rc;
ble_hs_lock();
ble_hs_lock_nested();
rc = ble_hs_id_addr(id_addr_type, &addr, out_is_nrpa);
if (rc == 0 && out_id_addr != NULL) {
memcpy(out_id_addr, addr, 6);
}
ble_hs_unlock();
ble_hs_unlock_nested();
return rc;
}
+11 -5
View File
@@ -192,7 +192,9 @@ ble_hs_pvcy_add_entry_hci(const uint8_t *addr, uint8_t addr_type,
memcpy(cmd.peer_irk, irk, 16);
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
ble_hs_lock_nested();
rc = ble_hs_resolv_list_add((uint8_t *) &cmd);
ble_hs_unlock_nested();
if (rc != 0) {
return rc;
}
@@ -299,18 +301,20 @@ void ble_hs_pvcy_set_default_irk(void)
struct ble_store_value_local_irk value_local_irk;
struct ble_store_key_local_irk key_local_irk;
uint8_t *local_id = NULL;
uint8_t local_id[BLE_DEV_ADDR_LEN];
bool have_local_id;
int rc;
memset(&key_local_irk, 0, sizeof key_local_irk);
memset(&value_local_irk, 0x0, sizeof value_local_irk);
rc = ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL);
rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, local_id, NULL);
have_local_id = (rc == 0);
/* Create key / value */
/* Some controllers give all 0s as address. Handle such case */
if (local_id) {
memcpy (key_local_irk.addr.val , local_id, BLE_DEV_ADDR_LEN);
if (have_local_id) {
memcpy(key_local_irk.addr.val, local_id, BLE_DEV_ADDR_LEN);
}
key_local_irk.addr.type = BLE_ADDR_PUBLIC;
@@ -350,7 +354,7 @@ void ble_hs_pvcy_set_default_irk(void)
memcpy(&value_local_irk.irk, ble_hs_pvcy_default_irk, 16);
if (local_id) {
if (have_local_id) {
memcpy(value_local_irk.addr.val, local_id, BLE_DEV_ADDR_LEN);
}
@@ -397,6 +401,7 @@ ble_hs_pvcy_set_our_irk(const uint8_t *irk)
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
if (irk != NULL) {
ble_hs_lock_nested();
bool rpa_state = false;
if ((rpa_state = ble_host_rpa_enabled()) == true) {
@@ -408,6 +413,7 @@ ble_hs_pvcy_set_our_irk(const uint8_t *irk)
if (rpa_state) {
ble_hs_resolv_enable(1);
}
ble_hs_unlock_nested();
}
#else
rc = ble_hs_pvcy_set_resolve_enabled(0);
+1 -1
View File
@@ -131,7 +131,7 @@ ble_rpa_peer_dev_rec_clear_all(void)
* NULL otherwise
*/
struct ble_hs_dev_records *
ble_rpa_find_peer_dev_rec(uint8_t *addr)
ble_rpa_find_peer_dev_rec(const uint8_t *addr)
{
struct ble_hs_dev_records *p_dev_rec = &peer_dev_rec[0];
int i;
+1 -1
View File
@@ -98,7 +98,7 @@ struct ble_hs_dev_records *ble_rpa_get_peer_dev_records(void);
int ble_rpa_get_num_peer_dev_records(void);
void ble_rpa_set_num_peer_dev_records(int);
int ble_rpa_remove_peer_dev_rec(struct ble_hs_dev_records *);
struct ble_hs_dev_records *ble_rpa_find_peer_dev_rec(uint8_t *);
struct ble_hs_dev_records *ble_rpa_find_peer_dev_rec(const uint8_t *);
/* Set the resolvable private address timeout */
int ble_hs_resolv_set_rpa_tmo(uint16_t);
+26 -2
View File
@@ -28,6 +28,18 @@ struct ble_store_util_peer_set {
int status;
};
#if NIMBLE_BLE_CONNECT && MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
static int
ble_store_util_lock_owned_by_cur_task(void)
{
#if MYNEWT_VAL(BLE_HS_DEBUG)
return ble_hs_locked_by_cur_task();
#else
return 0;
#endif
}
#endif
#if NIMBLE_BLE_CONNECT
static int
ble_store_util_iter_unique_peer(int obj_type,
@@ -197,8 +209,14 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr)
}
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
struct ble_hs_dev_records *peer_rec =
ble_rpa_find_peer_dev_rec(key.sec.peer_addr.val);
struct ble_hs_dev_records *peer_rec;
int needs_unlock;
needs_unlock = !ble_store_util_lock_owned_by_cur_task();
if (needs_unlock) {
ble_hs_lock();
}
peer_rec = ble_rpa_find_peer_dev_rec(peer_id_addr->val);
if (peer_rec != NULL) {
rc = ble_hs_resolv_list_rmv(peer_rec->peer_sec.peer_addr.type,
@@ -210,9 +228,15 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr)
rc = ble_rpa_remove_peer_dev_rec(peer_rec);
if (rc != 0) {
if (needs_unlock) {
ble_hs_unlock();
}
return rc;
}
}
if (needs_unlock) {
ble_hs_unlock();
}
#endif
return 0;