From 6d6590678958d37050da28f65ff88fb5d4214bdc Mon Sep 17 00:00:00 2001 From: Andrej Date: Wed, 15 Apr 2020 02:27:27 +0200 Subject: [PATCH 01/13] porting: use macros for log level filtering This reduces the size of the compiled binary by 7856 bytes. --- porting/nimble/include/modlog/modlog.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/porting/nimble/include/modlog/modlog.h b/porting/nimble/include/modlog/modlog.h index 55b6b3247..fc063b773 100644 --- a/porting/nimble/include/modlog/modlog.h +++ b/porting/nimble/include/modlog/modlog.h @@ -41,20 +41,24 @@ modlog_dummy(const char *msg, ...) #endif #ifdef ESP_PLATFORM +#define MODLOG_ESP_LOCAL(level, ml_msg_, ...) do { \ + if (LOG_LOCAL_LEVEL >= level) esp_log_write(level, "NimBLE", ml_msg_, ##__VA_ARGS__); \ +} while(0) + #define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_DEBUG, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_DEBUG, ml_msg_, ##__VA_ARGS__) #define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_INFO, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_INFO, ml_msg_, ##__VA_ARGS__) #define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_WARN, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_WARN, ml_msg_, ##__VA_ARGS__) #define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) #define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) #else From 69478c90ea10bc6c7836e954badbdab5d63a7ece Mon Sep 17 00:00:00 2001 From: freddie Date: Sun, 15 Dec 2019 04:37:44 +0800 Subject: [PATCH 02/13] nimble/host: Fix NULL pointer passed as a parameter --- nimble/host/src/ble_hs_hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index 94126679c..92ffde8fd 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -240,7 +240,7 @@ ble_hs_hci_process_ack(uint16_t expected_opcode, } if (rc == 0) { - if (params_buf == NULL) { + if (params_buf == NULL || out_ack->bha_params == NULL) { out_ack->bha_params_len = 0; } else { if (out_ack->bha_params_len > params_buf_len) { From a8da3e9215f71ff8ffc0fab0e9126c2ad5ac5987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Fri, 20 Dec 2019 15:14:55 +0100 Subject: [PATCH 03/13] nimble/host: Fail pairing when received unexpected pairing request According to spec, after pairing req/rsp we should proceed to next step of the pairing procedure. This means that we should not restart the procedure if another one is already in progress. This patch fixes this issue by aborting the proc and sending pairing failed to peer. --- nimble/host/src/ble_sm.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index e57562519..04f38b4a5 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1796,8 +1796,21 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, */ proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, -1, &prev); if (proc != NULL) { - /* Pairing already in progress; abort old procedure and start new. */ - /* XXX: Check the spec on this. */ + /* Fail if procedure is in progress unless we sent a slave security + * request to peer. + */ + if (proc->state != BLE_SM_PROC_STATE_SEC_REQ) { + res->sm_err = BLE_SM_ERR_UNSPECIFIED; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED); + ble_hs_unlock(); + return; + } + + /* Remove the procedure because it was allocated when + * sending the Slave Security Request and it will be allocated + * again later in this method. We should probably refactor this + * in the future. + */ ble_sm_proc_remove(proc, prev); ble_sm_proc_free(proc); } From 275caf975ba9c8b5647e7c2432e040398e2fbce8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 13 Jan 2020 22:59:17 +0100 Subject: [PATCH 04/13] 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/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 04f38b4a5..0ff57ae5d 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2045,7 +2045,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; From 6814781c11d2a542c80f19fd566c7e26c0b32136 Mon Sep 17 00:00:00 2001 From: Zac Bond Date: Wed, 25 Mar 2020 10:33:08 -0400 Subject: [PATCH 05/13] nimble/gap: Remove notification for update process timeout. The connection parameter update process has a hard-coded 40-second timeout, but in reality, the time it takes to complete a connection parameter might take longer, as it depends on the connection interval and when controller deciders to do it. This patch changes meaning of this 40 sec timer to be only a guard so the application does not perform too many connection update parameter requests. Now when timeout fires, application will not be notified about that and link will not be dropped. --- nimble/host/src/ble_gap.c | 1 - nimble/host/test/src/ble_gap_test.c | 67 ----------------------------- 2 files changed, 68 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index e24899141..1eb8480aa 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1853,7 +1853,6 @@ ble_gap_update_timer(void) ble_hs_unlock(); if (entry != NULL) { - ble_gap_update_notify(conn_handle, BLE_HS_ETIMEOUT); ble_gap_update_entry_free(entry); } } while (entry != NULL); diff --git a/nimble/host/test/src/ble_gap_test.c b/nimble/host/test/src/ble_gap_test.c index 4902821ad..2de4351b4 100644 --- a/nimble/host/test/src/ble_gap_test.c +++ b/nimble/host/test/src/ble_gap_test.c @@ -2033,70 +2033,6 @@ ble_gap_test_util_update_l2cap(struct ble_gap_upd_params *params, peer_addr, 6) == 0); } -static void -ble_gap_test_util_update_no_l2cap_tmo(struct ble_gap_upd_params *params, - int master) -{ - struct ble_hs_conn *conn; - int rc; - - uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 }; - - ble_gap_test_util_init(); - - ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb, - NULL); - - if (!master) { - ble_hs_lock(); - conn = ble_hs_conn_find(2); - TEST_ASSERT_FATAL(conn != NULL); - conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER; - ble_hs_unlock(); - } - - /* Erase callback info reported during connection establishment; we only - * care about updates. - */ - ble_gap_test_util_reset_cb_info(); - - TEST_ASSERT(!ble_gap_master_in_progress()); - - rc = ble_hs_test_util_conn_update(2, params, 0); - TEST_ASSERT(rc == 0); - TEST_ASSERT(!ble_gap_master_in_progress()); - - /* Verify tx of connection update command. */ - ble_gap_test_util_verify_tx_update_conn(params); - - /* Ensure no update event reported. */ - TEST_ASSERT(ble_gap_test_event.type == 0xff); - - /* Advance 39 seconds; ensure no timeout reported. */ - os_time_advance(39 * OS_TICKS_PER_SEC); - ble_gap_timer(); - TEST_ASSERT(ble_gap_test_event.type == 0xff); - - /* Advance 40th second; ensure timeout reported. */ - os_time_advance(1 * OS_TICKS_PER_SEC); - - /* Timeout will result in a terminate HCI command being sent; schedule ack - * from controller. - */ - ble_hs_test_util_hci_ack_set_disconnect(0); - - ble_gap_timer(); - - /* Verify terminate was sent. */ - ble_gap_test_util_verify_tx_disconnect(); - - TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE); - TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_ETIMEOUT); - TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2); - TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val, - peer_addr, 6) == 0); -} - static void ble_gap_test_util_update_l2cap_tmo(struct ble_gap_upd_params *params, uint8_t hci_status, uint8_t event_status, @@ -2967,9 +2903,6 @@ TEST_CASE_SELF(ble_gap_test_case_update_timeout) .max_ce_len = 456, }; - /* No L2CAP. */ - ble_gap_test_util_update_no_l2cap_tmo(¶ms, 1); - /* L2CAP - Local unsupported; L2CAP timeout. */ ble_gap_test_util_update_l2cap_tmo(¶ms, BLE_ERR_UNKNOWN_HCI_CMD, 0, 0); From be6c607dda6f34277691872fa9cab0504dfdc1ec Mon Sep 17 00:00:00 2001 From: Prasad Alatkar Date: Wed, 1 Apr 2020 00:08:29 +0530 Subject: [PATCH 06/13] 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 | 14 ++++++++------ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index a23cdd458..271340f5c 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -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 diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 1eb8480aa..b9bf8dece 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -5311,6 +5311,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/nimble/host/src/ble_store_util.c b/nimble/host/src/ble_store_util.c index 05c22176c..73c71d93b 100644 --- a/nimble/host/src/ble_store_util.c +++ b/nimble/host/src/ble_store_util.c @@ -253,13 +253,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(); + 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; + default: + return BLE_HS_EUNKNOWN; } case BLE_STORE_EVENT_FULL: From 795701ba86c90807fe0dffa2e8789fb6e2043e54 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 07/13] 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/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b9bf8dece..09ae27047 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -5362,7 +5362,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; @@ -5378,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/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index c80872898..90c32e22a 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/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/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 0ff57ae5d..5988e8776 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -947,7 +947,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 && @@ -1201,6 +1201,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); } @@ -2475,7 +2476,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/nimble/host/src/ble_sm_priv.h b/nimble/host/src/ble_sm_priv.h index 74205bd0c..bbb4b03ae 100644 --- a/nimble/host/src/ble_sm_priv.h +++ b/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) From 9c4944d471dec035e86a77feb1c84a1693bdf8d5 Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 18 Apr 2020 20:42:41 -0600 Subject: [PATCH 08/13] 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/nimble/host/src/ble_att_cmd.c b/nimble/host/src/ble_att_cmd.c index 999f57a2b..bad192df5 100644 --- a/nimble/host/src/ble_att_cmd.c +++ b/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/nimble/host/src/ble_hs_misc.c b/nimble/host/src/ble_hs_misc.c index e6bb3825b..00200d316 100644 --- a/nimble/host/src/ble_hs_misc.c +++ b/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/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index 27bf904b7..49269546c 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/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/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 07a338ae6..bc73d954a 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/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/nimble/host/src/ble_l2cap_sig_cmd.c b/nimble/host/src/ble_l2cap_sig_cmd.c index 366dde625..510420f09 100644 --- a/nimble/host/src/ble_l2cap_sig_cmd.c +++ b/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/nimble/host/src/ble_sm_cmd.c b/nimble/host/src/ble_sm_cmd.c index b5e674e75..e12e109d5 100644 --- a/nimble/host/src/ble_sm_cmd.c +++ b/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 From 612e31625f0c5f1e45eb4e28b4a4b748bef23548 Mon Sep 17 00:00:00 2001 From: h2zero Date: Fri, 24 Apr 2020 08:25:42 -0600 Subject: [PATCH 09/13] 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/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 271340f5c..b4dbdb051 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/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 From 793dd3d80167a133c85851a2ac09283d3d7e6b12 Mon Sep 17 00:00:00 2001 From: Prasad Alatkar Date: Tue, 28 Apr 2020 23:28:38 +0530 Subject: [PATCH 10/13] NimBLE store: Fix bug in NVS while retrieving matching index in get_nvs_db_attribute --- nimble/host/store/config/src/ble_store_nvs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/store/config/src/ble_store_nvs.c b/nimble/host/store/config/src/ble_store_nvs.c index 8cbb231b6..6a72e667a 100644 --- a/nimble/host/store/config/src/ble_store_nvs.c +++ b/nimble/host/store/config/src/ble_store_nvs.c @@ -208,11 +208,11 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) err = get_nvs_matching_index(&p_dev_rec, value, num_value, sizeof(struct ble_hs_dev_records)); } else { - if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { + if (obj_type != BLE_STORE_OBJ_TYPE_CCCD) { err = get_nvs_matching_index(&cur.sec, value, num_value, sizeof(struct ble_store_value_sec)); } else { - err = get_nvs_matching_index(&cur.sec, value, num_value, + err = get_nvs_matching_index(&cur.cccd, value, num_value, sizeof(struct ble_store_value_cccd)); } } From 7f53712e7a82a2db6f3cd5569a88b180e9970216 Mon Sep 17 00:00:00 2001 From: Prasad Alatkar Date: Tue, 28 Apr 2020 23:40:40 +0530 Subject: [PATCH 11/13] NimBLE : Change peer_addr type to PUBLIC in case of Host based privacy - When Identity of peer is resolved and peer address is RPA then NimBLE stack changes the peer_addr type to PUBLIC_ID(0x02); in Host based privacy it should not be done as it can result in mismatch while comparing stored addresses especially in case of CCCD storage. --- nimble/host/src/ble_sm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 5988e8776..4787c6202 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -538,6 +538,11 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) case BLE_ADDR_PUBLIC: case BLE_ADDR_PUBLIC_ID: conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC_ID; +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + /* In case of Host based privacy, we should not be changing + * peer address type to BLE_ADDR_PUBLIC_ID */ + conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC; +#endif break; case BLE_ADDR_RANDOM: From 095c14c9f4f37452f69aafed6cab2f0e69cc8d5b Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 16 Apr 2020 10:30:50 -0600 Subject: [PATCH 12/13] Allow host to resolve peer RPA without using local RPA. --- nimble/host/src/ble_hs_conn.c | 19 ++++++++----------- nimble/host/src/ble_hs_hci_evt.c | 13 ++++--------- nimble/host/src/ble_sm.c | 31 ++++++++++++++----------------- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index 035150b98..eb65e3288 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/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); + 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; - 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; + 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/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 43cb5b580..78383dff0 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/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/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 4787c6202..6fa6f00c4 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -553,26 +553,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 8c2005bb3d4f0c948234f1d8b1242ec43c9593d7 Mon Sep 17 00:00:00 2001 From: h2zero Date: Fri, 1 May 2020 21:54:46 -0600 Subject: [PATCH 13/13] Remove resolving RPA in advertisement report. --- nimble/host/src/ble_hs_hci_evt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 78383dff0..30dc92f28 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/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;