Skip to content
Permalink
Browse files

Bluetooth: controller: split: Port h/w privacy feature

Ported h/w based LL privacy to ULL/LLL split architecture.

Fixes #14675.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
  • Loading branch information...
cvinayak authored and nashif committed May 9, 2019
1 parent c5c87c3 commit b928cef69ccecb1cd8c425569ef9d1dfaf9ccc24
@@ -119,7 +119,7 @@ if(CONFIG_BT_LL_SW_SPLIT)
endif()
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_FILTER
ll_sw/nordic/lll/lll_filter.c
ll_sw/ull_filter.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_HCI_MESH_EXT
@@ -66,7 +66,7 @@ u8_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode);

u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t filter_policy, u8_t peer_addr_type,
u8_t *p_peer_addr, u8_t own_addr_type,
u8_t *peer_addr, u8_t own_addr_type,
u16_t interval, u16_t latency, u16_t timeout);
u8_t ll_connect_disable(void **rx);
u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
@@ -7,11 +7,21 @@
#define WL_SIZE 8
#define FILTER_IDX_NONE 0xFF

struct ll_filter {
struct lll_filter {
u8_t enable_bitmask;
u8_t addr_type_bitmask;
u8_t bdaddr[WL_SIZE][BDADDR_SIZE];
};

struct ll_filter *ctrl_filter_get(bool whitelist);
void ll_adv_scan_state_cb(u8_t bm);
extern bt_addr_t *ull_filter_lll_lrpa_get(u8_t rl_idx);
extern u8_t *ull_filter_lll_irks_get(u8_t *count);
extern u8_t ull_filter_lll_rl_idx(bool whitelist, u8_t devmatch_id);
extern u8_t ull_filter_lll_rl_irk_idx(u8_t irkmatch_id);
extern bool ull_filter_lll_irk_whitelisted(u8_t rl_idx);
extern struct lll_filter *ull_filter_lll_get(bool whitelist);
extern bool ull_filter_lll_rl_idx_allowed(u8_t irkmatch_ok, u8_t rl_idx);
extern bool ull_filter_lll_rl_addr_allowed(u8_t id_addr_type, u8_t *id_addr,
u8_t *rl_idx);
extern bool ull_filter_lll_rl_addr_resolve(u8_t id_addr_type, u8_t *id_addr,
u8_t rl_idx);
extern bool ull_filter_lll_rl_enabled(void);
@@ -27,8 +27,8 @@
#include "lll.h"
#include "lll_vendor.h"
#include "lll_adv.h"
#include "lll_filter.h"
#include "lll_chan.h"
#include "lll_filter.h"

#include "lll_internal.h"
#include "lll_tim_internal.h"
@@ -68,7 +68,8 @@ static inline int isr_rx_sr_report(struct pdu_adv *pdu_adv_rx,
static inline bool isr_rx_ci_check(struct lll_adv *lll, struct pdu_adv *adv,
struct pdu_adv *ci, u8_t devmatch_ok,
u8_t *rl_idx);
static inline bool isr_rx_ci_tgta_check(struct pdu_adv *adv, struct pdu_adv *ci,
static inline bool isr_rx_ci_tgta_check(struct lll_adv *lll,
struct pdu_adv *adv, struct pdu_adv *ci,
u8_t rl_idx);
static inline bool isr_rx_ci_adva_check(struct pdu_adv *adv,
struct pdu_adv *ci);
@@ -167,9 +168,9 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)


#if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) {
struct ll_filter *filter =
ctrl_filter_get(!!(_radio.advertiser.filter_policy));
if (ull_filter_lll_rl_enabled()) {
struct lll_filter *filter =
ull_filter_lll_get(!!(lll->filter_policy));

radio_filter_configure(filter->enable_bitmask,
filter->addr_type_bitmask,
@@ -181,7 +182,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* Setup Radio Filter */
if (lll->filter_policy) {

struct ll_filter *wl = ctrl_filter_get(true);
struct lll_filter *wl = ull_filter_lll_get(true);

radio_filter_configure(wl->enable_bitmask,
wl->addr_type_bitmask,
@@ -339,8 +340,8 @@ static void isr_tx(void *param)
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */

#if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) {
u8_t count, *irks = ctrl_irks_get(&count);
if (ull_filter_lll_rl_enabled()) {
u8_t count, *irks = ull_filter_lll_irks_get(&count);

radio_ar_configure(count, irks);
}
@@ -616,7 +617,7 @@ static inline int isr_rx_pdu(struct lll_adv *lll,
struct pdu_adv *pdu_rx, *pdu_adv;
#if defined(CONFIG_BT_CTLR_PRIVACY)
/* An IRK match implies address resolution enabled */
u8_t rl_idx = irkmatch_ok ? ctrl_rl_irk_idx(irkmatch_id) :
u8_t rl_idx = irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
FILTER_IDX_NONE;
#else
u8_t rl_idx = FILTER_IDX_NONE;
@@ -719,6 +720,15 @@ static inline int isr_rx_pdu(struct lll_adv *lll,

if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
ftr->extra = ull_pdu_rx_alloc();
if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
*((u8_t *)ftr->extra) = irkmatch_ok ?
rl_idx :
FILTER_IDX_NONE;
}
} else if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
ftr->extra = (void *)((u32_t)(irkmatch_ok ?
rl_idx :
FILTER_IDX_NONE));
}

ull_rx_put(rx->hdr.link, rx);
@@ -736,11 +746,12 @@ static inline bool isr_rx_sr_check(struct lll_adv *lll, struct pdu_adv *adv,
u8_t *rl_idx)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
return ((((_radio.advertiser.filter_policy & 0x01) == 0) &&
ctrl_rl_addr_allowed(sr->tx_addr, sr->scan_req.scan_addr,
rl_idx)) ||
(((_radio.advertiser.filter_policy & 0x01) != 0) &&
(devmatch_ok || ctrl_irk_whitelisted(*rl_idx)))) &&
return ((((lll->filter_policy & 0x01) == 0) &&
ull_filter_lll_rl_addr_allowed(sr->tx_addr,
sr->scan_req.scan_addr,
rl_idx)) ||
(((lll->filter_policy & 0x01) != 0) &&
(devmatch_ok || ull_filter_lll_irk_whitelisted(*rl_idx)))) &&
isr_rx_sr_adva_check(adv, sr);
#else
return (((lll->filter_policy & 0x01) == 0U) || devmatch_ok) &&
@@ -796,22 +807,23 @@ static inline bool isr_rx_ci_check(struct lll_adv *lll, struct pdu_adv *adv,
/* LL 4.3.2: filter policy shall be ignored for directed adv */
if (adv->type == PDU_ADV_TYPE_DIRECT_IND) {
#if defined(CONFIG_BT_CTLR_PRIVACY)
return ctrl_rl_addr_allowed(ci->tx_addr,
ci->connect_ind.init_addr,
rl_idx) &&
return ull_filter_lll_rl_addr_allowed(ci->tx_addr,
ci->connect_ind.init_addr,
rl_idx) &&
#else
return (1) &&
#endif
isr_rx_ci_adva_check(adv, ci) &&
isr_rx_ci_tgta_check(adv, ci, *rl_idx);
isr_rx_ci_tgta_check(lll, adv, ci, *rl_idx);
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
return ((((_radio.advertiser.filter_policy & 0x02) == 0) &&
ctrl_rl_addr_allowed(ci->tx_addr, ci->connect_ind.init_addr,
rl_idx)) ||
(((_radio.advertiser.filter_policy & 0x02) != 0) &&
(devmatch_ok || ctrl_irk_whitelisted(*rl_idx)))) &&
return ((((lll->filter_policy & 0x02) == 0) &&
ull_filter_lll_rl_addr_allowed(ci->tx_addr,
ci->connect_ind.init_addr,
rl_idx)) ||
(((lll->filter_policy & 0x02) != 0) &&
(devmatch_ok || ull_filter_lll_irk_whitelisted(*rl_idx)))) &&
isr_rx_ci_adva_check(adv, ci);
#else
return (((lll->filter_policy & 0x02) == 0) ||
@@ -820,12 +832,13 @@ static inline bool isr_rx_ci_check(struct lll_adv *lll, struct pdu_adv *adv,
#endif /* CONFIG_BT_CTLR_PRIVACY */
}

static inline bool isr_rx_ci_tgta_check(struct pdu_adv *adv, struct pdu_adv *ci,
static inline bool isr_rx_ci_tgta_check(struct lll_adv *lll,
struct pdu_adv *adv, struct pdu_adv *ci,
u8_t rl_idx)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
if (rl_idx != FILTER_IDX_NONE) {
return rl_idx == _radio.advertiser.rl_idx;
return rl_idx == lll->rl_idx;
}
#endif /* CONFIG_BT_CTLR_PRIVACY */
return (adv->rx_addr == ci->tx_addr) &&
@@ -34,6 +34,10 @@ struct lll_adv {
u8_t is_mesh:1;
#endif /* CONFIG_BT_HCI_MESH_EXT */

#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t rl_idx;
#endif /* CONFIG_BT_CTLR_PRIVACY */

struct lll_adv_pdu adv_data;
struct lll_adv_pdu scan_rsp;
};
@@ -26,13 +26,12 @@
#include "lll_scan.h"
#include "lll_conn.h"
#include "lll_chan.h"
#include "lll_filter.h"

#include "lll_internal.h"
#include "lll_tim_internal.h"
#include "lll_prof_internal.h"

#include "lll_filter.h"

#define LOG_MODULE_NAME bt_ctlr_llsw_nordic_lll_scan
#include "common/log.h"
#include <soc.h>
@@ -171,10 +170,10 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
radio_switch_complete_and_tx(0, 0, 0, 0);

#if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) {
struct ll_filter *filter =
ctrl_filter_get(!!(lll->filter_policy & 0x1));
u8_t count, *irks = ctrl_irks_get(&count);
if (ull_filter_lll_rl_enabled()) {
struct lll_filter *filter =
ull_filter_lll_get(!!(lll->filter_policy & 0x1));
u8_t count, *irks = ull_filter_lll_irks_get(&count);

radio_filter_configure(filter->enable_bitmask,
filter->addr_type_bitmask,
@@ -188,7 +187,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* Setup Radio Filter */
if (lll->filter_policy) {

struct ll_filter *wl = ctrl_filter_get(true);
struct lll_filter *wl = ull_filter_lll_get(true);

radio_filter_configure(wl->enable_bitmask,
wl->addr_type_bitmask,
@@ -340,6 +339,7 @@ static void ticker_op_start_cb(u32_t status, void *param)

static void isr_rx(void *param)
{
struct lll_scan *lll = (void *)param;
u8_t trx_done;
u8_t crc_ok;
u8_t devmatch_ok;
@@ -384,19 +384,19 @@ static void isr_rx(void *param)
}

#if defined(CONFIG_BT_CTLR_PRIVACY)
rl_idx = devmatch_ok ? ctrl_rl_idx(!!(_radio.scanner.filter_policy &
0x01),
devmatch_id) :
irkmatch_ok ? ctrl_rl_irk_idx(irkmatch_id) :
FILTER_IDX_NONE;
rl_idx = devmatch_ok ?
ull_filter_lll_rl_idx(!!(lll->filter_policy & 0x01),
devmatch_id) :
irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
FILTER_IDX_NONE;
#else
rl_idx = FILTER_IDX_NONE;
#endif
if (crc_ok && isr_rx_scan_check(param, irkmatch_ok, devmatch_ok,
if (crc_ok && isr_rx_scan_check(lll, irkmatch_ok, devmatch_ok,
rl_idx)) {
u32_t err;

err = isr_rx_pdu(param, devmatch_ok, devmatch_id, irkmatch_ok,
err = isr_rx_pdu(lll, devmatch_ok, devmatch_id, irkmatch_ok,
irkmatch_id, rl_idx, rssi_ready);
if (!err) {
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
@@ -408,7 +408,7 @@ static void isr_rx(void *param)
}

isr_rx_do_close:
radio_isr_set(isr_done, param);
radio_isr_set(isr_done, lll);
radio_disable();
}

@@ -440,8 +440,8 @@ static void isr_tx(void *param)
LL_ASSERT(!radio_is_ready());

#if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) {
u8_t count, *irks = ctrl_irks_get(&count);
if (ull_filter_lll_rl_enabled()) {
u8_t count, *irks = ull_filter_lll_irks_get(&count);

radio_ar_configure(count, irks);
}
@@ -493,8 +493,8 @@ static void isr_done(void *param)
radio_rssi_measure();

#if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) {
u8_t count, *irks = ctrl_irks_get(&count);
if (ull_filter_lll_rl_enabled()) {
u8_t count, *irks = ull_filter_lll_irks_get(&count);

radio_ar_configure(count, irks);
}
@@ -590,10 +590,11 @@ static inline bool isr_rx_scan_check(struct lll_scan *lll, u8_t irkmatch_ok,
u8_t devmatch_ok, u8_t rl_idx)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
return (((_radio.scanner.filter_policy & 0x01) == 0) &&
(!devmatch_ok || ctrl_rl_idx_allowed(irkmatch_ok, rl_idx))) ||
(((_radio.scanner.filter_policy & 0x01) != 0) &&
(devmatch_ok || ctrl_irk_whitelisted(rl_idx)));
return (((lll->filter_policy & 0x01) == 0) &&
(!devmatch_ok || ull_filter_lll_rl_idx_allowed(irkmatch_ok,
rl_idx))) ||
(((lll->filter_policy & 0x01) != 0) &&
(devmatch_ok || ull_filter_lll_irk_whitelisted(rl_idx)));
#else
return ((lll->filter_policy & 0x01) == 0U) ||
devmatch_ok;
@@ -676,8 +677,8 @@ static inline u32_t isr_rx_pdu(struct lll_scan *lll, u8_t devmatch_ok,
pdu_tx->rx_addr = pdu_adv_rx->tx_addr;
pdu_tx->len = sizeof(struct pdu_adv_connect_ind);
#if defined(CONFIG_BT_CTLR_PRIVACY)
lrpa = ctrl_lrpa_get(rl_idx);
if (_radio.scanner.rpa_gen && lrpa) {
lrpa = ull_filter_lll_lrpa_get(rl_idx);
if (lll->rpa_gen && lrpa) {
pdu_tx->tx_addr = 1;
memcpy(&pdu_tx->connect_ind.init_addr[0], lrpa->val,
BDADDR_SIZE);
@@ -777,6 +778,15 @@ static inline u32_t isr_rx_pdu(struct lll_scan *lll, u8_t devmatch_ok,

if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
ftr->extra = ull_pdu_rx_alloc();
if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
*((u8_t *)ftr->extra) = irkmatch_ok ?
rl_idx :
FILTER_IDX_NONE;
}
} else if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY)) {
ftr->extra = (void *)((u32_t)(irkmatch_ok ?
rl_idx :
FILTER_IDX_NONE));
}

ull_rx_put(rx->hdr.link, rx);
@@ -815,8 +825,8 @@ static inline u32_t isr_rx_pdu(struct lll_scan *lll, u8_t devmatch_ok,
pdu_tx->rx_addr = pdu_adv_rx->tx_addr;
pdu_tx->len = sizeof(struct pdu_adv_scan_req);
#if defined(CONFIG_BT_CTLR_PRIVACY)
lrpa = ctrl_lrpa_get(rl_idx);
if (_radio.scanner.rpa_gen && lrpa) {
lrpa = ull_filter_lll_lrpa_get(rl_idx);
if (lll->rpa_gen && lrpa) {
pdu_tx->tx_addr = 1;
memcpy(&pdu_tx->scan_req.scan_addr[0], lrpa->val,
BDADDR_SIZE);
@@ -941,10 +951,11 @@ static inline bool isr_scan_tgta_check(struct lll_scan *lll, bool init,
bool *dir_report)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_addr_resolve(pdu->rx_addr,
pdu->direct_ind.tgt_addr, rl_idx)) {
if (ull_filter_lll_rl_addr_resolve(pdu->rx_addr,
pdu->direct_ind.tgt_addr, rl_idx)) {
return true;
} else if (init && _radio.scanner.rpa_gen && ctrl_lrpa_get(rl_idx)) {
} else if (init && lll->rpa_gen &&
ull_filter_lll_lrpa_get(rl_idx)) {
/* Initiator generating RPAs, and could not resolve TargetA:
* discard
*/

0 comments on commit b928cef

Please sign in to comment.
You can’t perform that action at this time.