From c35e5fde8bf94638e8680b318c7ded62934f6d71 Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 18 Apr 2020 10:46:43 -0600 Subject: [PATCH 01/11] Resync NimBLE core to upstream master. esp-idf @be8c847 esp-nimble@0a1604a --- src/console/console.h | 2 +- src/esp-hci/src/esp_nimble_hci.c | 2 +- src/esp_nimble_cfg.h | 4 +- src/esp_nimble_hci.h | 2 +- src/esp_nimble_mem.h | 3 +- src/host/ble_gap.h | 14 -- src/host/ble_store.h | 2 - src/nimble/host/mesh/src/src/ble_gap_priv.h | 1 + src/nimble/host/mesh/src/src/ble_hs_id_priv.h | 4 + .../host/mesh/src/src/ble_hs_pvcy_priv.h | 3 + .../host/mesh/src/src/ble_hs_resolv_priv.h | 108 +++++++++++ src/nimble/host/mesh/src/src/ble_sm_priv.h | 4 + src/nimble/host/src/ble_gap.c | 47 +---- src/nimble/host/src/ble_gatts.c | 37 ++-- src/nimble/host/src/ble_hs_conn.c | 21 +- src/nimble/host/src/ble_hs_hci_evt.c | 19 +- src/nimble/host/src/ble_sm.c | 36 ++-- src/nimble/host/src/ble_store_util.c | 183 ++---------------- src/nimble/nimble_npl.h | 3 +- src/nimble/nimble_port.h | 1 - src/port/src/esp_nimble_mem.c | 8 +- 21 files changed, 209 insertions(+), 295 deletions(-) create mode 100644 src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h 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..a23cdd45 100644 --- a/src/host/ble_gap.h +++ b/src/host/ble_gap.h @@ -1886,20 +1886,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_gap.c b/src/nimble/host/src/ble_gap.c index e6564012..e2489914 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 0; } rc = ble_gap_unpair(&oldest_peer_id_addr); @@ -5315,41 +5312,6 @@ ble_gap_unpair_oldest_peer(void) return 0; } -int -ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer) -{ - ble_addr_t oldest_peer_id_addr[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)); - if (rc != 0) { - return rc; - } - - if (num_peers == 0) { - return BLE_HS_ENOENT; - } - - for (i = 0; i < num_peers; i++) { - if (memcmp(curr_peer, &oldest_peer_id_addr[i], sizeof (ble_addr_t)) != 0) { - break; - } - } - - if (i < num_peers) { - rc = ble_gap_unpair(&oldest_peer_id_addr[i]); - if (rc != 0) { - return rc; - } - } else { - return BLE_HS_ENOMEM; - } - - return 0; -} - void ble_gap_passkey_event(uint16_t conn_handle, struct ble_gap_passkey_params *passkey_params) @@ -5387,12 +5349,7 @@ 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 (status == 0) { if (security_restored) { ble_gatts_bonding_restored(conn_handle); } else { 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..035150b9 100644 --- a/src/nimble/host/src/ble_hs_conn.c +++ b/src/nimble/host/src/ble_hs_conn.c @@ -415,16 +415,17 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, 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); - - 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); + 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; /* 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 3f7c5d79..43cb5b58 100644 --- a/src/nimble/host/src/ble_hs_hci_evt.c +++ b/src/nimble/host/src/ble_hs_hci_evt.c @@ -332,19 +332,16 @@ 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); + 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); diff --git a/src/nimble/host/src/ble_sm.c b/src/nimble/host/src/ble_sm.c index 1bc55a62..e5756251 100644 --- a/src/nimble/host/src/ble_sm.c +++ b/src/nimble/host/src/ble_sm.c @@ -548,23 +548,26 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) identity_ev = 1; #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) - 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 (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); + } } - } - 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 } @@ -2029,10 +2032,7 @@ 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, - !!(proc->flags & BLE_SM_PROC_F_AUTHENTICATED), - !!(proc->flags & BLE_SM_PROC_F_BONDING), - proc->key_size); + ble_sm_update_sec_state(proc->conn_handle, 1, 0, 1, proc->key_size); proc->state = BLE_SM_PROC_STATE_NONE; res->app_status = 0; diff --git a/src/nimble/host/src/ble_store_util.c b/src/nimble/host/src/ble_store_util.c index 9813a865..05c22176 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,16 @@ 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_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_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 +} From e01c2cbc65788e0b5e190497924f0f78465e6c0d Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 18 Apr 2020 10:59:36 -0600 Subject: [PATCH 02/11] Patch no cccd store unbonded esp-nimble#9 --- src/nimble/host/src/ble_gatts.c | 37 +++++++++++++++++---------------- src/nimble/host/src/ble_sm.c | 5 ++++- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/nimble/host/src/ble_gatts.c b/src/nimble/host/src/ble_gatts.c index fccf1027..e84361cb 100644 --- a/src/nimble/host/src/ble_gatts.c +++ b/src/nimble/host/src/ble_gatts.c @@ -1689,29 +1689,30 @@ 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); - cccd_value.peer_addr = conn->bhc_peer_addr; - gatt_srv = &conn->bhc_gatt_svr; + if (conn->bhc_sec_state.bonded) { + 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_sm.c b/src/nimble/host/src/ble_sm.c index e5756251..edb8a862 100644 --- a/src/nimble/host/src/ble_sm.c +++ b/src/nimble/host/src/ble_sm.c @@ -2032,7 +2032,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 030b07ef57b927040612996e11bb8ab8238bb24e Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 18 Apr 2020 12:49:48 -0600 Subject: [PATCH 03/11] Apply resolve RPA with no local RPA patch. esp-nimble#7 --- src/nimble/host/src/ble_hs_conn.c | 18 ++++++++-------- src/nimble/host/src/ble_hs_hci_evt.c | 17 ++++++++------- src/nimble/host/src/ble_sm.c | 31 +++++++++++++--------------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/nimble/host/src/ble_hs_conn.c b/src/nimble/host/src/ble_hs_conn.c index 035150b9..9942b123 100644 --- a/src/nimble/host/src/ble_hs_conn.c +++ b/src/nimble/host/src/ble_hs_conn.c @@ -415,17 +415,17 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, 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); + 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_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; - 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 43cb5b58..4cb8a46d 100644 --- a/src/nimble/host/src/ble_hs_hci_evt.c +++ b/src/nimble/host/src/ble_hs_hci_evt.c @@ -332,16 +332,19 @@ 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); + 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); diff --git a/src/nimble/host/src/ble_sm.c b/src/nimble/host/src/ble_sm.c index edb8a862..1bc55a62 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 b40753cf2304b9e425a85a5b47493a4f4b574168 Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 18 Apr 2020 13:04:36 -0600 Subject: [PATCH 04/11] Apply CCCD limit round robin patch. mynewt-nimble #790 --- src/host/ble_gap.h | 14 ++++++++++++ src/nimble/host/src/ble_gap.c | 32 +++++++++++++++++++++++++++- src/nimble/host/src/ble_store_util.c | 16 ++++++++------ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/host/ble_gap.h b/src/host/ble_gap.h index a23cdd45..271340f5 100644 --- a/src/host/ble_gap.h +++ b/src/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/src/nimble/host/src/ble_gap.c b/src/nimble/host/src/ble_gap.c index e2489914..00f26288 100644 --- a/src/nimble/host/src/ble_gap.c +++ b/src/nimble/host/src/ble_gap.c @@ -5301,7 +5301,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); @@ -5312,6 +5312,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 05c22176..73c71d93 100644 --- a/src/nimble/host/src/ble_store_util.c +++ b/src/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(); - - 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: From 249f7a7d4cb14a36383b873942e2e0aecb569548 Mon Sep 17 00:00:00 2001 From: h2zero Date: Sun, 19 Apr 2020 20:54:19 -0600 Subject: [PATCH 05/11] Apply ble_hs_misc_conn_chan_find_reqd() null pointer exception fix. mynewt-nimble#802 --- src/nimble/host/src/ble_att_cmd.c | 7 +++---- src/nimble/host/src/ble_hs_misc.c | 5 +++-- src/nimble/host/src/ble_hs_priv.h | 6 +++--- src/nimble/host/src/ble_l2cap_sig.c | 9 +++++++-- src/nimble/host/src/ble_l2cap_sig_cmd.c | 8 +++++--- src/nimble/host/src/ble_sm_cmd.c | 11 ++++++++--- 6 files changed, 29 insertions(+), 17 deletions(-) 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_hs_misc.c b/src/nimble/host/src/ble_hs_misc.c index e6bb3825..0270ee11 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,6 @@ 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 (out_conn != NULL) { *out_conn = conn; @@ -74,6 +73,8 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, if (out_chan != NULL) { *out_chan = chan; } + + return rc; } 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_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 From 6fe1f80ec76e89f9cf5c46a28dcfa506ce25744b Mon Sep 17 00:00:00 2001 From: h2zero Date: Wed, 22 Apr 2020 20:47:37 -0600 Subject: [PATCH 06/11] Remove un-merged patches + apply merged versions. Removed previouly un-merged patches for unbonded CCCD storage and `ble_hs_misc_conn_chan_find_reqd()` null pointer exception fix. Applied offically merged versions: mynewt-nimble #730 - nimble/host: Fix setting connection flags after pairing mynewt-nimble #804 - nimble/gap: Fix storing CCC for bonded devices. mynewt-nimble #802 - nimble/host: Add return parameter to the ble_hs_misc_conn_chan_find_reqd() Retaining un-merged: esp-nimble #7 - Allow host to resolve peer RPA without using local RPA. --- src/nimble/host/src/ble_gap.c | 27 ++++++++++++++++------ src/nimble/host/src/ble_gap_priv.h | 2 +- src/nimble/host/src/ble_gatts.c | 37 +++++++++++++++--------------- src/nimble/host/src/ble_hs_misc.c | 5 +++- src/nimble/host/src/ble_sm.c | 5 ++-- src/nimble/host/src/ble_sm_priv.h | 8 +++---- 6 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/nimble/host/src/ble_gap.c b/src/nimble/host/src/ble_gap.c index 00f26288..6cce77df 100644 --- a/src/nimble/host/src/ble_gap.c +++ b/src/nimble/host/src/ble_gap.c @@ -5363,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; @@ -5379,12 +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); - 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 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_misc.c b/src/nimble/host/src/ble_hs_misc.c index 0270ee11..00200d31 100644 --- a/src/nimble/host/src/ble_hs_misc.c +++ b/src/nimble/host/src/ble_hs_misc.c @@ -66,6 +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); + if (rc != 0) { + return rc; + } if (out_conn != NULL) { *out_conn = conn; @@ -74,7 +77,7 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, *out_chan = chan; } - return rc; + return 0; } uint8_t 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_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) From 26fa2b1861b5dcd1870b212f8cde8d9ddecefda0 Mon Sep 17 00:00:00 2001 From: h2zero Date: Wed, 22 Apr 2020 21:10:28 -0600 Subject: [PATCH 07/11] Create applied_patches folder + add patch files used. The NimBLE core library that this project is based on has been patched to improve functionality. This new folder contains the patch files applied that have not yet been merged offically into the esp-nimble fork. The offical-merged folder contains patches that are offically applied to the upstream NimBLE core, the un-merged folder contains the patches not yet merged anywhere. --- .../official-merged/nimble#730.patch | 25 +++ .../official-merged/nimble#790.patch | 130 +++++++++++++++ .../official-merged/nimble#802.patch | 153 ++++++++++++++++++ .../official-merged/nimble#804.patch | 135 ++++++++++++++++ applied_patches/un-merged/esp-nimble#7.patch | 121 ++++++++++++++ 5 files changed, 564 insertions(+) create mode 100644 applied_patches/official-merged/nimble#730.patch create mode 100644 applied_patches/official-merged/nimble#790.patch create mode 100644 applied_patches/official-merged/nimble#802.patch create mode 100644 applied_patches/official-merged/nimble#804.patch create mode 100644 applied_patches/un-merged/esp-nimble#7.patch 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/un-merged/esp-nimble#7.patch b/applied_patches/un-merged/esp-nimble#7.patch new file mode 100644 index 00000000..e2d136f5 --- /dev/null +++ b/applied_patches/un-merged/esp-nimble#7.patch @@ -0,0 +1,121 @@ +From 97485b084c9d38160553101bd68eedb5f47f9fc3 Mon Sep 17 00:00:00 2001 +From: h2zero +Date: Thu, 16 Apr 2020 10:30:50 -0600 +Subject: [PATCH] Allow host to resolve peer RPA without using local RPA. + +--- + nimble/host/src/ble_hs_conn.c | 22 +++++++++++----------- + nimble/host/src/ble_hs_hci_evt.c | 19 +++++++++++-------- + nimble/host/src/ble_sm.c | 31 ++++++++++++++----------------- + 3 files changed, 36 insertions(+), 36 deletions(-) + +diff --git a/src/nimble/host/src/ble_hs_conn.c b/src/nimble/host/src/ble_hs_conn.c +index 035150b98..c3294e9c1 100644 +--- a/src/nimble/host/src/ble_hs_conn.c ++++ b/src/nimble/host/src/ble_hs_conn.c +@@ -415,17 +415,17 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, + 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; ++ ++ 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_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/src/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/host/src/ble_hs_hci_evt.c +index 43cb5b580..3f7c5d791 100644 +--- a/src/nimble/host/src/ble_hs_hci_evt.c ++++ b/src/nimble/host/src/ble_hs_hci_evt.c +@@ -332,16 +332,19 @@ 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); ++ 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); +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 8718701b5765a0a42b571774b6b7a908d0a998c4 Mon Sep 17 00:00:00 2001 From: h2zero Date: Wed, 22 Apr 2020 21:30:25 -0600 Subject: [PATCH 08/11] Patch connection event defaults for improved performance/reliability. The NimBLE controller does not make use of the Minimum and Maximum Connection Event lengths but the ESP32 controller does. The NimBLE default values create error conditions in the ESP32 controller when connecting to multiple peers with connection intervals. This patch sets those parameters to 0 to allow the controller to manage the time window. --- applied_patches/un-merged/min-max-ce.patch | 15 +++++++++++++++ src/host/ble_gap.h | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 applied_patches/un-merged/min-max-ce.patch diff --git a/applied_patches/un-merged/min-max-ce.patch b/applied_patches/un-merged/min-max-ce.patch new file mode 100644 index 00000000..87b52858 --- /dev/null +++ b/applied_patches/un-merged/min-max-ce.patch @@ -0,0 +1,15 @@ +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/src/host/ble_gap.h b/src/host/ble_gap.h index 271340f5..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 From 0c94b40ff4a89f523da799a59a77107a41a33b8d Mon Sep 17 00:00:00 2001 From: h2zero Date: Fri, 24 Apr 2020 18:44:37 -0600 Subject: [PATCH 09/11] Update min/max_ce patch to reflect PR @ mynewt/nimble --- applied_patches/un-merged/min-max-ce.patch | 15 ------------ applied_patches/un-merged/nimble#808.patch | 28 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) delete mode 100644 applied_patches/un-merged/min-max-ce.patch create mode 100644 applied_patches/un-merged/nimble#808.patch diff --git a/applied_patches/un-merged/min-max-ce.patch b/applied_patches/un-merged/min-max-ce.patch deleted file mode 100644 index 87b52858..00000000 --- a/applied_patches/un-merged/min-max-ce.patch +++ /dev/null @@ -1,15 +0,0 @@ -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/nimble#808.patch b/applied_patches/un-merged/nimble#808.patch new file mode 100644 index 00000000..031e4ed6 --- /dev/null +++ b/applied_patches/un-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 From 4239e8916785b1084e7058e571fc5104e4e4b1f7 Mon Sep 17 00:00:00 2001 From: h2zero Date: Mon, 27 Apr 2020 12:24:24 -0600 Subject: [PATCH 10/11] Min/max CE PR was merged upstream, move patch to merged. --- applied_patches/{un-merged => official-merged}/nimble#808.patch | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename applied_patches/{un-merged => official-merged}/nimble#808.patch (100%) diff --git a/applied_patches/un-merged/nimble#808.patch b/applied_patches/official-merged/nimble#808.patch similarity index 100% rename from applied_patches/un-merged/nimble#808.patch rename to applied_patches/official-merged/nimble#808.patch From 9eca05b962d1d944a6201e54122a0cf3421f569c Mon Sep 17 00:00:00 2001 From: h2zero Date: Sat, 2 May 2020 11:48:59 -0600 Subject: [PATCH 11/11] Update "Apply resolve RPA with no local RPA patch." This updates the esp-nimble #7 patch to the latest PR. --- applied_patches/un-merged/esp-nimble#7.patch | 69 +++++++++++++------- src/nimble/host/src/ble_hs_conn.c | 5 +- src/nimble/host/src/ble_hs_hci_evt.c | 16 ----- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/applied_patches/un-merged/esp-nimble#7.patch b/applied_patches/un-merged/esp-nimble#7.patch index e2d136f5..ce51b5e9 100644 --- a/applied_patches/un-merged/esp-nimble#7.patch +++ b/applied_patches/un-merged/esp-nimble#7.patch @@ -1,19 +1,24 @@ -From 97485b084c9d38160553101bd68eedb5f47f9fc3 Mon Sep 17 00:00:00 2001 +From 42fef9c3556ecd7a9b6c4d489a4a198696381599 Mon Sep 17 00:00:00 2001 From: h2zero Date: Thu, 16 Apr 2020 10:30:50 -0600 -Subject: [PATCH] Allow host to resolve peer RPA without using local RPA. +Subject: [PATCH 1/2] Allow host to resolve peer RPA without using local RPA. --- - nimble/host/src/ble_hs_conn.c | 22 +++++++++++----------- - nimble/host/src/ble_hs_hci_evt.c | 19 +++++++++++-------- + 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, 36 insertions(+), 36 deletions(-) + 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..c3294e9c1 100644 +index 035150b98..eb65e3288 100644 --- a/src/nimble/host/src/ble_hs_conn.c +++ b/src/nimble/host/src/ble_hs_conn.c -@@ -415,17 +415,17 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, +@@ -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); @@ -21,18 +26,16 @@ index 035150b98..c3294e9c1 100644 - - 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) { -+ addrs->peer_ota_addr = conn->bhc_peer_rpa_addr; -+ //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; + @@ -43,10 +46,10 @@ index 035150b98..c3294e9c1 100644 /* 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..3f7c5d791 100644 +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,19 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) +@@ -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); @@ -58,19 +61,12 @@ index 43cb5b580..3f7c5d791 100644 - 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); -+ 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); @@ -119,3 +115,32 @@ index e57562519..dc96c76c7 100644 } #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/nimble/host/src/ble_hs_conn.c b/src/nimble/host/src/ble_hs_conn.c index 9942b123..eb65e328 100644 --- a/src/nimble/host/src/ble_hs_conn.c +++ b/src/nimble/host/src/ble_hs_conn.c @@ -410,16 +410,13 @@ 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_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; diff --git a/src/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/host/src/ble_hs_hci_evt.c index 4cb8a46d..30dc92f2 100644 --- a/src/nimble/host/src/ble_hs_hci_evt.c +++ b/src/nimble/host/src/ble_hs_hci_evt.c @@ -337,14 +337,6 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) 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;