mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-05 21:04:49 +00:00
fix(nimble): Resolve host lock assert issue
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user