diff --git a/applied_patches/official-merged/nimble#730.patch b/applied_patches/official-merged/nimble#730.patch new file mode 100644 index 00000000..9afd5049 --- /dev/null +++ b/applied_patches/official-merged/nimble#730.patch @@ -0,0 +1,25 @@ +From 3cbef1a615a4d739c5bface245f827be2026a7b3 Mon Sep 17 00:00:00 2001 +From: Andrzej Kaczmarek +Date: Mon, 13 Jan 2020 22:59:17 +0100 +Subject: [PATCH] nimble/host: Fix setting connection flags after pairing + +--- + nimble/host/src/ble_sm.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/nimble/host/src/ble_sm.c b/src/nimble/host/src/ble_sm.c +index e2315fb0f..cfd80fcbd 100644 +--- a/src/nimble/host/src/ble_sm.c ++++ b/src/nimble/host/src/ble_sm.c +@@ -2015,7 +2015,10 @@ ble_sm_key_exch_success(struct ble_sm_proc *proc, struct ble_sm_result *res) + /* The procedure is now complete. Update connection bonded state and + * terminate procedure. + */ +- ble_sm_update_sec_state(proc->conn_handle, 1, 0, 1, proc->key_size); ++ ble_sm_update_sec_state(proc->conn_handle, 1, ++ !!(proc->flags & BLE_SM_PROC_F_AUTHENTICATED), ++ !!(proc->flags & BLE_SM_PROC_F_BONDING), ++ proc->key_size); + proc->state = BLE_SM_PROC_STATE_NONE; + + res->app_status = 0; diff --git a/applied_patches/official-merged/nimble#790.patch b/applied_patches/official-merged/nimble#790.patch new file mode 100644 index 00000000..7919ff6a --- /dev/null +++ b/applied_patches/official-merged/nimble#790.patch @@ -0,0 +1,130 @@ +From 9cb441213d9c56df44d97fb4eb121f0bb5146ee8 Mon Sep 17 00:00:00 2001 +From: Prasad Alatkar +Date: Fri, 3 Apr 2020 18:42:05 +0530 +Subject: [PATCH 1/2] nimble/host: Fix return code in + `ble_gap_unpair_oldest_peer` when no bonded peer exist + +--- + nimble/host/src/ble_gap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/nimble/host/src/ble_gap.c b/src/nimble/host/src/ble_gap.c +index 4729dd02a..b44012d33 100644 +--- a/src/nimble/host/src/ble_gap.c ++++ b/src/nimble/host/src/ble_gap.c +@@ -5594,7 +5594,7 @@ ble_gap_unpair_oldest_peer(void) + } + + if (num_peers == 0) { +- return 0; ++ return BLE_HS_ENOENT; + } + + rc = ble_gap_unpair(&oldest_peer_id_addr); + +From bb9303ab2fa33dafdd152be5b31bc07eedf38c24 Mon Sep 17 00:00:00 2001 +From: Prasad Alatkar +Date: Wed, 1 Apr 2020 00:08:29 +0530 +Subject: [PATCH 2/2] nimble/store: Fix store behavior when CCCDs exceed + maximum limit + +- Add supporting API to skip input peer while unpairing oldest peer +--- + nimble/host/include/host/ble_gap.h | 14 ++++++++++++++ + nimble/host/src/ble_gap.c | 30 ++++++++++++++++++++++++++++++ + nimble/host/src/ble_store_util.c | 16 +++++++++------- + 3 files changed, 53 insertions(+), 7 deletions(-) + +diff --git a/src/host/ble_gap.h b/src/host/ble_gap.h +index 20e7dab77..b58f350fb 100644 +--- a/src/host/ble_gap.h ++++ b/src/host/ble_gap.h +@@ -1896,6 +1896,20 @@ int ble_gap_unpair(const ble_addr_t *peer_addr); + */ + int ble_gap_unpair_oldest_peer(void); + ++/** ++ * Similar to `ble_gap_unpair_oldest_peer()`, except it makes sure that the ++ * peer received in input parameters is not deleted. ++ * ++ * @param peer_addr Address of the peer (not to be deleted) ++ * ++ * @return 0 on success; ++ * A BLE host HCI return code if the controller ++ * rejected the request; ++ * A BLE host core return code on unexpected ++ * error. ++ */ ++int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr); ++ + #define BLE_GAP_PRIVATE_MODE_NETWORK 0 + #define BLE_GAP_PRIVATE_MODE_DEVICE 1 + +diff --git a/src/nimble/host/src/ble_gap.c b/src/nimble/host/src/ble_gap.c +index b44012d33..53c6bf308 100644 +--- a/src/nimble/host/src/ble_gap.c ++++ b/src/nimble/host/src/ble_gap.c +@@ -5605,6 +5605,36 @@ ble_gap_unpair_oldest_peer(void) + return 0; + } + ++int ++ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr) ++{ ++ ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; ++ int num_peers; ++ int rc, i; ++ ++ rc = ble_store_util_bonded_peers( ++ &peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); ++ if (rc != 0) { ++ return rc; ++ } ++ ++ if (num_peers == 0) { ++ return BLE_HS_ENOENT; ++ } ++ ++ for (i = 0; i < num_peers; i++) { ++ if (ble_addr_cmp(peer_addr, &peer_id_addrs[i]) != 0) { ++ break; ++ } ++ } ++ ++ if (i >= num_peers) { ++ return BLE_HS_ENOMEM; ++ } ++ ++ return ble_gap_unpair(&peer_id_addrs[i]); ++} ++ + void + ble_gap_passkey_event(uint16_t conn_handle, + struct ble_gap_passkey_params *passkey_params) +diff --git a/src/nimble/host/src/ble_store_util.c b/src/nimble/host/src/ble_store_util.c +index 444cc55d7..7de482721 100644 +--- a/src/nimble/host/src/ble_store_util.c ++++ b/src/nimble/host/src/ble_store_util.c +@@ -233,13 +233,15 @@ ble_store_util_status_rr(struct ble_store_status_event *event, void *arg) + switch (event->event_code) { + case BLE_STORE_EVENT_OVERFLOW: + switch (event->overflow.obj_type) { +- case BLE_STORE_OBJ_TYPE_OUR_SEC: +- case BLE_STORE_OBJ_TYPE_PEER_SEC: +- case BLE_STORE_OBJ_TYPE_CCCD: +- return ble_gap_unpair_oldest_peer(); +- +- default: +- return BLE_HS_EUNKNOWN; ++ case BLE_STORE_OBJ_TYPE_OUR_SEC: ++ case BLE_STORE_OBJ_TYPE_PEER_SEC: ++ return ble_gap_unpair_oldest_peer(); ++ case BLE_STORE_OBJ_TYPE_CCCD: ++ /* Try unpairing oldest peer except current peer */ ++ return ble_gap_unpair_oldest_except(&event->overflow.value->cccd.peer_addr); ++ ++ default: ++ return BLE_HS_EUNKNOWN; + } + + case BLE_STORE_EVENT_FULL: diff --git a/applied_patches/official-merged/nimble#802.patch b/applied_patches/official-merged/nimble#802.patch new file mode 100644 index 00000000..f73c732c --- /dev/null +++ b/applied_patches/official-merged/nimble#802.patch @@ -0,0 +1,153 @@ +From 87b23db462ac4ad6932b0c2d621bcb99cf4f1dfd Mon Sep 17 00:00:00 2001 +From: h2zero +Date: Sat, 18 Apr 2020 20:42:41 -0600 +Subject: [PATCH] nimble/host: Add return parameter to the + ble_hs_misc_conn_chan_find_reqd() + +ble_hs_misc_conn_chan_find_reqd() did not return an error code if +the connection and or the channel were not found, i.e in a disconnected state. +When debug is not enabled and `ble_hs_misc_conn_chan_find_reqd()` is called and +the device has disconnected from the peer various functions may attempt to access +memory that is not valid causing an null pointer exception. +--- + nimble/host/src/ble_att_cmd.c | 7 +++---- + nimble/host/src/ble_hs_misc.c | 8 ++++++-- + nimble/host/src/ble_hs_priv.h | 6 +++--- + nimble/host/src/ble_l2cap_sig.c | 9 +++++++-- + nimble/host/src/ble_l2cap_sig_cmd.c | 8 +++++--- + nimble/host/src/ble_sm_cmd.c | 11 ++++++++--- + 6 files changed, 32 insertions(+), 17 deletions(-) + +diff --git a/src/nimble/host/src/ble_att_cmd.c b/src/nimble/host/src/ble_att_cmd.c +index a123c857c..81b070f9c 100644 +--- a/src/nimble/host/src/ble_att_cmd.c ++++ b/src/nimble/host/src/ble_att_cmd.c +@@ -66,11 +66,10 @@ ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom) + + ble_hs_lock(); + +- ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, +- &chan); +- if (chan == NULL) { ++ rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, ++ &chan); ++ if (rc != 0) { + os_mbuf_free_chain(txom); +- rc = BLE_HS_ENOTCONN; + } else { + ble_att_truncate_to_mtu(chan, txom); + rc = ble_l2cap_tx(conn, chan, txom); +diff --git a/src/nimble/host/src/ble_hs_misc.c b/src/nimble/host/src/ble_hs_misc.c +index 6c6da4675..dfb46b741 100644 +--- a/src/nimble/host/src/ble_hs_misc.c ++++ b/src/nimble/host/src/ble_hs_misc.c +@@ -56,7 +56,7 @@ ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, + return rc; + } + +-void ++int + ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan) +@@ -66,7 +66,9 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, + int rc; + + rc = ble_hs_misc_conn_chan_find(conn_handle, cid, &conn, &chan); +- BLE_HS_DBG_ASSERT_EVAL(rc == 0); ++ if (rc != 0) { ++ return rc; ++ } + + if (out_conn != NULL) { + *out_conn = conn; +@@ -74,6 +76,8 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, + if (out_chan != NULL) { + *out_chan = chan; + } ++ ++ return 0; + } + + uint8_t +diff --git a/src/nimble/host/src/ble_hs_priv.h b/src/nimble/host/src/ble_hs_priv.h +index 2cad6ef1d..538d07a97 100644 +--- a/src/nimble/host/src/ble_hs_priv.h ++++ b/src/nimble/host/src/ble_hs_priv.h +@@ -114,9 +114,9 @@ int ble_hs_hci_evt_acl_process(struct os_mbuf *om); + int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan); +-void ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, +- struct ble_hs_conn **out_conn, +- struct ble_l2cap_chan **out_chan); ++int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, ++ struct ble_hs_conn **out_conn, ++ struct ble_l2cap_chan **out_chan); + uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type); + int ble_hs_misc_restore_irks(void); + +diff --git a/src/nimble/host/src/ble_l2cap_sig.c b/src/nimble/host/src/ble_l2cap_sig.c +index bb4d8a5ac..58f96b0f3 100644 +--- a/src/nimble/host/src/ble_l2cap_sig.c ++++ b/src/nimble/host/src/ble_l2cap_sig.c +@@ -508,8 +508,13 @@ ble_l2cap_sig_update(uint16_t conn_handle, + STATS_INC(ble_l2cap_stats, update_init); + + ble_hs_lock(); +- ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, +- &conn, &chan); ++ rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, ++ &conn, &chan); ++ if (rc != 0) { ++ ble_hs_unlock(); ++ goto done; ++ } ++ + master = conn->bhc_flags & BLE_HS_CONN_F_MASTER; + ble_hs_unlock(); + +diff --git a/src/nimble/host/src/ble_l2cap_sig_cmd.c b/src/nimble/host/src/ble_l2cap_sig_cmd.c +index 366dde625..510420f09 100644 +--- a/src/nimble/host/src/ble_l2cap_sig_cmd.c ++++ b/src/nimble/host/src/ble_l2cap_sig_cmd.c +@@ -28,9 +28,11 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom) + int rc; + + ble_hs_lock(); +- ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, +- &conn, &chan); +- rc = ble_l2cap_tx(conn, chan, txom); ++ rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, ++ &conn, &chan); ++ if (rc == 0) { ++ rc = ble_l2cap_tx(conn, chan, txom); ++ } + ble_hs_unlock(); + + return rc; +diff --git a/src/nimble/host/src/ble_sm_cmd.c b/src/nimble/host/src/ble_sm_cmd.c +index 5eef798d6..01651f1df 100644 +--- a/src/nimble/host/src/ble_sm_cmd.c ++++ b/src/nimble/host/src/ble_sm_cmd.c +@@ -52,12 +52,17 @@ ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom) + { + struct ble_l2cap_chan *chan; + struct ble_hs_conn *conn; ++ int rc; + + BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); + + STATS_INC(ble_l2cap_stats, sm_tx); + +- ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM, +- &conn, &chan); +- return ble_l2cap_tx(conn, chan, txom); ++ rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM, ++ &conn, &chan); ++ if (rc == 0) { ++ rc = ble_l2cap_tx(conn, chan, txom); ++ } ++ ++ return rc; + } diff --git a/applied_patches/official-merged/nimble#804.patch b/applied_patches/official-merged/nimble#804.patch new file mode 100644 index 00000000..9fc9eef0 --- /dev/null +++ b/applied_patches/official-merged/nimble#804.patch @@ -0,0 +1,135 @@ +From b68bf07b4bf15aea1c1e9440abd4d7d72987d1b8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= +Date: Tue, 21 Apr 2020 09:48:02 +0200 +Subject: [PATCH] nimble/gap: Fix storing CCC for bonded devices. + +This PR make sure that ble_gatts_bonding_established is called only when +bonded. + +Note: renamed not used "persist_keys" to "bonded" and make use of it + +Bug can be easly reproduced when +BLE_SM_BONDING: 0 +BLE_HS_DEBUG: 1 + +Program received signal SIGTRAP, Trace/breakpoint trap. +ble_gatts_bonding_established (conn_handle=conn_handle@entry=1) at repos/apache-mynewt-nimble/nimble/host/src/ble_gatts.c:1681 +1681 BLE_HS_DBG_ASSERT(conn->bhc_sec_state.bonded); +(gdb) +--- + nimble/host/src/ble_gap.c | 27 ++++++++++++++++++++------- + nimble/host/src/ble_gap_priv.h | 2 +- + nimble/host/src/ble_sm.c | 5 +++-- + nimble/host/src/ble_sm_priv.h | 8 ++++---- + 4 files changed, 28 insertions(+), 14 deletions(-) + +diff --git a/src/nimble/host/src/ble_gap.c b/src/nimble/host/src/ble_gap.c +index 53c6bf308..4df3b7b93 100644 +--- a/src/nimble/host/src/ble_gap.c ++++ b/src/nimble/host/src/ble_gap.c +@@ -5363,10 +5363,11 @@ ble_gap_passkey_event(uint16_t conn_handle, + } + + void +-ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored) ++ble_gap_enc_event(uint16_t conn_handle, int status, ++ int security_restored, int bonded) + { + #if !NIMBLE_BLE_SM + return; + #endif + + struct ble_gap_event event; +@@ -5379,12 +5379,24 @@ ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored) + ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, conn_handle); + +- if (status == 0) { +- if (security_restored) { +- ble_gatts_bonding_restored(conn_handle); +- } else { +- ble_gatts_bonding_established(conn_handle); +- } ++ if (status != 0) { ++ return; ++ } ++ ++ /* If encryption succeded and encryption has been restored for bonded device, ++ * notify gatt server so it has chance to send notification/indication if needed. ++ */ ++ if (security_restored) { ++ ble_gatts_bonding_restored(conn_handle); ++ return; ++ } ++ ++ /* If this is fresh pairing and bonding has been established, ++ * notify gatt server about that so previous subscriptions (before bonding) ++ * can be stored. ++ */ ++ if (bonded) { ++ ble_gatts_bonding_established(conn_handle); + } + } + +diff --git a/src/nimble/host/src/ble_gap_priv.h b/src/nimble/host/src/ble_gap_priv.h +index c050435f4..499823bc5 100644 +--- a/src/nimble/host/src/ble_gap_priv.h ++++ b/src/nimble/host/src/ble_gap_priv.h +@@ -99,7 +99,7 @@ int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, + struct ble_gap_upd_params *params); + void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); + void ble_gap_enc_event(uint16_t conn_handle, int status, +- int security_restored); ++ int security_restored, int bonded); + void ble_gap_passkey_event(uint16_t conn_handle, + struct ble_gap_passkey_params *passkey_params); + void ble_gap_notify_rx_event(uint16_t conn_handle, uint16_t attr_handle, +diff --git a/src/nimble/host/src/ble_sm.c b/src/nimble/host/src/ble_sm.c +index cfd80fcbd..91afb75c2 100644 +--- a/src/nimble/host/src/ble_sm.c ++++ b/src/nimble/host/src/ble_sm.c +@@ -938,7 +938,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res) + + if (res->enc_cb) { + BLE_HS_DBG_ASSERT(proc == NULL || rm); +- ble_gap_enc_event(conn_handle, res->app_status, res->restore); ++ ble_gap_enc_event(conn_handle, res->app_status, res->restore, res->bonded); + } + + if (res->app_status == 0 && +@@ -1190,6 +1190,7 @@ ble_sm_enc_event_rx(uint16_t conn_handle, uint8_t evt_status, int encrypted) + + ble_hs_unlock(); + ++ res.bonded = bonded; + ble_sm_process_result(conn_handle, &res); + } + +@@ -2425,7 +2426,7 @@ ble_sm_timer(void) + * procedures without reconnect. + */ + while ((proc = STAILQ_FIRST(&exp_list)) != NULL) { +- ble_gap_enc_event(proc->conn_handle, BLE_HS_ETIMEOUT, 0); ++ ble_gap_enc_event(proc->conn_handle, BLE_HS_ETIMEOUT, 0, 0); + + STAILQ_REMOVE_HEAD(&exp_list, next); + ble_sm_proc_free(proc); +diff --git a/src/nimble/host/src/ble_sm_priv.h b/src/nimble/host/src/ble_sm_priv.h +index 6d5601bf6..27e75aa1d 100644 +--- a/src/nimble/host/src/ble_sm_priv.h ++++ b/src/nimble/host/src/ble_sm_priv.h +@@ -279,10 +279,10 @@ struct ble_sm_result { + uint8_t sm_err; + struct ble_gap_passkey_params passkey_params; + void *state_arg; +- unsigned execute:1; +- unsigned enc_cb:1; +- unsigned persist_keys:1; +- unsigned restore:1; ++ unsigned execute : 1; ++ unsigned enc_cb : 1; ++ unsigned bonded : 1; ++ unsigned restore : 1; + }; + + #if MYNEWT_VAL(BLE_HS_DEBUG) diff --git a/applied_patches/official-merged/nimble#808.patch b/applied_patches/official-merged/nimble#808.patch new file mode 100644 index 00000000..031e4ed6 --- /dev/null +++ b/applied_patches/official-merged/nimble#808.patch @@ -0,0 +1,28 @@ +From c028c2bcdbe7b53df8be44919bbad82061329913 Mon Sep 17 00:00:00 2001 +From: h2zero +Date: Fri, 24 Apr 2020 08:25:42 -0600 +Subject: [PATCH] nimble/gap: Make initial connection event length constants + zero. + +The NimBLE controller currently does not use these parameters, however other controllers such as the esp32 do make use of them. + +This PR is for changing these to a more "neutral" value to avoid unexpected behavior when using a different controller. +--- + nimble/host/include/host/ble_gap.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/host/ble_gap.h b/src/host/ble_gap.h +index 271340f..b4dbdb0 100644 +--- a/src/host/ble_gap.h ++++ b/src/host/ble_gap.h +@@ -98,8 +98,8 @@ struct hci_conn_update; + + #define BLE_GAP_INITIAL_CONN_LATENCY 0 + #define BLE_GAP_INITIAL_SUPERVISION_TIMEOUT 0x0100 +-#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0010 +-#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0300 ++#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0000 ++#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0000 + + #define BLE_GAP_ROLE_MASTER 0 + #define BLE_GAP_ROLE_SLAVE 1 diff --git a/applied_patches/un-merged/esp-nimble#7.patch b/applied_patches/un-merged/esp-nimble#7.patch new file mode 100644 index 00000000..ce51b5e9 --- /dev/null +++ b/applied_patches/un-merged/esp-nimble#7.patch @@ -0,0 +1,146 @@ +From 42fef9c3556ecd7a9b6c4d489a4a198696381599 Mon Sep 17 00:00:00 2001 +From: h2zero +Date: Thu, 16 Apr 2020 10:30:50 -0600 +Subject: [PATCH 1/2] Allow host to resolve peer RPA without using local RPA. + +--- + nimble/host/src/ble_hs_conn.c | 21 +++++++++------------ + nimble/host/src/ble_hs_hci_evt.c | 13 ++++--------- + nimble/host/src/ble_sm.c | 31 ++++++++++++++----------------- + 3 files changed, 27 insertions(+), 38 deletions(-) + +diff --git a/src/nimble/host/src/ble_hs_conn.c b/src/nimble/host/src/ble_hs_conn.c +index 035150b98..eb65e3288 100644 +--- a/src/nimble/host/src/ble_hs_conn.c ++++ b/src/nimble/host/src/ble_hs_conn.c +@@ -410,22 +410,19 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, + + #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + /* RPA: Override peer address information. */ +- struct ble_hs_resolv_entry *rl = NULL; +- + ble_addr_t bhc_peer_addr; + bhc_peer_addr.type = conn->bhc_peer_addr.type; + memcpy(bhc_peer_addr.val, conn->bhc_peer_addr.val, BLE_DEV_ADDR_LEN); +- if (ble_host_rpa_enabled()) { +- +- uint8_t *local_id = NULL; +- ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL); + +- rl = ble_hs_resolv_list_find(bhc_peer_addr.val); +- if (rl != NULL) { +- memcpy(addrs->peer_ota_addr.val, addrs->peer_id_addr.val, BLE_DEV_ADDR_LEN); +- memcpy(addrs->peer_id_addr.val, rl->rl_identity_addr, BLE_DEV_ADDR_LEN); +- +- addrs->peer_id_addr.type = rl->rl_addr_type; ++ struct ble_hs_resolv_entry *rl = NULL; ++ 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; ++ ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL); + + /* RL is present: populate our id addr with public ID */ + memcpy(addrs->our_id_addr.val, local_id, BLE_DEV_ADDR_LEN); +diff --git a/src/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/host/src/ble_hs_hci_evt.c +index 43cb5b580..78383dff0 100644 +--- a/src/nimble/host/src/ble_hs_hci_evt.c ++++ b/src/nimble/host/src/ble_hs_hci_evt.c +@@ -332,16 +332,11 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) + if (ble_host_rpa_enabled()) { + uint8_t *local_id_rpa = ble_hs_get_rpa_local(); + memcpy(evt.local_rpa, local_id_rpa, 6); +- +- struct ble_hs_resolv_entry *rl = NULL; +- ble_rpa_replace_peer_params_with_rl(evt.peer_addr, +- &evt.peer_addr_type, &rl); +- if (rl == NULL) { +- if (ble_rpa_resolv_add_peer_rec(evt.peer_addr) != 0) { +- BLE_HS_LOG(DEBUG, "Memory unavailable for new peer record\n"); +- } +- } + } ++ ++ struct ble_hs_resolv_entry *rl = NULL; ++ ble_rpa_replace_peer_params_with_rl(evt.peer_addr, ++ &evt.peer_addr_type, &rl); + #endif + } else { + memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN); +diff --git a/src/nimble/host/src/ble_sm.c b/src/nimble/host/src/ble_sm.c +index e57562519..dc96c76c7 100644 +--- a/src/nimble/host/src/ble_sm.c ++++ b/src/nimble/host/src/ble_sm.c +@@ -548,26 +548,23 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) + + identity_ev = 1; + #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +- if (ble_host_rpa_enabled()) +- { +- struct ble_hs_dev_records *p_dev_rec = +- ble_rpa_find_peer_dev_rec(conn->bhc_peer_rpa_addr.val); +- if (p_dev_rec == NULL) { +- if (!ble_rpa_resolv_add_peer_rec(conn->bhc_peer_rpa_addr.val)) { +- p_dev_rec = ble_rpa_find_peer_dev_rec(conn->bhc_peer_rpa_addr.val); +- } ++ struct ble_hs_dev_records *p_dev_rec = ++ ble_rpa_find_peer_dev_rec(conn->bhc_peer_rpa_addr.val); ++ if (p_dev_rec == NULL) { ++ if (!ble_rpa_resolv_add_peer_rec(conn->bhc_peer_rpa_addr.val)) { ++ p_dev_rec = ble_rpa_find_peer_dev_rec(conn->bhc_peer_rpa_addr.val); + } ++ } + +- if (p_dev_rec != NULL) { +- /* Once bonded, copy the peer device records */ +- swap_buf(p_dev_rec->peer_sec.irk, proc->peer_keys.irk, 16); +- p_dev_rec->peer_sec.irk_present = proc->peer_keys.irk_valid; +- memcpy(p_dev_rec->peer_sec.peer_addr.val, +- proc->peer_keys.addr, 6); +- p_dev_rec->peer_sec.peer_addr.type = proc->peer_keys.addr_type; ++ if (p_dev_rec != NULL) { ++ /* Once bonded, copy the peer device records */ ++ swap_buf(p_dev_rec->peer_sec.irk, proc->peer_keys.irk, 16); ++ p_dev_rec->peer_sec.irk_present = proc->peer_keys.irk_valid; ++ memcpy(p_dev_rec->peer_sec.peer_addr.val, ++ proc->peer_keys.addr, 6); ++ p_dev_rec->peer_sec.peer_addr.type = proc->peer_keys.addr_type; + +- ble_store_persist_peer_records(); +- } ++ ble_store_persist_peer_records(); + } + #endif + } + +From 70ea4ccc017d8b729123289bf74112d187830fd4 Mon Sep 17 00:00:00 2001 +From: h2zero +Date: Fri, 1 May 2020 21:54:46 -0600 +Subject: [PATCH 2/2] Remove resolving RPA in advertisement report. + +--- + nimble/host/src/ble_hs_hci_evt.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/src/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/host/src/ble_hs_hci_evt.c +index 78383dff0..30dc92f28 100644 +--- a/src/nimble/host/src/ble_hs_hci_evt.c ++++ b/src/nimble/host/src/ble_hs_hci_evt.c +@@ -433,14 +433,6 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, uint8_t *data, int len) + memcpy(desc.addr.val, data + off, 6); + off += 6; + +-#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +- if (ble_host_rpa_enabled()) { +- /* Now RPA to be resolved here, since controller is unaware of the +- * address is RPA */ +- ble_rpa_replace_peer_params_with_rl(desc.addr.val, +- &desc.addr.type, NULL); +- } +-#endif + desc.length_data = data[off]; + ++off; + diff --git a/src/console/console.h b/src/console/console.h index 342d6f69..96f96515 100644 --- a/src/console/console.h +++ b/src/console/console.h @@ -18,4 +18,4 @@ #define console_printf printf -#endif \ No newline at end of file +#endif diff --git a/src/esp-hci/src/esp_nimble_hci.c b/src/esp-hci/src/esp_nimble_hci.c index 8d994c44..e4ab9993 100644 --- a/src/esp-hci/src/esp_nimble_hci.c +++ b/src/esp-hci/src/esp_nimble_hci.c @@ -519,4 +519,4 @@ esp_err_t esp_nimble_hci_and_controller_deinit(void) } return ESP_OK; -} \ No newline at end of file +} diff --git a/src/esp_nimble_cfg.h b/src/esp_nimble_cfg.h index 16d4253b..384ec4a5 100644 --- a/src/esp_nimble_cfg.h +++ b/src/esp_nimble_cfg.h @@ -1,6 +1,4 @@ -/* Modifications copyright (C) 2020 Ryan Powell */ - #ifndef __ESP_NIMBLE_CFG__ #define __ESP_NIMBLE_CFG__ #include "nimconfig.h" @@ -470,7 +468,7 @@ #endif #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT -#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT CONFIG_BT_NIMBLE_FLOW_CTRL_TX_ON_DISCONNECT +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT #endif #ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS diff --git a/src/esp_nimble_hci.h b/src/esp_nimble_hci.h index 3c66ca79..e10436f3 100644 --- a/src/esp_nimble_hci.h +++ b/src/esp_nimble_hci.h @@ -135,4 +135,4 @@ esp_err_t esp_nimble_hci_and_controller_deinit(void); } #endif -#endif /* __ESP_NIMBLE_HCI_H__ */ \ No newline at end of file +#endif /* __ESP_NIMBLE_HCI_H__ */ diff --git a/src/esp_nimble_mem.h b/src/esp_nimble_mem.h index d257c546..90e52a20 100644 --- a/src/esp_nimble_mem.h +++ b/src/esp_nimble_mem.h @@ -1,4 +1,3 @@ - /* * Copyright 2020 Espressif Systems (Shanghai) PTE LTD * @@ -37,4 +36,4 @@ void nimble_platform_mem_free(void *ptr); } #endif -#endif /* __ESP_NIMBLE_MEM_H__ */ \ No newline at end of file +#endif /* __ESP_NIMBLE_MEM_H__ */ diff --git a/src/host/ble_gap.h b/src/host/ble_gap.h index 9ef4e18e..b4dbdb05 100644 --- a/src/host/ble_gap.h +++ b/src/host/ble_gap.h @@ -98,8 +98,8 @@ struct hci_conn_update; #define BLE_GAP_INITIAL_CONN_LATENCY 0 #define BLE_GAP_INITIAL_SUPERVISION_TIMEOUT 0x0100 -#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0010 -#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0300 +#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0000 +#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0000 #define BLE_GAP_ROLE_MASTER 0 #define BLE_GAP_ROLE_SLAVE 1 @@ -1783,6 +1783,20 @@ int ble_gap_unpair(const ble_addr_t *peer_addr); */ int ble_gap_unpair_oldest_peer(void); +/** + * Similar to `ble_gap_unpair_oldest_peer()`, except it makes sure that the + * peer received in input parameters is not deleted. + * + * @param peer_addr Address of the peer (not to be deleted) + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr); + #define BLE_GAP_PRIVATE_MODE_NETWORK 0 #define BLE_GAP_PRIVATE_MODE_DEVICE 1 @@ -1886,20 +1900,6 @@ struct ble_gap_event_listener { SLIST_ENTRY(ble_gap_event_listener) link; }; -/** - * Similar to `ble_gap_unpair_oldest_peer()`, except it makes sure that current - * peer is not deleted. - * - * @param peer_addr Address of the current peer (not to be deleted) - * - * @return 0 on success; - * A BLE host HCI return code if the controller - * rejected the request; - * A BLE host core return code on unexpected - * error. - */ -int ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer); - /** * Registers listener for GAP events * diff --git a/src/host/ble_store.h b/src/host/ble_store.h index e470f8ec..a3eca5d2 100644 --- a/src/host/ble_store.h +++ b/src/host/ble_store.h @@ -288,8 +288,6 @@ int ble_store_clear(void); /*** Utility functions. */ -int ble_store_clean_old_cccds(const ble_addr_t *curr_peer); - int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int max_peers); diff --git a/src/nimble/host/mesh/src/src/ble_gap_priv.h b/src/nimble/host/mesh/src/src/ble_gap_priv.h index 4285cfa4..c8087289 100644 --- a/src/nimble/host/mesh/src/src/ble_gap_priv.h +++ b/src/nimble/host/mesh/src/src/ble_gap_priv.h @@ -119,6 +119,7 @@ void ble_gap_preempt(void); void ble_gap_preempt_done(void); void ble_gap_conn_broken(uint16_t conn_handle, int reason); +void ble_gap_reset_state(int reason); int32_t ble_gap_timer(void); int ble_gap_init(void); diff --git a/src/nimble/host/mesh/src/src/ble_hs_id_priv.h b/src/nimble/host/mesh/src/src/ble_hs_id_priv.h index aa2827d4..c031b951 100644 --- a/src/nimble/host/mesh/src/src/ble_hs_id_priv.h +++ b/src/nimble/host/mesh/src/src/ble_hs_id_priv.h @@ -33,6 +33,10 @@ int ble_hs_id_use_addr(uint8_t addr_type); void ble_hs_id_reset(void); void ble_hs_id_rnd_reset(void); +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type); +int ble_hs_id_set_pseudo_rnd(const uint8_t *); +#endif #ifdef __cplusplus } #endif diff --git a/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h b/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h index 7f0aa4b9..86157da0 100644 --- a/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h +++ b/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h @@ -35,6 +35,9 @@ int ble_hs_pvcy_add_entry(const uint8_t *addr, uint8_t addrtype, const uint8_t *irk); int ble_hs_pvcy_ensure_started(void); int ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode); +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +bool ble_hs_pvcy_enabled(void); +#endif #ifdef __cplusplus } diff --git a/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h b/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h new file mode 100644 index 00000000..568aa89a --- /dev/null +++ b/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h @@ -0,0 +1,108 @@ +/* + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +/* + * An entry in the resolving list. + */ +struct ble_hs_resolv_entry { + uint8_t rl_addr_type; + uint8_t rl_local_irk[16]; + uint8_t rl_peer_irk[16]; + uint8_t rl_identity_addr[BLE_DEV_ADDR_LEN]; + uint8_t rl_pseudo_id[BLE_DEV_ADDR_LEN]; + uint8_t rl_local_rpa[BLE_DEV_ADDR_LEN]; + uint8_t rl_peer_rpa[BLE_DEV_ADDR_LEN]; +}; + +#if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) +/* Persist peer records in NVS. XXX Need to handle this in `store` module */ +int ble_store_persist_peer_records(void); +#endif + +struct ble_hs_peer_sec { + ble_addr_t peer_addr; + uint8_t irk[16]; + uint8_t irk_present: 1; +}; +/* + * BLE host peer device record, this helps in storing peer RPA before bond is + * created and IRKs are exchanged. + */ +struct ble_hs_dev_records { + bool rec_used; + uint8_t pseudo_addr[BLE_DEV_ADDR_LEN]; + uint8_t rand_addr[BLE_DEV_ADDR_LEN]; + uint8_t identity_addr[BLE_DEV_ADDR_LEN]; + struct ble_hs_peer_sec peer_sec; +}; + +/* Add a device to the resolving list */ +int ble_hs_resolv_list_add(uint8_t *cmdbuf); +int ble_hs_gen_own_rpa_random(void); +uint8_t *ble_hs_get_rpa_local(void); + +/* Remove a device from the resolving list */ +int ble_hs_resolv_list_rmv(uint8_t, uint8_t *); +/* Clear the resolving list and peer dev record */ +void ble_hs_resolv_list_clear_all(void); + +/* Address resolution enable command */ +void ble_hs_resolv_enable(bool); + +/* Finds 'addr' in resolving list. Doesnt check if address resolution enabled */ +struct ble_hs_resolv_entry * +ble_hs_resolv_list_find(uint8_t *addr); + +/* Returns true if host based RPA (privacy) is enabled */ +bool ble_host_rpa_enabled(void); + +/* Searches peer device records (RPA) and fetches matching RL, peer_address + * into input parameters if RL is found */ +void +ble_rpa_replace_peer_params_with_rl(uint8_t *, uint8_t *, struct ble_hs_resolv_entry **); + +int ble_rpa_resolv_add_peer_rec(uint8_t *); + +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 *); + +/* Set the resolvable private address timeout */ +int ble_hs_resolv_set_rpa_tmo(uint16_t); + +/* Resolve a resolvable private address */ +int ble_hs_resolv_rpa(uint8_t *rpa, uint8_t *irk); + +/* Initialize resolv*/ +void ble_hs_resolv_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/nimble/host/mesh/src/src/ble_sm_priv.h b/src/nimble/host/mesh/src/src/ble_sm_priv.h index 3f64b778..74205bd0 100644 --- a/src/nimble/host/mesh/src/src/ble_sm_priv.h +++ b/src/nimble/host/mesh/src/src/ble_sm_priv.h @@ -399,6 +399,7 @@ int ble_sm_slave_initiate(uint16_t conn_handle); int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, const uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); +int ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data); int ble_sm_init(void); #define BLE_SM_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ @@ -419,6 +420,9 @@ int ble_sm_init(void); #define ble_sm_init() 0 +#define ble_sm_alg_encrypt(key, plaintext, enc_data) \ + BLE_HS_ENOTSUP + #endif struct ble_l2cap_chan *ble_sm_create_chan(uint16_t handle); diff --git a/src/nimble/host/src/ble_att_cmd.c b/src/nimble/host/src/ble_att_cmd.c index 999f57a2..bad192df 100644 --- a/src/nimble/host/src/ble_att_cmd.c +++ b/src/nimble/host/src/ble_att_cmd.c @@ -66,11 +66,10 @@ ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom) ble_hs_lock(); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, - &chan); - if (chan == NULL) { + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, + &chan); + if (rc != 0) { os_mbuf_free_chain(txom); - rc = BLE_HS_ENOTCONN; } else { ble_att_truncate_to_mtu(chan, txom); rc = ble_l2cap_tx(conn, chan, txom); diff --git a/src/nimble/host/src/ble_gap.c b/src/nimble/host/src/ble_gap.c index e6564012..6cce77df 100644 --- a/src/nimble/host/src/ble_gap.c +++ b/src/nimble/host/src/ble_gap.c @@ -17,8 +17,6 @@ * under the License. */ - /* Modifications copyright (C) 2020 Ryan Powell */ - #include #include #include @@ -5303,8 +5301,7 @@ ble_gap_unpair_oldest_peer(void) } if (num_peers == 0) { - return BLE_HS_ENOENT; - //return 0; + return BLE_HS_ENOENT; } rc = ble_gap_unpair(&oldest_peer_id_addr); @@ -5316,14 +5313,14 @@ ble_gap_unpair_oldest_peer(void) } int -ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer) +ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr) { - ble_addr_t oldest_peer_id_addr[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int num_peers; int rc, i; rc = ble_store_util_bonded_peers( - &oldest_peer_id_addr[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + &peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); if (rc != 0) { return rc; } @@ -5333,21 +5330,16 @@ ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer) } for (i = 0; i < num_peers; i++) { - if (memcmp(curr_peer, &oldest_peer_id_addr[i], sizeof (ble_addr_t)) != 0) { + if (ble_addr_cmp(peer_addr, &peer_id_addrs[i]) != 0) { break; } } - if (i < num_peers) { - rc = ble_gap_unpair(&oldest_peer_id_addr[i]); - if (rc != 0) { - return rc; - } - } else { + if (i >= num_peers) { return BLE_HS_ENOMEM; } - return 0; + return ble_gap_unpair(&peer_id_addrs[i]); } void @@ -5371,7 +5363,8 @@ ble_gap_passkey_event(uint16_t conn_handle, } void -ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored) +ble_gap_enc_event(uint16_t conn_handle, int status, + int security_restored, int bonded) { #if !NIMBLE_BLE_SM return; @@ -5387,17 +5380,24 @@ ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored) ble_gap_event_listener_call(&event); ble_gap_call_conn_event_cb(&event, conn_handle); -/* H2zero mod - If bonding is not enabled don't store cccd data - if (status == 0) { -*/ - if (status == 0 && ble_hs_cfg.sm_bonding) { -/* End mod */ - if (security_restored) { - ble_gatts_bonding_restored(conn_handle); - } else { - ble_gatts_bonding_established(conn_handle); - } + if (status != 0) { + return; + } + + /* If encryption succeded and encryption has been restored for bonded device, + * notify gatt server so it has chance to send notification/indication if needed. + */ + if (security_restored) { + ble_gatts_bonding_restored(conn_handle); + return; + } + + /* If this is fresh pairing and bonding has been established, + * notify gatt server about that so previous subscriptions (before bonding) + * can be stored. + */ + if (bonded) { + ble_gatts_bonding_established(conn_handle); } } diff --git a/src/nimble/host/src/ble_gap_priv.h b/src/nimble/host/src/ble_gap_priv.h index c8087289..90c32e22 100644 --- a/src/nimble/host/src/ble_gap_priv.h +++ b/src/nimble/host/src/ble_gap_priv.h @@ -99,7 +99,7 @@ int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params); void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); void ble_gap_enc_event(uint16_t conn_handle, int status, - int security_restored); + int security_restored, int bonded); void ble_gap_passkey_event(uint16_t conn_handle, struct ble_gap_passkey_params *passkey_params); void ble_gap_notify_rx_event(uint16_t conn_handle, uint16_t attr_handle, diff --git a/src/nimble/host/src/ble_gatts.c b/src/nimble/host/src/ble_gatts.c index e84361cb..fccf1027 100644 --- a/src/nimble/host/src/ble_gatts.c +++ b/src/nimble/host/src/ble_gatts.c @@ -1689,30 +1689,29 @@ ble_gatts_bonding_established(uint16_t conn_handle) conn = ble_hs_conn_find(conn_handle); BLE_HS_DBG_ASSERT(conn != NULL); + BLE_HS_DBG_ASSERT(conn->bhc_sec_state.bonded); - if (conn->bhc_sec_state.bonded) { - cccd_value.peer_addr = conn->bhc_peer_addr; - gatt_srv = &conn->bhc_gatt_svr; + cccd_value.peer_addr = conn->bhc_peer_addr; + gatt_srv = &conn->bhc_gatt_svr; - for (i = 0; i < gatt_srv->num_clt_cfgs; ++i) { - clt_cfg = (gatt_srv->clt_cfgs + i); - if (clt_cfg == NULL) { - continue; - } + for (i = 0; i < gatt_srv->num_clt_cfgs; ++i) { + clt_cfg = (gatt_srv->clt_cfgs + i); + if (clt_cfg == NULL) { + continue; + } - if (clt_cfg->flags != 0) { - cccd_value.chr_val_handle = clt_cfg->chr_val_handle; - cccd_value.flags = clt_cfg->flags; - cccd_value.value_changed = 0; + if (clt_cfg->flags != 0) { + cccd_value.chr_val_handle = clt_cfg->chr_val_handle; + cccd_value.flags = clt_cfg->flags; + cccd_value.value_changed = 0; - /* Store write use ble_hs_lock */ - ble_hs_unlock(); - ble_store_write_cccd(&cccd_value); - ble_hs_lock(); + /* Store write use ble_hs_lock */ + ble_hs_unlock(); + ble_store_write_cccd(&cccd_value); + ble_hs_lock(); - conn = ble_hs_conn_find(conn_handle); - BLE_HS_DBG_ASSERT(conn != NULL); - } + conn = ble_hs_conn_find(conn_handle); + BLE_HS_DBG_ASSERT(conn != NULL); } } diff --git a/src/nimble/host/src/ble_hs_conn.c b/src/nimble/host/src/ble_hs_conn.c index c1985157..eb65e328 100644 --- a/src/nimble/host/src/ble_hs_conn.c +++ b/src/nimble/host/src/ble_hs_conn.c @@ -410,18 +410,16 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) /* RPA: Override peer address information. */ - struct ble_hs_resolv_entry *rl = NULL; - ble_addr_t bhc_peer_addr; bhc_peer_addr.type = conn->bhc_peer_addr.type; memcpy(bhc_peer_addr.val, conn->bhc_peer_addr.val, BLE_DEV_ADDR_LEN); - + + struct ble_hs_resolv_entry *rl = NULL; rl = ble_hs_resolv_list_find(bhc_peer_addr.val); if (rl != NULL) { - addrs->peer_ota_addr = conn->bhc_peer_rpa_addr; 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; ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL); diff --git a/src/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/host/src/ble_hs_hci_evt.c index 3f7c5d79..30dc92f2 100644 --- a/src/nimble/host/src/ble_hs_hci_evt.c +++ b/src/nimble/host/src/ble_hs_hci_evt.c @@ -333,18 +333,10 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) uint8_t *local_id_rpa = ble_hs_get_rpa_local(); memcpy(evt.local_rpa, local_id_rpa, 6); } - + struct ble_hs_resolv_entry *rl = NULL; ble_rpa_replace_peer_params_with_rl(evt.peer_addr, &evt.peer_addr_type, &rl); - if (rl == NULL) { - if (ble_rpa_resolv_add_peer_rec(evt.peer_addr) != 0) { - BLE_HS_LOG(DEBUG, "Memory unavailable for new peer record\n"); - } - } - /* Set the correct RPA for logging */ - memcpy(evt.peer_rpa, data + 6, BLE_DEV_ADDR_LEN); - #endif } else { memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN); @@ -441,14 +433,6 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, uint8_t *data, int len) memcpy(desc.addr.val, data + off, 6); off += 6; -#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) - if (ble_host_rpa_enabled()) { - /* Now RPA to be resolved here, since controller is unaware of the - * address is RPA */ - ble_rpa_replace_peer_params_with_rl(desc.addr.val, - &desc.addr.type, NULL); - } -#endif desc.length_data = data[off]; ++off; diff --git a/src/nimble/host/src/ble_hs_misc.c b/src/nimble/host/src/ble_hs_misc.c index e6bb3825..00200d31 100644 --- a/src/nimble/host/src/ble_hs_misc.c +++ b/src/nimble/host/src/ble_hs_misc.c @@ -56,7 +56,7 @@ ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, return rc; } -void +int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan) @@ -66,7 +66,9 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, int rc; rc = ble_hs_misc_conn_chan_find(conn_handle, cid, &conn, &chan); - BLE_HS_DBG_ASSERT_EVAL(rc == 0); + if (rc != 0) { + return rc; + } if (out_conn != NULL) { *out_conn = conn; @@ -74,6 +76,8 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, if (out_chan != NULL) { *out_chan = chan; } + + return 0; } uint8_t diff --git a/src/nimble/host/src/ble_hs_priv.h b/src/nimble/host/src/ble_hs_priv.h index 27bf904b..49269546 100644 --- a/src/nimble/host/src/ble_hs_priv.h +++ b/src/nimble/host/src/ble_hs_priv.h @@ -115,9 +115,9 @@ int ble_hs_hci_evt_acl_process(struct os_mbuf *om); int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); -void ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, - struct ble_hs_conn **out_conn, - struct ble_l2cap_chan **out_chan); +int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan); uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type); int ble_hs_misc_restore_irks(void); diff --git a/src/nimble/host/src/ble_l2cap_sig.c b/src/nimble/host/src/ble_l2cap_sig.c index 07a338ae..bc73d954 100644 --- a/src/nimble/host/src/ble_l2cap_sig.c +++ b/src/nimble/host/src/ble_l2cap_sig.c @@ -473,8 +473,13 @@ ble_l2cap_sig_update(uint16_t conn_handle, STATS_INC(ble_l2cap_stats, update_init); ble_hs_lock(); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, - &conn, &chan); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, + &conn, &chan); + if (rc != 0) { + ble_hs_unlock(); + goto done; + } + master = conn->bhc_flags & BLE_HS_CONN_F_MASTER; ble_hs_unlock(); diff --git a/src/nimble/host/src/ble_l2cap_sig_cmd.c b/src/nimble/host/src/ble_l2cap_sig_cmd.c index 366dde62..510420f0 100644 --- a/src/nimble/host/src/ble_l2cap_sig_cmd.c +++ b/src/nimble/host/src/ble_l2cap_sig_cmd.c @@ -28,9 +28,11 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom) int rc; ble_hs_lock(); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, - &conn, &chan); - rc = ble_l2cap_tx(conn, chan, txom); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, + &conn, &chan); + if (rc == 0) { + rc = ble_l2cap_tx(conn, chan, txom); + } ble_hs_unlock(); return rc; diff --git a/src/nimble/host/src/ble_sm.c b/src/nimble/host/src/ble_sm.c index 1bc55a62..3dc3f648 100644 --- a/src/nimble/host/src/ble_sm.c +++ b/src/nimble/host/src/ble_sm.c @@ -944,7 +944,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res) if (res->enc_cb) { BLE_HS_DBG_ASSERT(proc == NULL || rm); - ble_gap_enc_event(conn_handle, res->app_status, res->restore); + ble_gap_enc_event(conn_handle, res->app_status, res->restore, res->bonded); } if (res->app_status == 0 && @@ -1198,6 +1198,7 @@ ble_sm_enc_event_rx(uint16_t conn_handle, uint8_t evt_status, int encrypted) ble_hs_unlock(); + res.bonded = bonded; ble_sm_process_result(conn_handle, &res); } @@ -2459,7 +2460,7 @@ ble_sm_timer(void) * procedures without reconnect. */ while ((proc = STAILQ_FIRST(&exp_list)) != NULL) { - ble_gap_enc_event(proc->conn_handle, BLE_HS_ETIMEOUT, 0); + ble_gap_enc_event(proc->conn_handle, BLE_HS_ETIMEOUT, 0, 0); STAILQ_REMOVE_HEAD(&exp_list, next); ble_sm_proc_free(proc); diff --git a/src/nimble/host/src/ble_sm_cmd.c b/src/nimble/host/src/ble_sm_cmd.c index b5e674e7..e12e109d 100644 --- a/src/nimble/host/src/ble_sm_cmd.c +++ b/src/nimble/host/src/ble_sm_cmd.c @@ -52,14 +52,19 @@ ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; + int rc; BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); STATS_INC(ble_l2cap_stats, sm_tx); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM, - &conn, &chan); - return ble_l2cap_tx(conn, chan, txom); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM, + &conn, &chan); + if (rc == 0) { + rc = ble_l2cap_tx(conn, chan, txom); + } + + return rc; } #if NIMBLE_BLE_SM diff --git a/src/nimble/host/src/ble_sm_priv.h b/src/nimble/host/src/ble_sm_priv.h index 74205bd0..bbb4b03a 100644 --- a/src/nimble/host/src/ble_sm_priv.h +++ b/src/nimble/host/src/ble_sm_priv.h @@ -277,10 +277,10 @@ struct ble_sm_result { uint8_t sm_err; struct ble_gap_passkey_params passkey_params; void *state_arg; - unsigned execute:1; - unsigned enc_cb:1; - unsigned persist_keys:1; - unsigned restore:1; + unsigned execute : 1; + unsigned enc_cb : 1; + unsigned bonded : 1; + unsigned restore : 1; }; #if MYNEWT_VAL(BLE_HS_DEBUG) diff --git a/src/nimble/host/src/ble_store_util.c b/src/nimble/host/src/ble_store_util.c index 9813a865..73c71d93 100644 --- a/src/nimble/host/src/ble_store_util.c +++ b/src/nimble/host/src/ble_store_util.c @@ -19,6 +19,7 @@ #include "host/ble_store.h" #include "ble_hs_priv.h" +#include "ble_hs_resolv_priv.h" struct ble_store_util_peer_set { ble_addr_t *peer_id_addrs; @@ -27,12 +28,6 @@ struct ble_store_util_peer_set { int status; }; -struct ble_store_util_peer_cccd_set { - struct ble_store_util_peer_set peer_set; - ble_addr_t *curr_peer_addr; -}; - - static int ble_store_util_iter_unique_peer(int obj_type, union ble_store_value *val, @@ -65,42 +60,6 @@ ble_store_util_iter_unique_peer(int obj_type, return 0; } -static int -ble_store_util_iter_peer_cccd(int obj_type, - union ble_store_value *val, - void *arg) -{ - struct ble_store_util_peer_cccd_set *set; - int i; - - set = arg; - - /* Do nothing if this peer is a duplicate or current peer */ - for (i = 0; i < set->peer_set.num_peers; i++) { - if (ble_addr_cmp(set->peer_set.peer_id_addrs + i, &val->cccd.peer_addr) == 0) { - return 0; - } - - if (set->curr_peer_addr != NULL) { - if (ble_addr_cmp(set->curr_peer_addr, &val->cccd.peer_addr) == 0) { - return 0; - } - } - } - - if (set->peer_set.num_peers >= set->peer_set.max_peers) { - /* Overflow; abort the iterate procedure. */ - set->peer_set.status = BLE_HS_ENOMEM; - return 1; - } - - set->peer_set.peer_id_addrs[set->peer_set.num_peers] = val->cccd.peer_addr; - set->peer_set.num_peers++; - - return 0; -} - - /** * Retrieves the set of peer addresses for which a bond has been established. * @@ -141,51 +100,6 @@ ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, return 0; } -/** - * Retrieves the set of peer addresses for which CCCDs are subscribed. - * - * @param out_peer_id_addrs On success, the set of peer addresses - * gets written here. - * @param out_num_peers On success, the number of peer addresses gets written - * here. - * @param max_peers The capacity of the destination buffer. - * - * @param curr_peer_addrs Current peer's address, ignore if NULL - * - * @return 0 on success; - * BLE_HS_ENOMEM if the destination buffer is too - * small; - * Other nonzero on error. - */ -static int -ble_store_util_subscribed_cccds(ble_addr_t *out_peer_id_addrs, int *out_num_peers, - int max_peers, ble_addr_t *curr_peer_addr) -{ - struct ble_store_util_peer_cccd_set set = { - .peer_set = { - .peer_id_addrs = out_peer_id_addrs, - .num_peers = 0, - .max_peers = max_peers, - .status = 0, - }, - .curr_peer_addr = curr_peer_addr, - }; - int rc; - - rc = ble_store_iterate(BLE_STORE_OBJ_TYPE_CCCD, - ble_store_util_iter_peer_cccd, - &set); - if (rc != 0) { - return rc; - } - if (set.peer_set.status != 0) { - return set.peer_set.status; - } - - *out_num_peers = set.peer_set.num_peers; - return 0; -} - /** * Deletes all entries from the store that are attached to the specified peer * address. This function deletes security entries and CCCD records. @@ -222,6 +136,25 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) return rc; } +#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); + + if (peer_rec != NULL) { + rc = ble_hs_resolv_list_rmv(peer_rec->peer_sec.peer_addr.type, + peer_rec->peer_sec.peer_addr.val); + if (rc != 0) { + /* We can't do anything much here, continue with removing from peer_record */ + BLE_HS_LOG(DEBUG, "Peer Device was not removed from RL \n"); + } + + rc = ble_rpa_remove_peer_dev_rec(peer_rec); + if (rc != 0) { + return rc; + } + } +#endif + return 0; } @@ -305,63 +238,6 @@ ble_store_util_delete_oldest_peer(void) return 0; } -/** - * Delete CCCDs of unbonded devices. - * - * @param curr_peer Current peer's address (not to delete), ignore - * ignore if NULL - * - * @return 0 on success; - * nonzero on error. - */ -int -ble_store_clean_old_cccds(const ble_addr_t *curr_peer) -{ - ble_addr_t peer_cccd_addrs[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; - ble_addr_t peer_bonded_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; - int num_bonded_peers, num_cccd_peers; - int i, j, rc; - - rc = ble_store_util_subscribed_cccds(&peer_cccd_addrs[0], &num_cccd_peers, - MYNEWT_VAL(BLE_STORE_MAX_CCCDS), - (void *) curr_peer); - if (rc != 0) { - return rc; - } - - rc = ble_store_util_bonded_peers(&peer_bonded_addrs[0], &num_bonded_peers, - MYNEWT_VAL(BLE_STORE_MAX_BONDS)); - if (rc != 0) { - return rc; - } - - union ble_store_key key = {0}; - /* Init rc to BLE_HS_ENOENT to indicate no CCCD is deleted */ - rc = BLE_HS_ENOENT; - - for (i = 0; i < num_cccd_peers; i++) { - key.cccd.peer_addr = peer_cccd_addrs[i]; - - for (j = 0; j < num_bonded_peers; j++) { - if (memcmp(&peer_cccd_addrs[i], &peer_bonded_addrs[j], - sizeof(ble_addr_t)) == 0) { - break; - } - } - - if (j < num_bonded_peers) { - continue; - } - - rc = ble_store_util_delete_all(BLE_STORE_OBJ_TYPE_CCCD, &key); - if (rc != 0) { - return rc; - } - } - - return rc; -} - /** * Round-robin status callback. If a there is insufficient storage capacity * for a new record, delete the oldest bond and proceed with the persist @@ -374,33 +250,18 @@ ble_store_clean_old_cccds(const ble_addr_t *curr_peer) int ble_store_util_status_rr(struct ble_store_status_event *event, void *arg) { - int rc = BLE_HS_EUNKNOWN; switch (event->event_code) { case BLE_STORE_EVENT_OVERFLOW: switch (event->overflow.obj_type) { - case BLE_STORE_OBJ_TYPE_OUR_SEC: - case BLE_STORE_OBJ_TYPE_PEER_SEC: - return ble_gap_unpair_oldest_peer(); - case BLE_STORE_OBJ_TYPE_CCCD: - /* Try to remove unbonded CCCDs first */ - if ((rc = ble_store_clean_old_cccds((void *) &event->overflow.value->cccd.peer_addr)) == BLE_HS_ENOENT) { - /* No unbonded CCCDs found to delete, try unpairing oldest peer - * except current peer */ - return ble_gap_unpair_oldest_except_curr((void *) &event->overflow.value->cccd.peer_addr); - } - return rc; - - default: - return BLE_HS_EUNKNOWN; - - /* case BLE_STORE_OBJ_TYPE_OUR_SEC: - case BLE_STORE_OBJ_TYPE_PEER_SEC: - case BLE_STORE_OBJ_TYPE_CCCD: - return ble_gap_unpair_oldest_peer(); - - default: - return BLE_HS_EUNKNOWN; - */ + case BLE_STORE_OBJ_TYPE_OUR_SEC: + case BLE_STORE_OBJ_TYPE_PEER_SEC: + return ble_gap_unpair_oldest_peer(); + case BLE_STORE_OBJ_TYPE_CCCD: + /* Try unpairing oldest peer except current peer */ + return ble_gap_unpair_oldest_except(&event->overflow.value->cccd.peer_addr); + + default: + return BLE_HS_EUNKNOWN; } case BLE_STORE_EVENT_FULL: diff --git a/src/nimble/nimble_npl.h b/src/nimble/nimble_npl.h index 689d363d..88383228 100644 --- a/src/nimble/nimble_npl.h +++ b/src/nimble/nimble_npl.h @@ -16,8 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - -/* Modifications copyright (C) 2020 Ryan Powell*/ #ifndef _NIMBLE_NPL_H_ #define _NIMBLE_NPL_H_ @@ -26,6 +24,7 @@ #include #include #include "nimconfig.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/src/nimble/nimble_port.h b/src/nimble/nimble_port.h index aa5e6390..e8996a66 100644 --- a/src/nimble/nimble_port.h +++ b/src/nimble/nimble_port.h @@ -17,7 +17,6 @@ * under the License. */ - /* Modifications copyright (C) 2020 Ryan Powell */ #ifndef _NIMBLE_PORT_H #define _NIMBLE_PORT_H diff --git a/src/port/src/esp_nimble_mem.c b/src/port/src/esp_nimble_mem.c index ae2a69c2..a26e9b2f 100644 --- a/src/port/src/esp_nimble_mem.c +++ b/src/port/src/esp_nimble_mem.c @@ -19,8 +19,6 @@ * under the License. */ - /* Modifications copyright (C) 2020 Ryan Powell */ - #include "esp_attr.h" #include "esp_heap_caps.h" #include "nimconfig.h" @@ -32,6 +30,8 @@ IRAM_ATTR void *nimble_platform_mem_malloc(size_t size) return heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL return heap_caps_malloc(size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #else return malloc(size); #endif @@ -43,6 +43,8 @@ IRAM_ATTR void *nimble_platform_mem_calloc(size_t n, size_t size) return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + return heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #else return calloc(n, size); #endif @@ -51,4 +53,4 @@ IRAM_ATTR void *nimble_platform_mem_calloc(size_t n, size_t size) IRAM_ATTR void nimble_platform_mem_free(void *ptr) { heap_caps_free(ptr); -} \ No newline at end of file +}