first cut at LL privacy
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/d6bbacbd Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/d6bbacbd Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/d6bbacbd Branch: refs/heads/develop Commit: d6bbacbd95693af7bfdefef6ccdc4863dd6c53c9 Parents: 34e4509 Author: William San Filippo <[email protected]> Authored: Wed May 18 15:59:54 2016 -0700 Committer: Paul Dietrich <[email protected]> Committed: Thu Jun 2 14:12:15 2016 -0700 ---------------------------------------------------------------------- apps/bletest/src/bletest_hci.c | 32 ++ apps/bletest/src/bletest_priv.h | 4 + apps/bletest/src/main.c | 125 ++++++-- apps/bletiny/src/main.c | 2 +- .../controller/include/controller/ble_ll.h | 2 +- .../controller/include/controller/ble_ll_adv.h | 6 + .../controller/include/controller/ble_ll_conn.h | 3 + .../include/controller/ble_ll_resolv.h | 27 +- .../controller/include/controller/ble_ll_scan.h | 14 +- .../include/controller/ble_ll_whitelist.h | 2 +- net/nimble/controller/src/ble_ll.c | 16 +- net/nimble/controller/src/ble_ll_adv.c | 227 +++++++++----- net/nimble/controller/src/ble_ll_conn.c | 247 ++++++++++++---- net/nimble/controller/src/ble_ll_conn_hci.c | 100 ++++--- net/nimble/controller/src/ble_ll_conn_priv.h | 3 +- net/nimble/controller/src/ble_ll_hci.c | 2 +- net/nimble/controller/src/ble_ll_resolv.c | 148 ++++++++-- net/nimble/controller/src/ble_ll_scan.c | 296 ++++++++++++++----- net/nimble/controller/src/ble_ll_whitelist.c | 105 ++++--- net/nimble/drivers/nrf51/include/ble/xcvr.h | 6 + net/nimble/drivers/nrf51/src/ble_hw.c | 9 +- net/nimble/drivers/nrf51/src/ble_phy.c | 3 +- net/nimble/drivers/nrf52/include/ble/xcvr.h | 8 +- net/nimble/drivers/nrf52/src/ble_hw.c | 9 +- net/nimble/drivers/nrf52/src/ble_phy.c | 2 + net/nimble/host/src/host_dbg.c | 23 +- net/nimble/include/nimble/ble.h | 2 +- net/nimble/include/nimble/hci_common.h | 4 + 28 files changed, 1054 insertions(+), 373 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/apps/bletest/src/bletest_hci.c ---------------------------------------------------------------------- diff --git a/apps/bletest/src/bletest_hci.c b/apps/bletest/src/bletest_hci.c index 1eee29c..c227cc0 100755 --- a/apps/bletest/src/bletest_hci.c +++ b/apps/bletest/src/bletest_hci.c @@ -580,4 +580,36 @@ bletest_hci_le_create_connection(struct hci_create_conn *hcc) return rc; } +int +bletest_hci_le_add_resolv_list(uint8_t *local_irk, uint8_t *peer_irk, + uint8_t *peer_ident_addr, uint8_t addr_type) +{ + int rc; + struct hci_add_dev_to_resolving_list padd; + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_ADD_TO_RESOLV_LIST_LEN]; + + padd.addr_type = addr_type; + memcpy(padd.addr, peer_ident_addr, BLE_DEV_ADDR_LEN); + swap_buf(padd.local_irk, local_irk, 16); + swap_buf(padd.peer_irk, peer_irk, 16); + rc = host_hci_cmd_add_device_to_resolving_list(&padd, buf, sizeof buf); + if (!rc) { + rc = ble_hci_cmd_tx_empty_ack(buf); + } + return rc; +} + +int +bletest_hci_le_enable_resolv_list(uint8_t enable) +{ + int rc; + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADDR_RESOL_ENA_LEN]; + + + rc = host_hci_cmd_set_addr_resolution_enable(enable, buf, sizeof buf); + if (!rc) { + rc = ble_hci_cmd_tx_empty_ack(buf); + } + return rc; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/apps/bletest/src/bletest_priv.h ---------------------------------------------------------------------- diff --git a/apps/bletest/src/bletest_priv.h b/apps/bletest/src/bletest_priv.h index 4a00aef..28f3074 100644 --- a/apps/bletest/src/bletest_priv.h +++ b/apps/bletest/src/bletest_priv.h @@ -58,5 +58,9 @@ int bletest_hci_le_create_connection(struct hci_create_conn *hcc); int bletest_hci_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl, uint16_t scan_window, uint8_t own_addr_type, uint8_t filter_policy); +int bletest_hci_le_add_resolv_list(uint8_t *local_irk, uint8_t *peer_irk, + uint8_t *peer_ident_addr, uint8_t addr_type); +int bletest_hci_le_enable_resolv_list(uint8_t enable); + #endif /* H_BLETEST_PRIV_*/ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/apps/bletest/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c index 5a073c9..f4e4424 100755 --- a/apps/bletest/src/main.c +++ b/apps/bletest/src/main.c @@ -97,28 +97,38 @@ os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE]; #define BLETEST_ROLE_ADVERTISER (0) #define BLETEST_ROLE_SCANNER (1) #define BLETEST_ROLE_INITIATOR (2) -#define BLETEST_CFG_ROLE (BLETEST_ROLE_INITIATOR) -//#define BLETEST_CFG_ROLE (BLETEST_ROLE_ADVERTISER) + +//#define BLETEST_CFG_ROLE (BLETEST_ROLE_INITIATOR) +#define BLETEST_CFG_ROLE (BLETEST_ROLE_ADVERTISER) //#define BLETEST_CFG_ROLE (BLETEST_ROLE_SCANNER) -#define BLETEST_CFG_ADV_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC) + +/* Advertiser config */ +#define BLETEST_CFG_ADV_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PRIV_PUB) #define BLETEST_CFG_ADV_PEER_ADDR_TYPE (BLE_HCI_ADV_PEER_ADDR_PUBLIC) -#define BLETEST_CFG_FILT_DUP_ADV (0) +#define BLETEST_CFG_FILT_DUP_ADV (1) #define BLETEST_CFG_ADV_ITVL (60000 / BLE_HCI_ADV_ITVL) #define BLETEST_CFG_ADV_TYPE BLE_HCI_ADV_TYPE_ADV_IND #define BLETEST_CFG_ADV_FILT_POLICY (BLE_HCI_ADV_FILT_NONE) + +/* Scan config */ #define BLETEST_CFG_SCAN_ITVL (700000 / BLE_HCI_SCAN_ITVL) #define BLETEST_CFG_SCAN_WINDOW (700000 / BLE_HCI_SCAN_ITVL) -#define BLETEST_CFG_SCAN_TYPE (BLE_HCI_SCAN_TYPE_ACTIVE) +#define BLETEST_CFG_SCAN_TYPE (BLE_HCI_SCAN_TYPE_PASSIVE) +#define BLETEST_CFG_SCAN_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC) #define BLETEST_CFG_SCAN_FILT_POLICY (BLE_HCI_SCAN_FILT_NO_WL) + +/* Connection config */ #define BLETEST_CFG_CONN_ITVL (128) /* in 1.25 msec increments */ #define BLETEST_CFG_SLAVE_LATENCY (0) #define BLETEST_CFG_INIT_FILTER_POLICY (BLE_HCI_CONN_FILT_NO_WL) #define BLETEST_CFG_CONN_SPVN_TMO (1000) /* 20 seconds */ #define BLETEST_CFG_MIN_CE_LEN (6) #define BLETEST_CFG_MAX_CE_LEN (BLETEST_CFG_CONN_ITVL) -#define BLETEST_CFG_CONN_PEER_ADDR_TYPE (BLE_HCI_CONN_PEER_ADDR_PUBLIC) +#define BLETEST_CFG_CONN_PEER_ADDR_TYPE (BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT) #define BLETEST_CFG_CONN_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC) #define BLETEST_CFG_CONCURRENT_CONNS (1) + +/* Test packet config */ #define BLETEST_CFG_RAND_PKT_SIZE (1) #define BLETEST_CFG_SUGG_DEF_TXOCTETS (251) #define BLETEST_CFG_SUGG_DEF_TXTIME \ @@ -176,6 +186,18 @@ const uint8_t g_ble_ll_encrypt_test_encrypted_data[16] = 0x05, 0x8e, 0x3b, 0x8e, 0x27, 0xc2, 0xc6, 0x66 }; +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) +uint8_t g_bletest_adv_irk[16] = { + 0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, + 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b +}; + +uint8_t g_bletest_init_irk[16] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 +}; +#endif + #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1) /* LTK 0x4C68384139F574D836BCF34E9DFB01BF */ const uint8_t g_bletest_LTK[16] = @@ -242,7 +264,7 @@ bletest_inc_adv_pkt_num(void) * @return uint8_t */ uint8_t -bletest_set_adv_data(uint8_t *dptr) +bletest_set_adv_data(uint8_t *dptr, uint8_t *addr) { uint8_t len; @@ -282,7 +304,7 @@ bletest_set_adv_data(uint8_t *dptr) dptr[0] = 0x08; dptr[1] = 0x1B; dptr[2] = 0x00; - memcpy(dptr + 3, g_dev_addr, BLE_DEV_ADDR_LEN); + memcpy(dptr + 3, addr, BLE_DEV_ADDR_LEN); len += 9; g_host_adv_len = len; @@ -295,28 +317,50 @@ void bletest_init_advertising(void) { int rc; + int set_peer_addr; uint8_t adv_len; + uint8_t *addr; uint8_t rand_addr[BLE_DEV_ADDR_LEN]; struct hci_adv_params adv; /* Just zero out advertising */ + set_peer_addr = 0; memset(&adv, 0, sizeof(struct hci_adv_params)); + /* If we are using a random address, we need to set it */ + adv.own_addr_type = BLETEST_CFG_ADV_OWN_ADDR_TYPE; + if (adv.own_addr_type & 1) { + memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN); + rand_addr[5] |= 0xc0; + rc = bletest_hci_le_set_rand_addr(rand_addr); + assert(rc == 0); + addr = rand_addr; + } else { + addr = g_dev_addr; + } + /* Set advertising parameters */ adv.adv_type = BLETEST_CFG_ADV_TYPE; adv.adv_channel_map = 0x07; adv.adv_filter_policy = BLETEST_CFG_ADV_FILT_POLICY; - adv.own_addr_type = BLETEST_CFG_ADV_OWN_ADDR_TYPE; adv.peer_addr_type = BLETEST_CFG_ADV_PEER_ADDR_TYPE; if ((adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) || (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) { + set_peer_addr = 1; + adv_len = 0; + } else { + adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr); + } + + if (adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + set_peer_addr = 1; + } + + if (set_peer_addr) { memcpy(adv.peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN); if (adv.peer_addr_type == BLE_HCI_ADV_PEER_ADDR_RANDOM) { adv.peer_addr[5] |= 0xc0; } - adv_len = 0; - } else { - adv_len = bletest_set_adv_data(&g_host_adv_data[0]); } console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n", @@ -335,13 +379,18 @@ bletest_init_advertising(void) rc = bletest_hci_le_set_adv_params(&adv); assert(rc == 0); - /* If we are using a random address, we need to set it */ - if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) { - memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN); - rand_addr[5] |= 0xc0; - rc = bletest_hci_le_set_rand_addr(rand_addr); +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + rc = bletest_hci_le_add_resolv_list(g_bletest_adv_irk, + g_bletest_init_irk, + adv.peer_addr, + adv.peer_addr_type); + assert(rc == 0); + + rc = bletest_hci_le_enable_resolv_list(1); assert(rc == 0); } +#endif /* Set advertising data */ if (adv_len != 0) { @@ -360,29 +409,45 @@ void bletest_init_scanner(void) { int rc; + uint8_t own_addr_type; uint8_t dev_addr[BLE_DEV_ADDR_LEN]; uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN]; - uint8_t filter_policy; + uint8_t add_whitelist; + own_addr_type = BLETEST_CFG_SCAN_OWN_ADDR_TYPE; rc = host_hci_cmd_build_le_set_scan_params(BLETEST_CFG_SCAN_TYPE, BLETEST_CFG_SCAN_ITVL, BLETEST_CFG_SCAN_WINDOW, - BLE_HCI_ADV_OWN_ADDR_PUBLIC, + BLETEST_CFG_SCAN_OWN_ADDR_TYPE, BLETEST_CFG_SCAN_FILT_POLICY, buf, sizeof buf); assert(rc == 0); rc = ble_hci_cmd_tx_empty_ack(buf); if (rc == 0) { - filter_policy = BLETEST_CFG_SCAN_FILT_POLICY; - if (filter_policy & 1) { - /* Add some whitelist addresses */ + add_whitelist = BLETEST_CFG_SCAN_FILT_POLICY; +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + rc = bletest_hci_le_add_resolv_list(g_bletest_init_irk, + g_bletest_adv_irk, + g_bletest_cur_peer_addr, + BLETEST_CFG_ADV_PEER_ADDR_TYPE); + assert(rc == 0); + + rc = bletest_hci_le_enable_resolv_list(1); + assert(rc == 0); + + add_whitelist = 0; + } +#endif + if (add_whitelist & 1) { + /* Add peer to whitelist */ dev_addr[0] = 0x00; dev_addr[1] = 0x00; dev_addr[2] = 0x00; dev_addr[3] = 0x88; dev_addr[4] = 0x88; dev_addr[5] = 0x08; - rc = bletest_hci_le_add_to_whitelist(dev_addr, BLE_ADDR_TYPE_PUBLIC); + rc = bletest_hci_le_add_to_whitelist(dev_addr,BLE_ADDR_TYPE_PUBLIC); assert(rc == 0); } } @@ -448,6 +513,20 @@ bletest_init_initiator(void) assert(rc == 0); } +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if ((hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) || + (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM)) { + rc = bletest_hci_le_add_resolv_list(g_bletest_init_irk, + g_bletest_adv_irk, + g_bletest_cur_peer_addr, + BLETEST_CFG_ADV_PEER_ADDR_TYPE); + assert(rc == 0); + + rc = bletest_hci_le_enable_resolv_list(1); + assert(rc == 0); + } +#endif + rc = bletest_hci_le_create_connection(hcc); assert(rc == 0); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/apps/bletiny/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c index 47394b3..3657cc3 100755 --- a/apps/bletiny/src/main.c +++ b/apps/bletiny/src/main.c @@ -73,7 +73,7 @@ uint8_t g_host_adv_len; static uint8_t bletiny_addr[6] = {0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a}; /* Create a mbuf pool of BLE mbufs */ -#define MBUF_NUM_MBUFS (12) +#define MBUF_NUM_MBUFS (16) #define MBUF_BUF_SIZE OS_ALIGN(BLE_MBUF_PAYLOAD_SIZE, 4) #define MBUF_MEMBLOCK_SIZE (MBUF_BUF_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD) #define MBUF_MEMPOOL_SIZE OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/include/controller/ble_ll.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h index 9a4014c..81cba53 100644 --- a/net/nimble/controller/include/controller/ble_ll.h +++ b/net/nimble/controller/include/controller/ble_ll.h @@ -299,7 +299,7 @@ int ble_ll_is_valid_random_addr(uint8_t *addr); uint16_t ble_ll_pdu_tx_time_get(uint16_t len); /* Is this address a resolvable private address? */ -int ble_ll_is_resolvable_priv_addr(uint8_t *addr); +int ble_ll_is_rpa(uint8_t *addr, uint8_t addr_type); /* Is 'addr' our device address? 'addr_type' is public (0) or random (!=0) */ int ble_ll_is_our_devaddr(uint8_t *addr, int addr_type); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/include/controller/ble_ll_adv.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_adv.h b/net/nimble/controller/include/controller/ble_ll_adv.h index 5a5d607..33a73ab 100644 --- a/net/nimble/controller/include/controller/ble_ll_adv.h +++ b/net/nimble/controller/include/controller/ble_ll_adv.h @@ -116,6 +116,12 @@ int ble_ll_adv_set_adv_params(uint8_t *cmd); int ble_ll_adv_read_txpwr(uint8_t *rspbuf, uint8_t *rsplen); /*---- API used by BLE LL ----*/ +/* Returns local resolvable private address */ +uint8_t *ble_ll_adv_get_local_rpa(void); + +/* Returns peer resolvable private address */ +uint8_t *ble_ll_adv_get_peer_rpa(void); + /* Called when advertising event done posted to LL task */ void ble_ll_adv_event_done(void *arg); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/include/controller/ble_ll_conn.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_conn.h b/net/nimble/controller/include/controller/ble_ll_conn.h index f035852..035ca39 100644 --- a/net/nimble/controller/include/controller/ble_ll_conn.h +++ b/net/nimble/controller/include/controller/ble_ll_conn.h @@ -160,6 +160,9 @@ struct ble_ll_conn_sm uint8_t last_rxd_hdr_byte; /* note: possibly can make 1 bit since we only use the MD bit now */ + /* For privacy */ + int8_t rpa_index; + /* connection event mgmt */ uint8_t reject_reason; uint8_t host_reply_opcode; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/include/controller/ble_ll_resolv.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_resolv.h b/net/nimble/controller/include/controller/ble_ll_resolv.h index bddf70b..251543b 100644 --- a/net/nimble/controller/include/controller/ble_ll_resolv.h +++ b/net/nimble/controller/include/controller/ble_ll_resolv.h @@ -27,7 +27,7 @@ */ struct ble_ll_resolv_entry { - uint8_t rl_valid; + uint8_t rl_reserved; uint8_t rl_addr_type; uint8_t rl_identity_addr[BLE_DEV_ADDR_LEN]; uint8_t rl_local_irk[16]; @@ -51,16 +51,11 @@ int ble_ll_resolv_list_rmv(uint8_t *cmdbuf); /* Address resolution enable command */ int ble_ll_resolv_enable_cmd(uint8_t *cmdbuf); +/* XXX: implement */ int ble_ll_resolv_peer_addr_rd(uint8_t *cmdbuf); void ble_ll_resolv_local_addr_rd(uint8_t *cmdbuf); -/* Enable resolving list */ -void ble_ll_resolv_list_enable(void); - -/* Disable resolving list */ -void ble_ll_resolv_list_disable(void); - -/* Finds 'addr' in resolving list. */ +/* Finds 'addr' in resolving list. Doesnt check if address resolution enabled */ struct ble_ll_resolv_entry * ble_ll_resolv_list_find(uint8_t *addr, uint8_t addr_type); @@ -76,4 +71,20 @@ void ble_ll_resolv_list_reset(void); void ble_ll_resolv_gen_priv_addr(struct ble_ll_resolv_entry *rl, int local, uint8_t *addr); +/* Generate a resolvable private address. */ +int ble_ll_resolv_gen_rpa(uint8_t *addr, uint8_t addr_type, uint8_t *rpa, + int local); + +/* Set the resolvable private address timeout */ +int ble_ll_resolv_set_rpa_tmo(uint8_t *cmdbuf); + +/* Get the RPA timeout, in seconds */ +uint32_t ble_ll_resolv_get_rpa_tmo(void); + +/* Resolve a resolvable private address */ +int ble_ll_resolv_rpa(uint8_t *rpa, uint8_t *irk); + +/* Initialize resolv*/ +void ble_ll_resolv_init(void); + #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/include/controller/ble_ll_scan.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h b/net/nimble/controller/include/controller/ble_ll_scan.h index 8323138..7dafcee 100644 --- a/net/nimble/controller/include/controller/ble_ll_scan.h +++ b/net/nimble/controller/include/controller/ble_ll_scan.h @@ -61,6 +61,8 @@ struct ble_ll_scan_sm uint8_t scan_rsp_pending; uint8_t scan_rsp_cons_fails; uint8_t scan_rsp_cons_ok; + int8_t scan_rpa_index; + uint8_t scan_peer_rpa[BLE_DEV_ADDR_LEN]; uint16_t upper_limit; uint16_t backoff_count; uint16_t scan_itvl; @@ -119,6 +121,15 @@ int ble_ll_scan_initiator_start(struct hci_create_conn *hcc); /* Returns the PDU allocated by the scanner */ struct os_mbuf *ble_ll_scan_get_pdu(void); +/* Called to set the resolvable private address of the last connected peer */ +void ble_ll_scan_set_peer_rpa(uint8_t *rpa); + +/* Returns peer RPA of last connection made */ +uint8_t *ble_ll_scan_get_peer_rpa(void); + +/* Returns the local RPA used by the scanner/initiator */ +uint8_t *ble_ll_scan_get_local_rpa(void); + /* Stop the scanning state machine */ void ble_ll_scan_sm_stop(int chk_disable); @@ -128,7 +139,4 @@ void ble_ll_scan_chk_resume(void); /* Called when wait for response timer expires in scanning mode */ void ble_ll_scan_wfr_timer_exp(void); -/* Returns the global scanning state machine */ -struct ble_ll_scan_sm *ble_ll_scan_sm_get(void); - #endif /* H_BLE_LL_SCAN_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/include/controller/ble_ll_whitelist.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_whitelist.h b/net/nimble/controller/include/controller/ble_ll_whitelist.h index f62ab27..3c37afd 100644 --- a/net/nimble/controller/include/controller/ble_ll_whitelist.h +++ b/net/nimble/controller/include/controller/ble_ll_whitelist.h @@ -39,6 +39,6 @@ void ble_ll_whitelist_enable(void); void ble_ll_whitelist_disable(void); /* Boolean function returning true if address matches a whitelist entry */ -int ble_ll_whitelist_match(uint8_t *addr, uint8_t addr_type); +int ble_ll_whitelist_match(uint8_t *addr, uint8_t addr_type, int is_ident); #endif /* H_BLE_LL_WHITELIST_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c index e53d56f..a5197bb 100644 --- a/net/nimble/controller/src/ble_ll.c +++ b/net/nimble/controller/src/ble_ll.c @@ -288,21 +288,23 @@ ble_ll_chk_txrx_time(uint16_t time) return rc; } -/* WWW: check where called to see if correct */ /** - * Checks to see if the address is a resolvable private address. Th + * Checks to see if the address is a resolvable private address. * + * NOTE: the addr_type parameter will be 0 if the address is public; + * any other value is random (all non-zero values). * * @param addr + * @param addr_type Public (zero) or Random (non-zero) address * * @return int */ int -ble_ll_is_resolvable_priv_addr(uint8_t *addr) +ble_ll_is_rpa(uint8_t *addr, uint8_t addr_type) { int rc; - if ((addr[5] & 0xc0) == 0x40) { + if (addr_type && ((addr[5] & 0xc0) == 0x40)) { rc = 1; } else { rc = 0; @@ -385,7 +387,7 @@ ble_ll_set_random_addr(uint8_t *addr) * @param addr * @param addr_type * - * @return int + * @return int 0: not our device address. 1: is our device address */ int ble_ll_is_our_devaddr(uint8_t *addr, int addr_type) @@ -1161,6 +1163,10 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size) features |= BLE_LL_FEAT_LE_ENCRYPTION; #endif +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + ble_ll_resolv_init(); +#endif + /* Initialize random number generation */ ble_ll_rand_init(); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_adv.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c index c49686c..a5974ed 100644 --- a/net/nimble/controller/src/ble_ll_adv.c +++ b/net/nimble/controller/src/ble_ll_adv.c @@ -57,6 +57,13 @@ * adv_pdu_len * The length of the advertising PDU that will be sent. This does not * include the preamble, access address and CRC. + * + * initiator_addr: + * This is the address that we send in directed advertisements (the + * INITA field). If we are using Privacy this is a RPA that we need to + * generate. We reserve space in the advsm to save time when creating + * the ADV_DIRECT_IND. If own address type is not 2 or 3, this is simply + * the peer address from the set advertising parameters. */ struct ble_ll_adv_sm { @@ -71,12 +78,14 @@ struct ble_ll_adv_sm uint8_t scan_rsp_len; uint8_t adv_pdu_len; int8_t adv_rpa_index; + uint8_t adv_directed; uint16_t adv_itvl_min; uint16_t adv_itvl_max; uint32_t adv_itvl_usecs; uint32_t adv_event_start_time; uint32_t adv_pdu_start_time; uint32_t adv_dir_hd_end_time; + uint32_t adv_rpa_timer; uint8_t adva[BLE_DEV_ADDR_LEN]; uint8_t adv_rpa[BLE_DEV_ADDR_LEN]; uint8_t peer_addr[BLE_DEV_ADDR_LEN]; @@ -108,6 +117,29 @@ struct ble_ll_adv_sm g_ble_ll_adv_sm; #define BLE_LL_ADV_SCHED_MAX_USECS (852) #define BLE_LL_ADV_DIRECT_SCHED_MAX_USECS (502) + +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) +void +ble_ll_adv_chk_rpa_timeout(struct ble_ll_adv_sm *advsm) +{ + uint32_t now; + + if (advsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + now = os_time_get(); + if ((int32_t)(now >= advsm->adv_rpa_timer)) { + ble_ll_resolv_gen_rpa(advsm->peer_addr, advsm->peer_addr_type, + advsm->adva, 1); + + if (advsm->adv_directed) { + ble_ll_resolv_gen_rpa(advsm->peer_addr, advsm->peer_addr_type, + advsm->initiator_addr, 0); + } + advsm->adv_rpa_timer = now + ble_ll_resolv_get_rpa_tmo(); + } + } +} +#endif + /** * Calculate the first channel that we should advertise upon when we start * an advertising event. @@ -141,7 +173,6 @@ ble_ll_adv_first_chan(struct ble_ll_adv_sm *advsm) static void ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) { - int is_direct_adv; uint8_t adv_data_len; uint8_t *dptr; uint8_t pdulen; @@ -150,7 +181,6 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) /* assume this is not a direct ind */ adv_data_len = advsm->adv_len; pdulen = BLE_DEV_ADDR_LEN + adv_data_len; - is_direct_adv = 0; /* Must be an advertising type! */ switch (advsm->adv_type) { @@ -168,7 +198,6 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD: case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD: - is_direct_adv = 1; pdu_type = BLE_ADV_PDU_TYPE_ADV_DIRECT_IND; adv_data_len = 0; pdulen = BLE_ADV_DIRECT_IND_LEN; @@ -192,8 +221,9 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) /* Set the PDU length in the state machine (includes header) */ advsm->adv_pdu_len = pdulen + BLE_LL_PDU_HDR_LEN; - /* Set TxAdd to random if needed */ - if (advsm->own_addr_type & 1) { + /* Set TxAdd to random if needed. */ + if (ble_ll_is_rpa(advsm->adva, 1) || + (advsm->own_addr_type & 1)) { pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; } @@ -205,8 +235,8 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m) memcpy(dptr, advsm->adva, BLE_DEV_ADDR_LEN); dptr += BLE_DEV_ADDR_LEN; - /* For ADV_DIRECT_IND, we need to put initiators address in there */ - if (is_direct_adv) { + /* For ADV_DIRECT_IND add inita */ + if (advsm->adv_directed) { memcpy(dptr, advsm->initiator_addr, BLE_DEV_ADDR_LEN); } @@ -249,6 +279,15 @@ ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm) ble_ll_mbuf_init(m, pdulen, hdr); + /* + * XXX: Am I sure this is correct? The adva in this packet will be the + * same one that was being advertised and is based on the peer identity + * address in the set advertising parameters. If a different peer sends + * us a scan request (for some reason) we will reply with an adva that + * was not generated based on the local irk of the peer sending the scan + * request. + */ + /* Construct scan response */ dptr = m->om_data; memcpy(dptr, advsm->adva, BLE_DEV_ADDR_LEN); @@ -477,6 +516,7 @@ ble_ll_adv_set_adv_params(uint8_t *cmd) /* Assume min interval based on low duty cycle/indirect advertising */ min_itvl = BLE_LL_ADV_ITVL_MIN; + advsm->adv_directed = 0; switch (adv_type) { /* Fall through intentional */ case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD: @@ -487,7 +527,8 @@ ble_ll_adv_set_adv_params(uint8_t *cmd) case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD: adv_filter_policy = BLE_HCI_ADV_FILT_NONE; - memcpy(advsm->initiator_addr, cmd + 7, BLE_DEV_ADDR_LEN); + advsm->adv_directed = 1; + memcpy(advsm->peer_addr, cmd + 7, BLE_DEV_ADDR_LEN); break; case BLE_HCI_ADV_TYPE_ADV_IND: /* Nothing to do */ @@ -521,9 +562,12 @@ ble_ll_adv_set_adv_params(uint8_t *cmd) if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { /* Copy peer address */ memcpy(advsm->peer_addr, cmd + 7, BLE_DEV_ADDR_LEN); + + /* Reset RPA timer so we generate a new RPA */ + advsm->adv_rpa_timer = os_time_get(); } #else - /* If we dont support privacy these own address types wont work */ + /* If we dont support privacy some address types wont work */ if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { return BLE_ERR_UNSUPPORTED; } @@ -598,7 +642,6 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) { uint8_t adv_chan; uint8_t *addr; - struct ble_ll_resolv_entry *rl; /* * This is not in the specification. I will reject the command with a @@ -621,27 +664,18 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) } memcpy(advsm->adva, addr, BLE_DEV_ADDR_LEN); -#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) - /* WWW: - * 1) Make sure we are doing this for the proper adv types - */ - if (ble_ll_resolv_enabled()) { - if (advsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { - rl = ble_ll_resolv_list_find(advsm->peer_addr, advsm->peer_addr_type); - if (rl && ble_ll_resolv_irk_nonzero(rl->rl_local_irk)) { - ble_ll_resolv_gen_priv_addr(rl, 1, advsm->adva); - } - } - ble_phy_resolv_list_enable(); - } else { - ble_phy_resolv_list_disable(); + if (advsm->adv_directed) { + memcpy(advsm->initiator_addr, advsm->peer_addr, BLE_DEV_ADDR_LEN); } + + /* This will generate an RPA for both initiator addr and adva */ +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + ble_ll_adv_chk_rpa_timeout(advsm); #endif /* Set flag telling us that advertising is enabled */ advsm->enabled = 1; - /* WWW: what about privacy for direct? */ /* Determine the advertising interval we will use */ if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) { /* Set it to max. allowed for high duty cycle advertising */ @@ -810,11 +844,13 @@ static int ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) { int rc; - int index; - uint8_t chk_whitelist; + int resolved; + uint8_t chk_wl; uint8_t txadd; + uint8_t peer_addr_type; uint8_t *rxbuf; uint8_t *adva; + uint8_t *peer; struct ble_mbuf_hdr *ble_hdr; struct ble_ll_adv_sm *advsm; struct os_mbuf *scan_rsp; @@ -829,27 +865,35 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) /* Set device match bit if we are whitelisting */ if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) { - chk_whitelist = advsm->adv_filter_policy & 1; + chk_wl = advsm->adv_filter_policy & 1; } else { - chk_whitelist = advsm->adv_filter_policy & 2; + chk_wl = advsm->adv_filter_policy & 2; + } + + /* Get the peer address type */ + if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) { + txadd = BLE_ADDR_TYPE_RANDOM; + } else { + txadd = BLE_ADDR_TYPE_PUBLIC; } ble_hdr = BLE_MBUF_HDR_PTR(rxpdu); + peer = rxbuf + BLE_LL_PDU_HDR_LEN; + peer_addr_type = txadd; + resolved = 0; #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) - uint8_t *peer; - - peer = rxbuf + BLE_LL_PDU_HDR_LEN; - if (ble_ll_is_resolvable_priv_addr(peer) && ble_ll_resolv_enabled()) { - index = ble_hw_resolv_list_match(); - if (index >= 0) { - advsm->adv_rpa_index = index; + if (ble_ll_is_rpa(peer, txadd) && ble_ll_resolv_enabled()) { + advsm->adv_rpa_index = ble_hw_resolv_list_match(); + if (advsm->adv_rpa_index >= 0) { ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED; - if (chk_whitelist) { - chk_whitelist = 0; + if (chk_wl) { + peer = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr; + peer_addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type; + resolved = 1; } } else { - if (chk_whitelist) { + if (chk_wl) { return -1; } } @@ -857,18 +901,8 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) #endif /* Set device match bit if we are whitelisting */ - if (chk_whitelist) { - /* Get the scanners address type */ - if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) { - txadd = BLE_ADDR_TYPE_RANDOM; - } else { - txadd = BLE_ADDR_TYPE_PUBLIC; - } - - /* Check for whitelist match */ - if (!ble_ll_whitelist_match(rxbuf + BLE_LL_PDU_HDR_LEN, txadd)) { - return -1; - } + if (chk_wl && !ble_ll_whitelist_match(peer, peer_addr_type, resolved)) { + return -1; } /* @@ -888,6 +922,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_SCAN_RSP_TXD; STATS_INC(ble_ll_stats, scan_rsp_txg); } + os_mbuf_free_chain(scan_rsp); } } @@ -910,35 +945,48 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) int valid; uint8_t pyld_len; uint8_t resolved; + uint8_t addr_type; uint8_t *inita; + uint8_t *ident_addr; uint32_t endtime; struct ble_ll_adv_sm *advsm; /* Check filter policy. */ valid = 0; + resolved = BLE_MBUF_HDR_RESOLVED(hdr); advsm = &g_ble_ll_adv_sm; inita = rxbuf + BLE_LL_PDU_HDR_LEN; if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH) { + valid = 1; - if ((advsm->adv_filter_policy & 2) == 0) { - /* - * Only accept connect requests from the desired address if we - * are doing directed advertising - */ - if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) || - (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) { - /* XXX: not sure if this works if address is random */ - /* WWW: deal with RPA */ - /* Compare addresses */ - if (memcmp(advsm->initiator_addr, inita, BLE_DEV_ADDR_LEN)) { - valid = 0; - } + if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) { + addr_type = BLE_ADDR_TYPE_RANDOM; + } else { + addr_type = BLE_ADDR_TYPE_PUBLIC; + } + + /* + * Only accept connect requests from the desired address if we + * are doing directed advertising + */ + if ((advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) || + (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) { + ident_addr = inita; + +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (resolved) { + ident_addr = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr; + addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type; + } +#endif + if ((addr_type != advsm->peer_addr_type) || + memcmp(advsm->peer_addr, ident_addr, BLE_DEV_ADDR_LEN)) { + valid = 0; } } } if (valid) { - resolved = BLE_MBUF_HDR_RESOLVED(hdr); #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) if (resolved) { /* Retain the resolvable private address that we received. */ @@ -951,13 +999,17 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) memcpy(inita, g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr, BLE_DEV_ADDR_LEN); + + /* Peer address type is an identity address */ + addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type; + addr_type += 2; } #endif /* Try to start slave connection. If successful, stop advertising */ pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK; endtime = hdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len); - valid = ble_ll_conn_slave_start(rxbuf, endtime, resolved); + valid = ble_ll_conn_slave_start(rxbuf, endtime, addr_type); if (valid) { ble_ll_adv_sm_stop(advsm); } @@ -1216,6 +1268,11 @@ ble_ll_adv_event_done(void *arg) } } + /* We need to regenerate our RPA's if we have passed timeout */ +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + ble_ll_adv_chk_rpa_timeout(advsm); +#endif + /* Schedule advertising transmit */ ble_ll_adv_set_sched(advsm, 0); @@ -1252,6 +1309,44 @@ ble_ll_adv_can_chg_whitelist(void) } /** + * Returns the local resolvable private address currently being using by + * the advertiser + * + * @return uint8_t* + */ +uint8_t * +ble_ll_adv_get_local_rpa(void) +{ + uint8_t *rpa; + struct ble_ll_adv_sm *advsm; + + advsm = &g_ble_ll_adv_sm; + + rpa = NULL; + if (advsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + rpa = advsm->adva; + } + + return rpa; +} + +/** + * Returns the peer resolvable private address of last device connecting to us + * + * @return uint8_t* + */ +uint8_t * +ble_ll_adv_get_peer_rpa(void) +{ + struct ble_ll_adv_sm *advsm; + + advsm = &g_ble_ll_adv_sm; + + /* XXX: should this go into IRK list or connection? */ + return advsm->adv_rpa; +} + +/** * Called when the LL wait for response timer expires while in the advertising * state. Disables the phy and * http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_conn.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c index fe72a8e..3890a4f 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -32,7 +32,9 @@ #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_ctrl.h" +#include "controller/ble_ll_resolv.h" #include "controller/ble_phy.h" +#include "controller/ble_hw.h" #include "ble_ll_conn_priv.h" #include "hal/hal_cputime.h" #include "hal/hal_gpio.h" @@ -1116,6 +1118,10 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) ble_phy_setchan(connsm->data_chan_index, connsm->access_addr, connsm->crcinit); +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + ble_phy_resolv_list_disable(); +#endif + if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { /* Set start time of transmission */ rc = ble_phy_tx_set_start_time(sch->start_time + XCVR_PROC_DELAY_USECS); @@ -1302,8 +1308,6 @@ ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, connsm->slave_latency = hcc->conn_latency; connsm->supervision_tmo = hcc->supervision_timeout; - /* WWW: if not using whitelist, what happens if we resolve the address? - we would have to set the differently huh? CHeck this out... */ /* Set own address type and peer address if needed */ connsm->own_addr_type = hcc->own_addr_type; if (hcc->filter_policy == 0) { @@ -1367,6 +1371,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->sub_vers_nr = 0; connsm->reject_reason = BLE_ERR_SUCCESS; connsm->conn_rssi = BLE_LL_CONN_UNKNOWN_RSSI; + connsm->rpa_index = -1; /* Reset current control procedure */ connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_IDLE; @@ -1777,7 +1782,6 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, uint32_t endtime) ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD); } } - /* WWW: enhanced connection complete! */ ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS); } @@ -1874,51 +1878,120 @@ ble_ll_conn_event_end(void *arg) * * @param m * @param adva - * @param addr_type + * @param addr_type Address type of ADVA from received advertisement. * @param txoffset The tx window offset for this connection */ static void ble_ll_conn_req_pdu_update(struct os_mbuf *m, uint8_t *adva, uint8_t addr_type, - uint16_t txoffset) + uint16_t txoffset, int rpa_index) { - uint8_t pdu_type; + int is_rpa; + uint8_t hdr; uint8_t *dptr; + uint8_t *addr; struct ble_mbuf_hdr *ble_hdr; + struct ble_ll_resolv_entry *rl; + struct ble_ll_conn_sm *connsm; assert(m != NULL); + /* Retain pdu type but clear txadd/rxadd bits */ ble_hdr = BLE_MBUF_HDR_PTR(m); - pdu_type = ble_hdr->txinfo.hdr_byte; + hdr = ble_hdr->txinfo.hdr_byte & BLE_ADV_PDU_HDR_TYPE_MASK; if (addr_type) { /* Set random address */ - pdu_type |= BLE_ADV_PDU_HDR_RXADD_MASK; + hdr |= BLE_ADV_PDU_HDR_RXADD_MASK; + } + + dptr = m->om_data; + + /* Get pointer to our device address */ + connsm = g_ble_ll_conn_create_sm; + if ((connsm->own_addr_type & 1) == 0) { + addr = g_dev_addr; } else { - /* Set public device address */ - pdu_type &= ~BLE_ADV_PDU_HDR_RXADD_MASK; + hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; + addr = g_random_addr; } - /* Set BLE transmit header */ - ble_hdr->txinfo.hdr_byte = pdu_type; + /* XXX: do this ahead of time? Calculate the local rpa I mean */ + if (connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + rl = NULL; + is_rpa = ble_ll_is_rpa(adva, addr_type); + if (is_rpa) { + if (rpa_index >= 0) { + rl = &g_ble_ll_resolv_list[rpa_index]; + } + } else { + if (ble_ll_resolv_enabled()) { + rl = ble_ll_resolv_list_find(adva, addr_type); + } + } - dptr = m->om_data; + if (rl) { + hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; + ble_ll_resolv_gen_priv_addr(rl, 1, dptr); + addr = NULL; + } + } + + if (addr) { + memcpy(dptr, addr, BLE_DEV_ADDR_LEN); + } memcpy(dptr + BLE_DEV_ADDR_LEN, adva, BLE_DEV_ADDR_LEN); htole16(dptr + 20, txoffset); + + /* Set BLE transmit header */ + ble_hdr->txinfo.hdr_byte = hdr; } /* Returns true if the address matches the connection peer address */ static int -ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva) +ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva, int index) { int rc; + uint8_t *peer_addr; struct ble_ll_conn_sm *connsm; /* XXX: Deal with different types of random addresses here! */ connsm = g_ble_ll_conn_create_sm; - if (connsm && (connsm->peer_addr_type == addr_type) && - !memcmp(adva, connsm->peer_addr, BLE_DEV_ADDR_LEN)) { - rc = 1; - } else { - rc = 0; + if (!connsm) { + return 0; + } + + switch (connsm->peer_addr_type) { + /* Fall-through intentional */ + case BLE_HCI_CONN_PEER_ADDR_PUBLIC: + case BLE_HCI_CONN_PEER_ADDR_RANDOM: + if (addr_type != connsm->peer_addr_type) { + return 0; + } + peer_addr = adva; + break; + case BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT: + if ((index < 0) || + (g_ble_ll_resolv_list[index].rl_addr_type != 0)) { + return 0; + } + peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr; + break; + case BLE_HCI_CONN_PEER_ADDR_RANDOM_IDENT: + if ((index < 0) || + (g_ble_ll_resolv_list[index].rl_addr_type != 1)) { + return 0; + } + peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr; + break; + default: + peer_addr = NULL; + break; + } + + rc = 0; + if (peer_addr) { + if (!memcmp(peer_addr, connsm->peer_addr, BLE_DEV_ADDR_LEN)) { + rc = 1; + } } return rc; @@ -1946,13 +2019,14 @@ ble_ll_conn_req_txend(void *arg) * @param adva Address of advertiser */ static int -ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva, uint16_t txoffset) +ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva, uint16_t txoffset, + int rpa_index) { int rc; struct os_mbuf *m; m = ble_ll_scan_get_pdu(); - ble_ll_conn_req_pdu_update(m, adva, addr_type, txoffset); + ble_ll_conn_req_pdu_update(m, adva, addr_type, txoffset, rpa_index); ble_phy_set_txend_cb(ble_ll_conn_req_txend, NULL); rc = ble_phy_tx(m, BLE_PHY_TRANSITION_NONE); return rc; @@ -1988,8 +2062,10 @@ ble_ll_conn_event_halt(void) void ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr) { + int8_t rpa_index; uint8_t addr_type; uint8_t payload_len; + uint8_t *addr; uint32_t endtime; struct ble_ll_conn_sm *connsm; @@ -2000,11 +2076,6 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr) if (connsm && CONN_F_CONN_REQ_TXD(connsm)) { /* Set address of advertiser to which we are connecting. */ if (ble_ll_scan_whitelist_enabled()) { - /* - * XXX: need to see if the whitelist tells us exactly what peer - * addr type we should use? Not sure it matters. If whitelisting - * is not used the peer addr and type already set - */ /* Get address type of advertiser */ if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) { addr_type = BLE_HCI_CONN_PEER_ADDR_RANDOM; @@ -2012,15 +2083,31 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr) addr_type = BLE_HCI_CONN_PEER_ADDR_PUBLIC; } + /* + * Did we resolve this address? If so, set correct peer address + * and peer address type. + */ + rpa_index = connsm->rpa_index; + + if (rpa_index >= 0) { + addr_type = g_ble_ll_resolv_list[rpa_index].rl_addr_type + 2; + addr = g_ble_ll_resolv_list[rpa_index].rl_identity_addr; + } else { + addr = rxbuf + BLE_LL_PDU_HDR_LEN; + } + connsm->peer_addr_type = addr_type; - memcpy(connsm->peer_addr, rxbuf + BLE_LL_PDU_HDR_LEN, - BLE_DEV_ADDR_LEN); + memcpy(connsm->peer_addr, addr, BLE_DEV_ADDR_LEN); + } + + if (connsm->rpa_index >= 0) { + ble_ll_scan_set_peer_rpa(rxbuf + BLE_LL_PDU_HDR_LEN); } /* Connection has been created. Stop scanning */ g_ble_ll_conn_create_sm = NULL; ble_ll_scan_sm_stop(0); - payload_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;; + payload_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK; endtime = ble_hdr->beg_cputime + BLE_TX_DUR_USECS_M(payload_len); ble_ll_conn_created(connsm, endtime); } else { @@ -2044,15 +2131,22 @@ int ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) { int rc; + int resolved; int chk_send_req; + int chk_wl; + int index; uint8_t pdu_type; uint8_t addr_type; + uint8_t peer_addr_type; uint8_t *adv_addr; + uint8_t *peer; uint8_t *init_addr; uint8_t *rxbuf; uint8_t pyld_len; + uint8_t inita_is_rpa; uint32_t endtime; struct ble_mbuf_hdr *ble_hdr; + struct ble_ll_conn_sm *connsm; /* * We have to restart receive if we cant hand up pdu. We return 0 so that @@ -2068,22 +2162,34 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) goto init_rx_isr_exit; } + /* Get connection state machine to use if connection to be established */ + connsm = g_ble_ll_conn_create_sm; + /* Only interested in ADV IND or ADV DIRECT IND */ rxbuf = rxpdu->om_data; pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK; pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK; + inita_is_rpa = 0; + switch (pdu_type) { case BLE_ADV_PDU_TYPE_ADV_IND: chk_send_req = 1; break; case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND: + /* XXX: needs to be fixed for privacy */ + chk_send_req = 0; init_addr = rxbuf + BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN; addr_type = rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK; - if (ble_ll_is_our_devaddr(init_addr, addr_type)) { - chk_send_req = 1; - } else { - chk_send_req = 0; + if (addr_type) { + inita_is_rpa = (uint8_t)ble_ll_is_rpa(init_addr, addr_type); + } + + if (!inita_is_rpa && ble_ll_is_our_devaddr(init_addr, addr_type)) { + /* We should not respond if we expect the device to be private */ + if (connsm->own_addr_type <= BLE_HCI_ADV_OWN_ADDR_RANDOM) { + chk_send_req = 1; + } } break; default: @@ -2101,34 +2207,65 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) addr_type = BLE_HCI_CONN_PEER_ADDR_PUBLIC; } - /* Check filter policy */ + index = -1; ble_hdr = BLE_MBUF_HDR_PTR(rxpdu); - if (ble_ll_scan_whitelist_enabled()) { - /* Check if device is on whitelist. If not, leave */ - if (!ble_ll_whitelist_match(adv_addr, addr_type)) { - return -1; + peer = adv_addr; + peer_addr_type = addr_type; + + resolved = 0; + chk_wl = ble_ll_scan_whitelist_enabled(); + +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (ble_ll_is_rpa(adv_addr, addr_type) && ble_ll_resolv_enabled()) { + index = ble_hw_resolv_list_match(); + if (index >= 0) { + ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED; + connsm->rpa_index = index; + peer = g_ble_ll_resolv_list[index].rl_identity_addr; + peer_addr_type = g_ble_ll_resolv_list[index].rl_addr_type; + resolved = 1; + } else { + if (chk_wl) { + return -1; + } } + } +#endif - /* Set BLE mbuf header flags */ - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH; + /* Check filter policy */ + if (chk_wl) { + if (!ble_ll_whitelist_match(peer, peer_addr_type, resolved)) { + return -1; + } } else { - /* XXX: Resolvable? Deal with those */ - /* XXX: HW device matching? If so, implement */ /* Must match the connection address */ - if (!ble_ll_conn_is_peer_adv(addr_type, adv_addr)) { + if (!ble_ll_conn_is_peer_adv(addr_type, adv_addr, index)) { + return -1; + } + } + ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH; + + /* + * If the inita is a RPA, we must see if it resolves based on the + * identity address of the resolved ADVA. + */ + if (inita_is_rpa) { + if ((index < 0) || + !ble_ll_resolv_rpa(init_addr, + g_ble_ll_resolv_list[index].rl_local_irk)) { return -1; } } /* Attempt to schedule new connection. Possible that this might fail */ endtime = ble_hdr->beg_cputime + BLE_TX_DUR_USECS_M(pyld_len); - if (!ble_ll_sched_master_new(g_ble_ll_conn_create_sm, endtime, + if (!ble_ll_sched_master_new(connsm, endtime, NIMBLE_OPT_LL_CONN_INIT_SLOTS)) { /* Setup to transmit the connect request */ rc = ble_ll_conn_request_send(addr_type, adv_addr, - g_ble_ll_conn_create_sm->tx_win_off); + connsm->tx_win_off, index); if (!rc) { - CONN_F_CONN_REQ_TXD(g_ble_ll_conn_create_sm) = 1; + CONN_F_CONN_REQ_TXD(connsm) = 1; STATS_INC(ble_ll_conn_stats, conn_req_txd); } } else { @@ -2747,7 +2884,7 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, uint8_t *chanmap) * @return 0: connection not started; 1 connecton started */ int -ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end, uint8_t resolved) +ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end, uint8_t pat) { int rc; uint32_t temp; @@ -2824,23 +2961,9 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end, uint8_t resolved) goto err_slave_start; } - /* WWW: what about master when it makes a connection? It has to do this - properly! */ /* Set the address of device that we are connecting with */ memcpy(&connsm->peer_addr, inita, BLE_DEV_ADDR_LEN); - if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) { - if (resolved) { - connsm->peer_addr_type = BLE_HCI_CONN_PEER_ADDR_RANDOM_IDENT; - } else { - connsm->peer_addr_type = BLE_HCI_CONN_PEER_ADDR_RANDOM; - } - } else { - if (resolved) { - connsm->peer_addr_type = BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT; - } else { - connsm->peer_addr_type = BLE_HCI_CONN_PEER_ADDR_PUBLIC; - } - } + connsm->peer_addr_type = pat; /* Calculate number of used channels; make sure it meets min requirement */ connsm->num_used_chans = ble_ll_conn_calc_used_chans(connsm->chanmap); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_conn_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_hci.c b/net/nimble/controller/src/ble_ll_conn_hci.c index f1b0cd9..08ced85 100644 --- a/net/nimble/controller/src/ble_ll_conn_hci.c +++ b/net/nimble/controller/src/ble_ll_conn_hci.c @@ -30,6 +30,7 @@ #include "controller/ble_ll_conn.h" #include "controller/ble_ll_ctrl.h" #include "controller/ble_ll_scan.h" +#include "controller/ble_ll_adv.h" #include "ble_ll_conn_priv.h" /* @@ -88,7 +89,6 @@ static void ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm) { uint8_t pdu_type; - uint8_t *addr; uint8_t *dptr; struct os_mbuf *m; @@ -98,26 +98,13 @@ ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm) /* Construct first PDU header byte */ pdu_type = BLE_ADV_PDU_TYPE_CONNECT_REQ; - /* Get pointer to our device address */ - if (connsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) { - addr = g_dev_addr; - } else if (connsm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) { - pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; - addr = g_random_addr; - } else { - /* XXX: unsupported for now */ - addr = NULL; - assert(0); - } - /* Set BLE transmit header */ ble_ll_mbuf_init(m, BLE_CONNECT_REQ_LEN, pdu_type); /* Construct the connect request */ dptr = m->om_data; - memcpy(dptr, addr, BLE_DEV_ADDR_LEN); - /* Skip the advertiser's address as we dont know that yet */ + /* Skip inita and adva advertiser's address as we dont know that yet */ dptr += (2 * BLE_DEV_ADDR_LEN); /* Access address */ @@ -142,23 +129,74 @@ ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm) void ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status) { + uint8_t peer_addr_type; + uint8_t enabled; + uint8_t enh_enabled; uint8_t *evbuf; + uint8_t *evdata; + uint8_t *rpa; - if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_COMPLETE)) { + enabled = ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_COMPLETE); + enh_enabled = ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE); + + if (enabled || enh_enabled) { evbuf = os_memblock_get(&g_hci_cmd_pool); if (evbuf) { + /* Put common elements in event */ evbuf[0] = BLE_HCI_EVCODE_LE_META; - evbuf[1] = BLE_HCI_LE_CONN_COMPLETE_LEN; - evbuf[2] = BLE_HCI_LE_SUBEV_CONN_COMPLETE; + if (enh_enabled) { + evbuf[1] = BLE_HCI_LE_ENH_CONN_COMPLETE_LEN; + evbuf[2] = BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE; + } else { + evbuf[1] = BLE_HCI_LE_CONN_COMPLETE_LEN; + evbuf[2] = BLE_HCI_LE_SUBEV_CONN_COMPLETE; + } evbuf[3] = status; - htole16(evbuf + 4, connsm->conn_handle); - evbuf[6] = connsm->conn_role - 1; - evbuf[7] = connsm->peer_addr_type; - memcpy(evbuf + 8, connsm->peer_addr, BLE_DEV_ADDR_LEN); - htole16(evbuf + 14, connsm->conn_itvl); - htole16(evbuf + 16, connsm->slave_latency); - htole16(evbuf + 18, connsm->supervision_tmo); - evbuf[20] = connsm->master_sca; + + if (connsm) { + htole16(evbuf + 4, connsm->conn_handle); + evbuf[6] = connsm->conn_role - 1; + peer_addr_type = connsm->peer_addr_type; + + evdata = evbuf + 14; + if (enh_enabled) { + memset(evdata, 0, 2 * BLE_DEV_ADDR_LEN); + if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + rpa = ble_ll_scan_get_local_rpa(); + } else { + rpa = NULL; + } + } else { + rpa = ble_ll_adv_get_local_rpa(); + } + if (rpa) { + memcpy(evdata, rpa, BLE_DEV_ADDR_LEN); + } + + if (connsm->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + rpa = ble_ll_scan_get_peer_rpa(); + } else { + rpa = ble_ll_adv_get_peer_rpa(); + } + memcpy(evdata + 6, rpa, BLE_DEV_ADDR_LEN); + } + evdata += 12; + } else { + if (peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { + peer_addr_type -= 2; + } + } + + evbuf[7] = peer_addr_type; + memcpy(evbuf + 8, connsm->peer_addr, BLE_DEV_ADDR_LEN); + + htole16(evdata, connsm->conn_itvl); + htole16(evdata + 2, connsm->slave_latency); + htole16(evdata + 4, connsm->supervision_tmo); + evdata[6] = connsm->master_sca; + } ble_ll_hci_event_send(evbuf); } } @@ -341,11 +379,6 @@ ble_ll_conn_create(uint8_t *cmdbuf) return BLE_ERR_INV_HCI_CMD_PARMS; } - /* XXX: not supported */ - if (hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { - return BLE_ERR_UNSUPPORTED; - } - memcpy(&hcc->peer_addr, cmdbuf + 6, BLE_DEV_ADDR_LEN); } @@ -355,11 +388,6 @@ ble_ll_conn_create(uint8_t *cmdbuf) return BLE_ERR_INV_HCI_CMD_PARMS; } - /* XXX: not supported */ - if (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { - return BLE_ERR_UNSUPPORTED; - } - /* Check connection interval, latency and supervision timeoout */ hcc->conn_itvl_min = le16toh(cmdbuf + 13); hcc->conn_itvl_max = le16toh(cmdbuf + 15); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_conn_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h b/net/nimble/controller/src/ble_ll_conn_priv.h index 24a7a1e..7794a6a 100644 --- a/net/nimble/controller/src/ble_ll_conn_priv.h +++ b/net/nimble/controller/src/ble_ll_conn_priv.h @@ -92,8 +92,7 @@ void ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm, struct ble_ll_len_req *req); /* Advertising interface */ -int ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end, - uint8_t resolved); +int ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end, uint8_t pat); /* Link Layer interface */ void ble_ll_conn_module_init(void); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c index ec26019..d6e574d 100644 --- a/net/nimble/controller/src/ble_ll_hci.c +++ b/net/nimble/controller/src/ble_ll_hci.c @@ -663,7 +663,7 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) rc = ble_ll_resolv_enable_cmd(cmdbuf); break; case BLE_HCI_OCF_LE_SET_RPA_TMO: - /* XXX: implement */ + rc = ble_ll_resolv_set_rpa_tmo(cmdbuf); break; #endif case BLE_HCI_OCF_LE_RD_MAX_DATA_LEN: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_resolv.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_resolv.c b/net/nimble/controller/src/ble_ll_resolv.c index 62d85e4..b81d957 100644 --- a/net/nimble/controller/src/ble_ll_resolv.c +++ b/net/nimble/controller/src/ble_ll_resolv.c @@ -36,6 +36,7 @@ uint8_t g_ble_ll_addr_res_enabled; uint8_t g_ble_ll_resolv_list_size; uint8_t g_ble_ll_resolv_list_cnt; +uint32_t g_ble_ll_resolv_rpa_tmo; struct ble_ll_resolv_entry g_ble_ll_resolv_list[NIMBLE_OPT_LL_RESOLV_LIST_SIZE]; @@ -67,7 +68,7 @@ ble_ll_resolv_list_chg_allowed(void) * * @param irk * - * @return int 0: IRK has a non-zero value. 1: IRK is all zero. + * @return int 0: IRK is zero . 1: IRK has non-zero value. */ int ble_ll_resolv_irk_nonzero(uint8_t *irk) @@ -75,10 +76,10 @@ ble_ll_resolv_irk_nonzero(uint8_t *irk) int i; int rc; - rc = 1; + rc = 0; for (i = 0; i < 16; ++i) { if (*irk != 0) { - rc = 0; + rc = 1; break; } ++irk; @@ -178,27 +179,6 @@ ble_ll_resolv_list_find(uint8_t *addr, uint8_t addr_type) } /** - * Is there a match between the device and a device on the resolving list - * - * @param addr - * @param addr_type Public address (0) or random address (1) - * - * @return int - */ -int -ble_ll_resolv_list_match(uint8_t *addr, uint8_t addr_type) -{ - int rc; - /* WWW: will this be used? */ -#ifdef BLE_USES_HW_RESOLV_LIST - rc = ble_hw_resolv_list_match(); -#else - rc = ble_ll_is_on_resolv_list(addr, addr_type); -#endif - return rc; -} - -/** * Add a device to the resolving list * * @return int @@ -292,7 +272,6 @@ ble_ll_resolv_enable_cmd(uint8_t *cmdbuf) g_ble_ll_conn_create_sm) { rc = BLE_ERR_CMD_DISALLOWED; } else { - /* WWW: do we do anything here if we change state? */ g_ble_ll_addr_res_enabled = cmdbuf[0]; rc = BLE_ERR_SUCCESS; } @@ -313,6 +292,41 @@ ble_ll_resolv_local_addr_rd(uint8_t *cmdbuf) } /** + * Set the resolvable private address timeout. + * + * @param cmdbuf + * + * @return int + */ +int +ble_ll_resolv_set_rpa_tmo(uint8_t *cmdbuf) +{ + int rc; + uint16_t tmo_secs; + + tmo_secs = le16toh(cmdbuf); + if ((tmo_secs > 0) && (tmo_secs <= 0xA1B8)) { + g_ble_ll_resolv_rpa_tmo = tmo_secs * OS_TICKS_PER_SEC; + } else { + rc = BLE_ERR_INV_HCI_CMD_PARMS; + } + + return rc; +} + +/** + * Returns the Resolvable Private address timeout, in os ticks + * + * + * @return uint32_t + */ +uint32_t +ble_ll_resolv_get_rpa_tmo(void) +{ + return OS_TICKS_PER_SEC * g_ble_ll_resolv_rpa_tmo; +} + +/** * Called the generate a resolvable private address * * @@ -348,7 +362,68 @@ ble_ll_resolv_gen_priv_addr(struct ble_ll_resolv_entry *rl, int local, /* Calculate hash */ ble_hw_encrypt_block(&ecb); - swap_buf(addr, ecb.cipher_text, 3); + swap_buf(addr, ecb.cipher_text + 13, 3); +} + +/** + * Generate a resolvable private address. + * + * @param addr + * @param addr_type + * @param rpa + * + * @return int + */ +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)) { + ble_ll_resolv_gen_priv_addr(rl, local, rpa); + rc = 1; + } + } + + return rc; +} + +/** + * Resolve a Resolvable Private Address + * + * @param rpa + * @param index + * + * @return int + */ +int +ble_ll_resolv_rpa(uint8_t *rpa, uint8_t *irk) +{ + int rc; + struct ble_encryption_block ecb; + + memcpy(ecb.key, irk, BLE_ENC_BLOCK_SIZE); + memset(ecb.plain_text, 0, BLE_ENC_BLOCK_SIZE); + swap_buf(&ecb.plain_text[13], rpa + 3, 3); + ble_hw_encrypt_block(&ecb); + if ((ecb.cipher_text[15] == rpa[0]) && (ecb.cipher_text[14] == rpa[1]) && + (ecb.cipher_text[13] == rpa[2])) { + rc = 1; + } else { + rc = 0; + } + + return rc; } /** @@ -368,10 +443,25 @@ ble_ll_resolv_enabled(void) void ble_ll_resolv_list_reset(void) { - ble_ll_resolv_list_clr(); g_ble_ll_addr_res_enabled = 0; - /* XXX: deal with HW restrictions */ - g_ble_ll_resolv_list_size = NIMBLE_OPT_LL_RESOLV_LIST_SIZE; + ble_ll_resolv_list_clr(); + ble_ll_resolv_init(); +} + +void +ble_ll_resolv_init(void) +{ + uint8_t hw_size; + + /* Default is 15 minutes */ + g_ble_ll_resolv_rpa_tmo = 15 * 60 * OS_TICKS_PER_SEC; + + hw_size = ble_hw_resolv_list_size(); + if (hw_size > NIMBLE_OPT_LL_RESOLV_LIST_SIZE) { + hw_size = NIMBLE_OPT_LL_RESOLV_LIST_SIZE; + } + g_ble_ll_resolv_list_size = hw_size; + } #endif /* if BLE_LL_CFG_FEAT_LL_PRIVACY == 1 */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d6bbacbd/net/nimble/controller/src/ble_ll_scan.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c index f675ec7..008f632 100644 --- a/net/nimble/controller/src/ble_ll_scan.c +++ b/net/nimble/controller/src/ble_ll_scan.c @@ -26,12 +26,14 @@ #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" #include "controller/ble_phy.h" +#include "controller/ble_hw.h" #include "controller/ble_ll.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_whitelist.h" +#include "controller/ble_ll_resolv.h" #include "hal/hal_cputime.h" #include "hal/hal_gpio.h" @@ -122,7 +124,8 @@ ble_ll_scan_req_backoff(struct ble_ll_scan_sm *scansm, int success) * * @param scansm Pointer to scanning state machine * @param adv_addr Pointer to device address of advertiser - * @param addr_type 0 if public; non-zero if random + * @param addr_type 0 if public; non-zero if random. This is the addr type of + * the advertiser; not our "own address type" */ static void ble_ll_scan_req_pdu_make(struct ble_ll_scan_sm *scansm, uint8_t *adv_addr, @@ -130,8 +133,12 @@ ble_ll_scan_req_pdu_make(struct ble_ll_scan_sm *scansm, uint8_t *adv_addr, { uint8_t *dptr; uint8_t pdu_type; - uint8_t *addr; + uint8_t *scana; struct os_mbuf *m; +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + uint8_t rpa[BLE_DEV_ADDR_LEN]; + struct ble_ll_resolv_entry *rl; +#endif /* Construct first PDU header byte */ pdu_type = BLE_ADV_PDU_TYPE_SCAN_REQ; @@ -144,22 +151,39 @@ ble_ll_scan_req_pdu_make(struct ble_ll_scan_sm *scansm, uint8_t *adv_addr, assert(m != NULL); /* Get pointer to our device address */ - if (scansm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) { - addr = g_dev_addr; - } else if (scansm->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) { - pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; - addr = g_random_addr; + if ((scansm->own_addr_type & 1) == 0) { + scana = g_dev_addr; } else { - /* XXX: unsupported for now */ - addr = NULL; - assert(0); + pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; + scana = g_random_addr; } +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (scansm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + if (ble_ll_is_rpa(adv_addr, adv_addr_type)) { + rl = NULL; + if (scansm->scan_rpa_index >= 0) { + /* Generate a RPA to use for scana */ + rl = &g_ble_ll_resolv_list[scansm->scan_rpa_index]; + } else { + if (ble_ll_resolv_enabled()) { + rl = ble_ll_resolv_list_find(adv_addr, adv_addr_type); + } + } + + if (rl) { + ble_ll_resolv_gen_priv_addr(rl, 1, rpa); + scana = rpa; + } + } + } +#endif + ble_ll_mbuf_init(m, BLE_SCAN_REQ_LEN, pdu_type); /* Construct the scan request */ dptr = m->om_data; - memcpy(dptr, addr, BLE_DEV_ADDR_LEN); + memcpy(dptr, scana, BLE_DEV_ADDR_LEN); memcpy(dptr + BLE_DEV_ADDR_LEN, adv_addr, BLE_DEV_ADDR_LEN); } @@ -185,16 +209,18 @@ ble_ll_scan_find_dup_adv(uint8_t *addr, uint8_t txadd) /* Address type must match */ if (txadd) { if ((adv->sc_adv_flags & BLE_LL_SC_ADV_F_RANDOM_ADDR) == 0) { - continue; + goto next_dup_adv; } } else { if (adv->sc_adv_flags & BLE_LL_SC_ADV_F_RANDOM_ADDR) { - continue; + goto next_dup_adv; } } return adv; } + +next_dup_adv: ++adv; --num_advs; } @@ -237,11 +263,12 @@ ble_ll_scan_is_dup_adv(uint8_t pdu_type, uint8_t txadd, uint8_t *addr) * the list of duplicate addresses when the controller sends an advertising * report to the host. * - * @param addr + * @param addr Pointer to advertisers address or identity address * @param Txadd. TxAdd bit (0 public, random otherwise) + * @param subev Type of advertising report sent (direct or normal). */ void -ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t txadd) +ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t txadd, uint8_t subev) { uint8_t num_advs; struct ble_ll_scan_advertisers *adv; @@ -266,11 +293,11 @@ ble_ll_scan_add_dup_adv(uint8_t *addr, uint8_t txadd) } } - /* - * XXX: need to set correct flag based on type of report being sent - * for now, we dont send direct advertising reports - */ - adv->sc_adv_flags |= BLE_LL_SC_ADV_F_ADV_RPT_SENT; + if (subev == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) { + adv->sc_adv_flags |= BLE_LL_SC_ADV_F_DIRECT_RPT_SENT; + } else { + adv->sc_adv_flags |= BLE_LL_SC_ADV_F_ADV_RPT_SENT; + } } /** @@ -348,24 +375,37 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd) * @param pdu_type * @param txadd * @param rxbuf - * @param rssi + * @param hdr + * @param scansm */ static void ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t txadd, uint8_t *rxbuf, - int8_t rssi) + struct ble_mbuf_hdr *hdr, + struct ble_ll_scan_sm *scansm) { int rc; + int index; uint8_t evtype; uint8_t subev; uint8_t *evbuf; + uint8_t *orig_evbuf; + uint8_t *adv_addr; + uint8_t *inita; + uint8_t addr_type; uint8_t adv_data_len; + uint8_t event_len; + inita = NULL; subev = BLE_HCI_LE_SUBEV_ADV_RPT; if (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND) { - /* XXX: NOTE: the direct advertising report is only used when InitA - is a resolvable private address. We dont support that yet! */ - //subev = BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT; + if (scansm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + inita = rxbuf + BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN; + if ((inita[5] & 0x40) == 0x40) { + subev = BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT; + } + } evtype = BLE_HCI_ADV_RPT_EVTYPE_DIR_IND; + event_len = BLE_HCI_LE_ADV_DIRECT_RPT_LEN; adv_data_len = 0; } else { if (pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) { @@ -377,41 +417,61 @@ ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t txadd, uint8_t *rxbuf, } else { evtype = BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP; } - subev = BLE_HCI_LE_SUBEV_ADV_RPT; - adv_data_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK; adv_data_len -= BLE_DEV_ADDR_LEN; + event_len = BLE_HCI_LE_ADV_RPT_MIN_LEN + adv_data_len; } if (ble_ll_hci_is_le_event_enabled(subev)) { evbuf = os_memblock_get(&g_hci_cmd_pool); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; - evbuf[1] = 12 + adv_data_len; + evbuf[1] = event_len; evbuf[2] = subev; evbuf[3] = 1; /* number of reports */ evbuf[4] = evtype; - /* WWW: Yeah... if we are using private resolvable addresses - we need to deal here. The address type is different... */ - /* XXX: need to deal with resolvable addresses here! */ if (txadd) { - evbuf[5] = BLE_HCI_ADV_OWN_ADDR_RANDOM; + addr_type = BLE_HCI_ADV_OWN_ADDR_RANDOM; } else { - evbuf[5] = BLE_HCI_ADV_OWN_ADDR_PUBLIC; + addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC; } + rxbuf += BLE_LL_PDU_HDR_LEN; - memcpy(evbuf + 6, rxbuf, BLE_DEV_ADDR_LEN); - evbuf[12] = adv_data_len; - memcpy(evbuf + 13, rxbuf + BLE_DEV_ADDR_LEN, - adv_data_len); - evbuf[13 + adv_data_len] = rssi; + if (BLE_MBUF_HDR_RESOLVED(hdr)) { + index = scansm->scan_rpa_index; + adv_addr = g_ble_ll_resolv_list[index].rl_identity_addr; + /* + * NOTE: this looks a bit odd, but the resolved address types + * are 2 greater than the unresolved ones in the spec, so + * we just add 2 here. + */ + addr_type += 2; + } else{ + adv_addr = rxbuf; + } + + orig_evbuf = evbuf; + evbuf += 5; + if (inita) { + evbuf[0] = BLE_HCI_ADV_OWN_ADDR_RANDOM; + memcpy(evbuf + 1, inita, adv_data_len); + evbuf += BLE_DEV_ADDR_LEN + 1; + } else { + evbuf[7] = adv_data_len; + memcpy(evbuf + 8, rxbuf + BLE_DEV_ADDR_LEN, adv_data_len); + evbuf[8 + adv_data_len] = hdr->rxinfo.rssi; + } - rc = ble_ll_hci_event_send(evbuf); + /* The advertisers address type and address are always in event */ + evbuf[0] = addr_type; + memcpy(evbuf + 1, adv_addr, BLE_DEV_ADDR_LEN); + + rc = ble_ll_hci_event_send(orig_evbuf); if (!rc) { /* If filtering, add it to list of duplicate addresses */ if (g_ble_ll_scan_sm.scan_filt_dups) { - ble_ll_scan_add_dup_adv(rxbuf, txadd); + ble_ll_scan_add_dup_adv(adv_addr, txadd, subev); } } } @@ -429,7 +489,7 @@ ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t txadd, uint8_t *rxbuf, * * @return int 0: pdu allowed by filter policy. 1: pdu not allowed */ -int +static int ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf, uint8_t flags) { uint8_t *addr; @@ -474,7 +534,7 @@ ble_ll_scan_chk_filter_policy(uint8_t pdu_type, uint8_t *rxbuf, uint8_t flags) addr = rxbuf + BLE_LL_PDU_HDR_LEN; addr_type = rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK; if (!ble_ll_is_our_devaddr(addr + BLE_DEV_ADDR_LEN, addr_type)) { - if (!chk_inita || !ble_ll_is_resolvable_priv_addr(addr)) { + if (!chk_inita || !ble_ll_is_rpa(addr, addr_type)) { return 1; } } @@ -511,6 +571,14 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, uint8_t chan) ble_phy_encrypt_disable(); #endif +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (ble_ll_resolv_enabled()) { + ble_phy_resolv_list_enable(); + } else { + ble_phy_resolv_list_disable(); + } +#endif + /* Start receiving */ rc = ble_phy_rx(); if (!rc) { @@ -829,10 +897,14 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) { int rc; int chk_send_req; - int chk_whitelist; + int chk_wl; + int index; + int resolved; uint8_t pdu_type; uint8_t addr_type; + uint8_t peer_addr_type; uint8_t *adv_addr; + uint8_t *peer; uint8_t *rxbuf; struct ble_mbuf_hdr *ble_hdr; struct ble_ll_scan_sm *scansm; @@ -863,12 +935,13 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) /* Get pdu type, pointer to address and address "type" */ rxbuf = rxpdu->om_data; pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK; - adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN; + peer = rxbuf + BLE_LL_PDU_HDR_LEN; if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) { addr_type = BLE_ADDR_TYPE_RANDOM; } else { addr_type = BLE_ADDR_TYPE_PUBLIC; } + peer_addr_type = addr_type; /* Determine if request may be sent and if whitelist needs to be checked */ chk_send_req = 0; @@ -878,34 +951,51 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) if (scansm->scan_type == BLE_SCAN_TYPE_ACTIVE) { chk_send_req = 1; } - chk_whitelist = 1; + chk_wl = 1; break; case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND: case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND: - chk_whitelist = 1; + chk_wl = 1; break; default: - chk_whitelist = 0; + chk_wl = 0; break; } - /* Set device match bit if we are whitelisting */ - if (chk_whitelist && (scansm->scan_filt_policy & 1)) { - /* Check if device is on whitelist. If not, leave */ - if (!ble_ll_whitelist_match(adv_addr, addr_type)) { - return -1; + ble_hdr = BLE_MBUF_HDR_PTR(rxpdu); + if ((scansm->scan_filt_policy & 1) == 0) { + chk_wl = 0; + } + resolved = 0; + + index = -1; +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + if (ble_ll_is_rpa(peer, peer_addr_type) && ble_ll_resolv_enabled()) { + index = ble_hw_resolv_list_match(); + if (index >= 0) { + ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED; + peer = g_ble_ll_resolv_list[index].rl_identity_addr; + peer_addr_type = g_ble_ll_resolv_list[index].rl_addr_type; + resolved = 1; + } else { + if (chk_wl) { + goto scan_rx_isr_exit; + } } - ble_hdr = BLE_MBUF_HDR_PTR(rxpdu); - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH; } +#endif + scansm->scan_rpa_index = index; + + /* If whitelist enabled, check to see if device is in the white list */ + if (chk_wl && !ble_ll_whitelist_match(peer, peer_addr_type, resolved)) { + return -1; + } + ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH; /* Should we send a scan request? */ if (chk_send_req) { - /* - * Check to see if we have received a scan response from this - * advertisor. If so, no need to send scan request. - */ - if (ble_ll_scan_have_rxd_scan_rsp(adv_addr, addr_type)) { + /* Dont send scan request if we have sent one to this advertiser */ + if (ble_ll_scan_have_rxd_scan_rsp(peer, peer_addr_type)) { return -1; } @@ -916,6 +1006,7 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) --scansm->backoff_count; if (scansm->backoff_count == 0) { /* Setup to transmit the scan request */ + adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN; ble_ll_scan_req_pdu_make(scansm, adv_addr, addr_type); rc = ble_phy_tx(scansm->scan_req_pdu, BLE_PHY_TRANSITION_TX_RX); @@ -1006,8 +1097,11 @@ ble_ll_scan_wfr_timer_exp(void) void ble_ll_scan_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) { + int index; uint8_t *adv_addr; uint8_t *adva; + uint8_t *ident_addr; + uint8_t ident_addr_type; uint8_t txadd; uint8_t rxadd; uint8_t scan_rsp_chk; @@ -1032,13 +1126,26 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) txadd = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK; adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN; + ident_addr = adv_addr; + ident_addr_type = txadd; + + scansm = &g_ble_ll_scan_sm; +#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) + index = scansm->scan_rpa_index; + if (index >= 0) { + ident_addr = g_ble_ll_resolv_list[index].rl_identity_addr; + ident_addr_type = g_ble_ll_resolv_list[index].rl_addr_type; + } +#else + index = -1; +#endif + /* * XXX: The BLE spec is a bit unclear here. What if we get a scan * response from an advertiser that we did not send a request to? * Do we send an advertising report? Do we add it to list of devices * that we have heard a scan response from? */ - scansm = &g_ble_ll_scan_sm; if (ptype == BLE_ADV_PDU_TYPE_SCAN_RSP) { /* * If this is a scan response in reply to a request we sent we need @@ -1056,7 +1163,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) if (((txadd && rxadd) || ((txadd + rxadd) == 0)) && !memcmp(adv_addr, adva, BLE_DEV_ADDR_LEN)) { /* We have received a scan response. Add to list */ - ble_ll_scan_add_scan_rsp_adv(adv_addr, txadd); + ble_ll_scan_add_scan_rsp_adv(ident_addr, ident_addr_type); /* Perform scan request backoff procedure */ ble_ll_scan_req_backoff(scansm, 1); @@ -1066,13 +1173,13 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) /* Filter duplicates */ if (scansm->scan_filt_dups) { - if (ble_ll_scan_is_dup_adv(ptype, txadd, adv_addr)) { + if (ble_ll_scan_is_dup_adv(ptype, ident_addr_type, ident_addr)) { goto scan_continue; } } /* Send the advertising report */ - ble_ll_hci_send_adv_report(ptype, txadd, rxbuf, hdr->rxinfo.rssi); + ble_ll_hci_send_adv_report(ptype, ident_addr_type, rxbuf, hdr, scansm); scan_continue: /* @@ -1237,6 +1344,61 @@ ble_ll_scan_enabled(void) return (int)g_ble_ll_scan_sm.scan_enabled; } +/** + * Returns the peer resolvable private address of last device connecting to us + * + * @return uint8_t* + */ +uint8_t * +ble_ll_scan_get_peer_rpa(void) +{ + struct ble_ll_scan_sm *scansm; + + /* XXX: should this go into IRK list or connection? */ + scansm = &g_ble_ll_scan_sm; + return scansm->scan_peer_rpa; +} + +/** + * Returns the local resolvable private address currently being using by + * the scanner/initiator + * + * @return uint8_t* + */ +uint8_t * +ble_ll_scan_get_local_rpa(void) +{ + uint8_t *rpa; + struct ble_ll_scan_sm *scansm; + + scansm = &g_ble_ll_scan_sm; + + /* + * The RPA we used is in connect request or scan request and is the + * first address in the packet + */ + rpa = scansm->scan_req_pdu->om_data; + + return rpa; +} + +/** + * Set the Resolvable Private Address in the scanning (or initiating) state + * machine. + * + * XXX: should this go into IRK list or connection? + * + * @param rpa + */ +void +ble_ll_scan_set_peer_rpa(uint8_t *rpa) +{ + struct ble_ll_scan_sm *scansm; + + scansm = &g_ble_ll_scan_sm; + memcpy(scansm->scan_peer_rpa, rpa, BLE_DEV_ADDR_LEN); +} + /* Returns the PDU allocated by the scanner */ struct os_mbuf * ble_ll_scan_get_pdu(void) @@ -1244,13 +1406,6 @@ ble_ll_scan_get_pdu(void) return g_ble_ll_scan_sm.scan_req_pdu; } -/* Returns the global scanning state machine */ -struct ble_ll_scan_sm * -ble_ll_scan_sm_get(void) -{ - return &g_ble_ll_scan_sm; -} - /* Returns true if whitelist is enabled for scanning */ int ble_ll_scan_whitelist_enabled(void) @@ -1320,4 +1475,3 @@ ble_ll_scan_init(void) sizeof(struct ble_mbuf_hdr)); assert(scansm->scan_req_pdu != NULL); } -
