You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2019/12/20 08:36:51 UTC
[mynewt-nimble] 01/04: nimble/ll: Use flags for tracking IRKs
presence in RL
This is an automated email from the ASF dual-hosted git repository.
janc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 7b2993fd9f3c322f763f9129c151e7756b2a2881
Author: Szymon Janc <sz...@codecoup.pl>
AuthorDate: Wed Dec 18 11:19:27 2019 +0100
nimble/ll: Use flags for tracking IRKs presence in RL
This makes sure we won't be generating RPAs from all zero IRKs.
---
.../controller/include/controller/ble_ll_resolv.h | 13 +++--
nimble/controller/src/ble_ll_adv.c | 2 +-
nimble/controller/src/ble_ll_conn.c | 11 ++--
nimble/controller/src/ble_ll_resolv.c | 67 +++++++++++++---------
nimble/controller/src/ble_ll_scan.c | 2 +-
5 files changed, 54 insertions(+), 41 deletions(-)
diff --git a/nimble/controller/include/controller/ble_ll_resolv.h b/nimble/controller/include/controller/ble_ll_resolv.h
index f9dc397..228e0a3 100644
--- a/nimble/controller/include/controller/ble_ll_resolv.h
+++ b/nimble/controller/include/controller/ble_ll_resolv.h
@@ -29,13 +29,16 @@ extern "C" {
* The identity address is stored in little endian format.
* The local rpa is stored in little endian format.
* The IRKs are stored in big endian format.
+ *
+ * Note:
+ * rl_local_irk and rl_peer_irk need to be word aligned
*/
struct ble_ll_resolv_entry
{
uint8_t rl_addr_type;
- uint8_t rl_reserved;
uint8_t rl_priv_mode;
- uint8_t _pad;
+ uint8_t rl_has_local;
+ uint8_t rl_has_peer;
uint8_t rl_local_irk[16];
uint8_t rl_peer_irk[16];
uint8_t rl_identity_addr[BLE_DEV_ADDR_LEN];
@@ -69,15 +72,15 @@ int ble_ll_resolv_local_addr_rd(const uint8_t *cmdbuf, uint8_t len,
struct ble_ll_resolv_entry *
ble_ll_resolv_list_find(const uint8_t *addr, uint8_t addr_type);
-/* Called to determine if the IRK is all zero. */
-int ble_ll_resolv_irk_nonzero(const uint8_t *irk);
-
/* Returns true if address resolution is enabled */
uint8_t ble_ll_resolv_enabled(void);
/* Reset private address resolution */
void ble_ll_resolv_list_reset(void);
+/* Generate local or peer RPA. It is up to caller to make sure required IRK
+ * is present on RL
+ */
void ble_ll_resolv_get_priv_addr(struct ble_ll_resolv_entry *rl, int local,
uint8_t *addr);
diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c
index 22cd559..2c8363e 100644
--- a/nimble/controller/src/ble_ll_adv.c
+++ b/nimble/controller/src/ble_ll_adv.c
@@ -4022,7 +4022,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
/* Verify privacy mode */
rl = ble_ll_resolv_list_find(peer, peer_addr_type);
if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
- ble_ll_resolv_irk_nonzero(rl->rl_peer_irk)) {
+ rl->rl_has_peer) {
return -1;
}
}
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index 98fe9b7..b578ab7 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -2579,7 +2579,7 @@ ble_ll_conn_connect_ind_prepare(struct ble_ll_conn_sm *connsm,
* from resolving list entry. In other case, we need to use our identity
* address (see Core 5.0, Vol 6, Part B, section 6.4).
*/
- if (rl) {
+ if (rl && rl->rl_has_local) {
hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
ble_ll_resolv_get_priv_addr(rl, 1, pdu_data->inita);
addr = NULL;
@@ -2634,7 +2634,7 @@ ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva, int index)
if (ble_ll_resolv_enabled()) {
rl = ble_ll_resolv_list_find(adva, addr_type);
if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
- ble_ll_resolv_irk_nonzero(rl->rl_peer_irk)) {
+ rl->rl_has_peer) {
return 0;
}
}
@@ -3165,9 +3165,8 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
resolved = 1;
/* Assure privacy */
- if ((rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
- init_addr && !inita_is_rpa &&
- ble_ll_resolv_irk_nonzero(rl->rl_local_irk)) {
+ if ((rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) && init_addr &&
+ !inita_is_rpa && rl->rl_has_local) {
goto init_rx_isr_exit;
}
@@ -3216,7 +3215,7 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
*/
if (rl && !inita_is_rpa &&
(rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
- ble_ll_resolv_irk_nonzero(rl->rl_local_irk)) {
+ rl->rl_has_local) {
goto init_rx_isr_exit;
}
diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c
index c35cc33..c8d7bfb 100644
--- a/nimble/controller/src/ble_ll_resolv.c
+++ b/nimble/controller/src/ble_ll_resolv.c
@@ -138,13 +138,17 @@ ble_ll_resolv_rpa_timer_cb(struct ble_npl_event *ev)
rl = &g_ble_ll_resolv_list[0];
for (i = 0; i < g_ble_ll_resolv_data.rl_cnt; ++i) {
- OS_ENTER_CRITICAL(sr);
- ble_ll_resolv_gen_priv_addr(rl, 1);
- OS_EXIT_CRITICAL(sr);
+ if (rl->rl_has_local) {
+ OS_ENTER_CRITICAL(sr);
+ ble_ll_resolv_gen_priv_addr(rl, 1);
+ OS_EXIT_CRITICAL(sr);
+ }
- OS_ENTER_CRITICAL(sr);
- ble_ll_resolv_gen_priv_addr(rl, 0);
- OS_EXIT_CRITICAL(sr);
+ if (rl->rl_has_peer) {
+ OS_ENTER_CRITICAL(sr);
+ ble_ll_resolv_gen_priv_addr(rl, 0);
+ OS_EXIT_CRITICAL(sr);
+ }
++rl;
}
ble_npl_callout_reset(&g_ble_ll_resolv_data.rpa_timer,
@@ -160,7 +164,7 @@ ble_ll_resolv_rpa_timer_cb(struct ble_npl_event *ev)
*
* @return int 0: IRK is zero . 1: IRK has non-zero value.
*/
-int
+static int
ble_ll_resolv_irk_nonzero(const uint8_t *irk)
{
int i;
@@ -319,28 +323,41 @@ ble_ll_resolv_list_add(const uint8_t *cmdbuf, uint8_t len)
memset (rl, 0, sizeof(*rl));
rl->rl_addr_type = cmd->peer_addr_type;
memcpy(rl->rl_identity_addr, cmd->peer_id_addr, BLE_DEV_ADDR_LEN);
- swap_buf(rl->rl_peer_irk, cmd->peer_irk, 16);
- swap_buf(rl->rl_local_irk, cmd->local_irk, 16);
+
+ if (ble_ll_resolv_irk_nonzero(cmd->peer_irk)) {
+ swap_buf(rl->rl_peer_irk, cmd->peer_irk, 16);
+ rl->rl_has_peer = 1;
+
+ /* generate peer RPA now, those will be updated by timer when
+ * resolution is enabled
+ */
+ ble_ll_resolv_gen_priv_addr(rl, 0);
+ }
+
+ if (ble_ll_resolv_irk_nonzero(cmd->local_irk)) {
+ swap_buf(rl->rl_local_irk, cmd->local_irk, 16);
+ rl->rl_has_local = 1;
+
+ /* generate local RPA now, those will be updated by timer when
+ * resolution is enabled
+ */
+ ble_ll_resolv_gen_priv_addr(rl, 1);
+ }
/* By default use privacy network mode */
rl->rl_priv_mode = BLE_HCI_PRIVACY_NETWORK;
- /* generate a local and peer RPAs now, those will be updated by timer
- * when resolution is enabled
- */
- ble_ll_resolv_gen_priv_addr(rl, 1);
- ble_ll_resolv_gen_priv_addr(rl, 0);
- g_ble_ll_resolv_data.rl_cnt++;
-
/* Add peers IRKs to HW resolving list. Should always succeed since we
* already checked if there is room for it.
*/
- if (ble_ll_resolv_irk_nonzero(cmd->peer_irk)) {
+ if (rl->rl_has_peer) {
rc = ble_hw_resolv_list_add(rl->rl_peer_irk);
BLE_LL_ASSERT(rc == BLE_ERR_SUCCESS);
g_ble_ll_resolv_data.rl_cnt_hw++;
}
+ g_ble_ll_resolv_data.rl_cnt++;
+
return rc;
}
@@ -567,8 +584,10 @@ ble_ll_resolv_get_priv_addr(struct ble_ll_resolv_entry *rl, int local,
OS_ENTER_CRITICAL(sr);
if (local) {
+ BLE_LL_ASSERT(rl->rl_has_local);
memcpy(addr, rl->rl_local_rpa, BLE_DEV_ADDR_LEN);
} else {
+ BLE_LL_ASSERT(rl->rl_has_peer);
memcpy(addr, rl->rl_peer_rpa, BLE_DEV_ADDR_LEN);
}
@@ -611,25 +630,17 @@ ble_ll_resolv_set_local_rpa(int index, uint8_t *rpa)
int
ble_ll_resolv_gen_rpa(uint8_t *addr, uint8_t addr_type, uint8_t *rpa, int local)
{
- int rc;
- uint8_t *irk;
struct ble_ll_resolv_entry *rl;
- rc = 0;
rl = ble_ll_resolv_list_find(addr, addr_type);
if (rl) {
- if (local) {
- irk = rl->rl_local_irk;
- } else {
- irk = rl->rl_peer_irk;
- }
- if (ble_ll_resolv_irk_nonzero(irk)) {
+ if ((local && rl->rl_has_local) || (!local && rl->rl_has_peer)) {
ble_ll_resolv_get_priv_addr(rl, local, rpa);
- rc = 1;
+ return 1;
}
}
- return rc;
+ return 0;
}
/**
diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 150ac33..d0ca915 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -365,7 +365,7 @@ ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, uint8_t *adv_addr,
* being tracked when doing an active scan (see Core 5.0, Vol 6, Part B,
* section 6.3).
*/
- if (rl) {
+ if (rl && rl->rl_has_local) {
ble_ll_resolv_get_priv_addr(rl, 1, rpa);
scana = rpa;
} else {