mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-14 22:17:54 +00:00
fix(nimble): Fix adding device to resolving list when defer connection
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "ble_hs_priv.h"
|
||||
#include "ble_gap_priv.h"
|
||||
#include "ble_hs_resolv_priv.h"
|
||||
#include "ble_sm_priv.h"
|
||||
#if MYNEWT_VAL(BLE_DEFER_CONN_EVENTS)
|
||||
#include "ble_hs_pvcy_priv.h"
|
||||
#include "ble_att_priv.h"
|
||||
@@ -1263,6 +1264,7 @@ static void ble_gap_notify_conn_event(uint16_t conn_handle,
|
||||
static enum ble_gap_defer_result
|
||||
ble_gap_defer_event(uint16_t conn_handle, const struct ble_gap_event *event,
|
||||
const struct ble_gap_defer_meta *meta);
|
||||
static bool ble_gap_connect_delivered(uint16_t conn_handle);
|
||||
static void ble_gap_mark_connect_delivered(uint16_t conn_handle);
|
||||
|
||||
static bool
|
||||
@@ -1382,6 +1384,9 @@ ble_gap_notify_conn_event(uint16_t conn_handle, struct ble_gap_event *event)
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_notify_conn_event: defer failed; type=%d conn=%u\n",
|
||||
event->type, conn_handle);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
return;
|
||||
}
|
||||
ble_gap_event_listener_call(event);
|
||||
ble_gap_call_conn_event_cb(event, conn_handle);
|
||||
break;
|
||||
@@ -1562,6 +1567,20 @@ ble_gap_mark_connect_delivered(uint16_t conn_handle)
|
||||
ble_hs_unlock();
|
||||
}
|
||||
|
||||
static bool
|
||||
ble_gap_connect_delivered(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_hs_conn *conn;
|
||||
bool delivered;
|
||||
|
||||
ble_hs_lock();
|
||||
conn = ble_hs_conn_find(conn_handle);
|
||||
delivered = conn != NULL && conn->bhc_connect_delivered;
|
||||
ble_hs_unlock();
|
||||
|
||||
return delivered;
|
||||
}
|
||||
|
||||
void
|
||||
ble_gap_conn_deferred_init(struct ble_hs_conn *conn)
|
||||
{
|
||||
@@ -10067,9 +10086,19 @@ ble_gap_rx_param_req(const struct ble_hci_ev_le_subev_rem_conn_param_req *ev)
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_rx_param_req: defer failed; conn=%u\n",
|
||||
conn_handle);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
rc = ble_gap_tx_param_neg_reply(conn_handle, BLE_ERR_CONN_PARMS);
|
||||
if (rc != 0) {
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_rx_param_req: negative reply failed; "
|
||||
"conn=%u rc=%d\n",
|
||||
conn_handle, rc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* NOT_NEEDED or FAILED: fall through to the normal path. */
|
||||
/* NOT_NEEDED, or FAILED after CONNECT was delivered: normal path. */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -10836,6 +10865,16 @@ ble_gap_passkey_event(uint16_t conn_handle,
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_passkey_event: defer failed; conn=%u\n",
|
||||
conn_handle);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
struct ble_sm_result res;
|
||||
|
||||
memset(&res, 0, sizeof res);
|
||||
res.sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res.app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED);
|
||||
res.enc_cb = 1;
|
||||
ble_sm_process_result(conn_handle, &res, true);
|
||||
return;
|
||||
}
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_conn_event_cb(&event, conn_handle);
|
||||
break;
|
||||
@@ -10876,6 +10915,11 @@ ble_gap_enc_event(uint16_t conn_handle, int status,
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_enc_event: defer failed; conn=%u status=%d\n",
|
||||
conn_handle, status);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
ble_gap_enc_side_effects(conn_handle, status,
|
||||
security_restored, bonded);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -11002,6 +11046,9 @@ ble_gap_pairing_complete_event(uint16_t conn_handle, int status)
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_pairing_complete_event: defer failed; conn=%u\n",
|
||||
conn_handle);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
return;
|
||||
}
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_conn_event_cb(&event, conn_handle);
|
||||
break;
|
||||
@@ -11039,6 +11086,9 @@ ble_gap_assoc_event(uint16_t conn_handle, int status, uint8_t cache_state)
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_assoc_event: defer failed; conn=%u\n",
|
||||
conn_handle);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
return;
|
||||
}
|
||||
ble_gap_call_conn_event_cb(&event, conn_handle);
|
||||
break;
|
||||
}
|
||||
@@ -11115,6 +11165,10 @@ ble_gap_notify_rx_event(uint16_t conn_handle, uint16_t attr_handle,
|
||||
BLE_HS_LOG(ERROR,
|
||||
"ble_gap_notify_rx_event: defer failed; conn=%u\n",
|
||||
conn_handle);
|
||||
if (!ble_gap_connect_delivered(conn_handle)) {
|
||||
os_mbuf_free_chain(event.notify_rx.om);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -283,6 +283,9 @@ ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec)
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
|
||||
int rc;
|
||||
int valid_peer_addr;
|
||||
|
||||
valid_peer_addr = ble_addr_cmp(&value_sec->peer_addr, BLE_ADDR_ANY);
|
||||
#if MYNEWT_VAL(BLE_DEFER_CONN_EVENTS) && MYNEWT_VAL(BLE_HS_PVCY)
|
||||
struct ble_store_key_sec key_sec;
|
||||
struct ble_store_value_sec old_sec;
|
||||
@@ -303,19 +306,21 @@ ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ble_addr_cmp(&value_sec->peer_addr, BLE_ADDR_ANY) &&
|
||||
if (valid_peer_addr &&
|
||||
value_sec->irk_present) {
|
||||
#if MYNEWT_VAL(BLE_HS_PVCY)
|
||||
#if MYNEWT_VAL(BLE_DEFER_CONN_EVENTS)
|
||||
/* Do not update the controller resolving list while this peer is still
|
||||
* connected. The bond is already persisted for the current link, and
|
||||
* some controllers reject LE Add Device To Resolving List in this
|
||||
* state even when GAP is preempted.
|
||||
/* Defer the controller resolving-list update only until the CONNECT
|
||||
* event has been delivered. Once the application knows about the
|
||||
* connection, resolving-list setup must proceed so scanning can use
|
||||
* the newly exchanged IRK while the connection remains active.
|
||||
*/
|
||||
#if !MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
|
||||
ble_hs_lock();
|
||||
struct ble_hs_conn *conn = ble_hs_conn_find_by_addr(&value_sec->peer_addr);
|
||||
if (conn != NULL) {
|
||||
if (conn != NULL && !conn->bhc_connect_delivered) {
|
||||
BLE_HS_LOG(INFO, "PVCY: deferring controller resolving-list add "
|
||||
"until CONNECT is delivered\n");
|
||||
conn->bhc_deferred_pvcy_add = 1;
|
||||
conn->bhc_deferred_pvcy_replace = replace_entry;
|
||||
conn->bhc_deferred_pvcy_addr = value_sec->peer_addr;
|
||||
|
||||
Reference in New Issue
Block a user