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>
This commit is contained in:
Vinayak Kariappa Chettimada 2019-05-09 18:39:26 +05:30 committed by Anas Nashif
commit b928cef69c
14 changed files with 935 additions and 1006 deletions

View file

@ -119,7 +119,7 @@ if(CONFIG_BT_LL_SW_SPLIT)
endif() endif()
zephyr_library_sources_ifdef( zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_FILTER CONFIG_BT_CTLR_FILTER
ll_sw/nordic/lll/lll_filter.c ll_sw/ull_filter.c
) )
zephyr_library_sources_ifdef( zephyr_library_sources_ifdef(
CONFIG_BT_HCI_MESH_EXT CONFIG_BT_HCI_MESH_EXT

View file

@ -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 ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t filter_policy, u8_t peer_addr_type, 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); u16_t interval, u16_t latency, u16_t timeout);
u8_t ll_connect_disable(void **rx); 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, u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,

View file

@ -7,11 +7,21 @@
#define WL_SIZE 8 #define WL_SIZE 8
#define FILTER_IDX_NONE 0xFF #define FILTER_IDX_NONE 0xFF
struct ll_filter { struct lll_filter {
u8_t enable_bitmask; u8_t enable_bitmask;
u8_t addr_type_bitmask; u8_t addr_type_bitmask;
u8_t bdaddr[WL_SIZE][BDADDR_SIZE]; u8_t bdaddr[WL_SIZE][BDADDR_SIZE];
}; };
struct ll_filter *ctrl_filter_get(bool whitelist); extern bt_addr_t *ull_filter_lll_lrpa_get(u8_t rl_idx);
void ll_adv_scan_state_cb(u8_t bm); 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);

View file

@ -27,8 +27,8 @@
#include "lll.h" #include "lll.h"
#include "lll_vendor.h" #include "lll_vendor.h"
#include "lll_adv.h" #include "lll_adv.h"
#include "lll_filter.h"
#include "lll_chan.h" #include "lll_chan.h"
#include "lll_filter.h"
#include "lll_internal.h" #include "lll_internal.h"
#include "lll_tim_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, static inline bool isr_rx_ci_check(struct lll_adv *lll, struct pdu_adv *adv,
struct pdu_adv *ci, u8_t devmatch_ok, struct pdu_adv *ci, u8_t devmatch_ok,
u8_t *rl_idx); 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); u8_t rl_idx);
static inline bool isr_rx_ci_adva_check(struct pdu_adv *adv, static inline bool isr_rx_ci_adva_check(struct pdu_adv *adv,
struct pdu_adv *ci); 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 defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) { if (ull_filter_lll_rl_enabled()) {
struct ll_filter *filter = struct lll_filter *filter =
ctrl_filter_get(!!(_radio.advertiser.filter_policy)); ull_filter_lll_get(!!(lll->filter_policy));
radio_filter_configure(filter->enable_bitmask, radio_filter_configure(filter->enable_bitmask,
filter->addr_type_bitmask, filter->addr_type_bitmask,
@ -181,7 +182,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* Setup Radio Filter */ /* Setup Radio Filter */
if (lll->filter_policy) { 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, radio_filter_configure(wl->enable_bitmask,
wl->addr_type_bitmask, wl->addr_type_bitmask,
@ -339,8 +340,8 @@ static void isr_tx(void *param)
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */ #endif /* CONFIG_BT_CTLR_PROFILE_ISR */
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) { if (ull_filter_lll_rl_enabled()) {
u8_t count, *irks = ctrl_irks_get(&count); u8_t count, *irks = ull_filter_lll_irks_get(&count);
radio_ar_configure(count, irks); 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; struct pdu_adv *pdu_rx, *pdu_adv;
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
/* An IRK match implies address resolution enabled */ /* 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; FILTER_IDX_NONE;
#else #else
u8_t rl_idx = FILTER_IDX_NONE; 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)) { if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
ftr->extra = ull_pdu_rx_alloc(); 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); 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) u8_t *rl_idx)
{ {
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
return ((((_radio.advertiser.filter_policy & 0x01) == 0) && return ((((lll->filter_policy & 0x01) == 0) &&
ctrl_rl_addr_allowed(sr->tx_addr, sr->scan_req.scan_addr, ull_filter_lll_rl_addr_allowed(sr->tx_addr,
rl_idx)) || sr->scan_req.scan_addr,
(((_radio.advertiser.filter_policy & 0x01) != 0) && rl_idx)) ||
(devmatch_ok || ctrl_irk_whitelisted(*rl_idx)))) && (((lll->filter_policy & 0x01) != 0) &&
(devmatch_ok || ull_filter_lll_irk_whitelisted(*rl_idx)))) &&
isr_rx_sr_adva_check(adv, sr); isr_rx_sr_adva_check(adv, sr);
#else #else
return (((lll->filter_policy & 0x01) == 0U) || devmatch_ok) && 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 */ /* LL 4.3.2: filter policy shall be ignored for directed adv */
if (adv->type == PDU_ADV_TYPE_DIRECT_IND) { if (adv->type == PDU_ADV_TYPE_DIRECT_IND) {
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
return ctrl_rl_addr_allowed(ci->tx_addr, return ull_filter_lll_rl_addr_allowed(ci->tx_addr,
ci->connect_ind.init_addr, ci->connect_ind.init_addr,
rl_idx) && rl_idx) &&
#else #else
return (1) && return (1) &&
#endif #endif
isr_rx_ci_adva_check(adv, ci) && 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) #if defined(CONFIG_BT_CTLR_PRIVACY)
return ((((_radio.advertiser.filter_policy & 0x02) == 0) && return ((((lll->filter_policy & 0x02) == 0) &&
ctrl_rl_addr_allowed(ci->tx_addr, ci->connect_ind.init_addr, ull_filter_lll_rl_addr_allowed(ci->tx_addr,
rl_idx)) || ci->connect_ind.init_addr,
(((_radio.advertiser.filter_policy & 0x02) != 0) && rl_idx)) ||
(devmatch_ok || ctrl_irk_whitelisted(*rl_idx)))) && (((lll->filter_policy & 0x02) != 0) &&
(devmatch_ok || ull_filter_lll_irk_whitelisted(*rl_idx)))) &&
isr_rx_ci_adva_check(adv, ci); isr_rx_ci_adva_check(adv, ci);
#else #else
return (((lll->filter_policy & 0x02) == 0) || 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 */ #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) u8_t rl_idx)
{ {
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (rl_idx != FILTER_IDX_NONE) { if (rl_idx != FILTER_IDX_NONE) {
return rl_idx == _radio.advertiser.rl_idx; return rl_idx == lll->rl_idx;
} }
#endif /* CONFIG_BT_CTLR_PRIVACY */ #endif /* CONFIG_BT_CTLR_PRIVACY */
return (adv->rx_addr == ci->tx_addr) && return (adv->rx_addr == ci->tx_addr) &&

View file

@ -34,6 +34,10 @@ struct lll_adv {
u8_t is_mesh:1; u8_t is_mesh:1;
#endif /* CONFIG_BT_HCI_MESH_EXT */ #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 adv_data;
struct lll_adv_pdu scan_rsp; struct lll_adv_pdu scan_rsp;
}; };

View file

@ -26,13 +26,12 @@
#include "lll_scan.h" #include "lll_scan.h"
#include "lll_conn.h" #include "lll_conn.h"
#include "lll_chan.h" #include "lll_chan.h"
#include "lll_filter.h"
#include "lll_internal.h" #include "lll_internal.h"
#include "lll_tim_internal.h" #include "lll_tim_internal.h"
#include "lll_prof_internal.h" #include "lll_prof_internal.h"
#include "lll_filter.h"
#define LOG_MODULE_NAME bt_ctlr_llsw_nordic_lll_scan #define LOG_MODULE_NAME bt_ctlr_llsw_nordic_lll_scan
#include "common/log.h" #include "common/log.h"
#include <soc.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); radio_switch_complete_and_tx(0, 0, 0, 0);
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) { if (ull_filter_lll_rl_enabled()) {
struct ll_filter *filter = struct lll_filter *filter =
ctrl_filter_get(!!(lll->filter_policy & 0x1)); ull_filter_lll_get(!!(lll->filter_policy & 0x1));
u8_t count, *irks = ctrl_irks_get(&count); u8_t count, *irks = ull_filter_lll_irks_get(&count);
radio_filter_configure(filter->enable_bitmask, radio_filter_configure(filter->enable_bitmask,
filter->addr_type_bitmask, filter->addr_type_bitmask,
@ -188,7 +187,7 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
/* Setup Radio Filter */ /* Setup Radio Filter */
if (lll->filter_policy) { 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, radio_filter_configure(wl->enable_bitmask,
wl->addr_type_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) static void isr_rx(void *param)
{ {
struct lll_scan *lll = (void *)param;
u8_t trx_done; u8_t trx_done;
u8_t crc_ok; u8_t crc_ok;
u8_t devmatch_ok; u8_t devmatch_ok;
@ -384,19 +384,19 @@ static void isr_rx(void *param)
} }
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
rl_idx = devmatch_ok ? ctrl_rl_idx(!!(_radio.scanner.filter_policy & rl_idx = devmatch_ok ?
0x01), ull_filter_lll_rl_idx(!!(lll->filter_policy & 0x01),
devmatch_id) : devmatch_id) :
irkmatch_ok ? ctrl_rl_irk_idx(irkmatch_id) : irkmatch_ok ? ull_filter_lll_rl_irk_idx(irkmatch_id) :
FILTER_IDX_NONE; FILTER_IDX_NONE;
#else #else
rl_idx = FILTER_IDX_NONE; rl_idx = FILTER_IDX_NONE;
#endif #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)) { rl_idx)) {
u32_t err; 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); irkmatch_id, rl_idx, rssi_ready);
if (!err) { if (!err) {
#if defined(CONFIG_BT_CTLR_PROFILE_ISR) #if defined(CONFIG_BT_CTLR_PROFILE_ISR)
@ -408,7 +408,7 @@ static void isr_rx(void *param)
} }
isr_rx_do_close: isr_rx_do_close:
radio_isr_set(isr_done, param); radio_isr_set(isr_done, lll);
radio_disable(); radio_disable();
} }
@ -440,8 +440,8 @@ static void isr_tx(void *param)
LL_ASSERT(!radio_is_ready()); LL_ASSERT(!radio_is_ready());
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) { if (ull_filter_lll_rl_enabled()) {
u8_t count, *irks = ctrl_irks_get(&count); u8_t count, *irks = ull_filter_lll_irks_get(&count);
radio_ar_configure(count, irks); radio_ar_configure(count, irks);
} }
@ -493,8 +493,8 @@ static void isr_done(void *param)
radio_rssi_measure(); radio_rssi_measure();
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_enabled()) { if (ull_filter_lll_rl_enabled()) {
u8_t count, *irks = ctrl_irks_get(&count); u8_t count, *irks = ull_filter_lll_irks_get(&count);
radio_ar_configure(count, irks); 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) u8_t devmatch_ok, u8_t rl_idx)
{ {
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
return (((_radio.scanner.filter_policy & 0x01) == 0) && return (((lll->filter_policy & 0x01) == 0) &&
(!devmatch_ok || ctrl_rl_idx_allowed(irkmatch_ok, rl_idx))) || (!devmatch_ok || ull_filter_lll_rl_idx_allowed(irkmatch_ok,
(((_radio.scanner.filter_policy & 0x01) != 0) && rl_idx))) ||
(devmatch_ok || ctrl_irk_whitelisted(rl_idx))); (((lll->filter_policy & 0x01) != 0) &&
(devmatch_ok || ull_filter_lll_irk_whitelisted(rl_idx)));
#else #else
return ((lll->filter_policy & 0x01) == 0U) || return ((lll->filter_policy & 0x01) == 0U) ||
devmatch_ok; 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->rx_addr = pdu_adv_rx->tx_addr;
pdu_tx->len = sizeof(struct pdu_adv_connect_ind); pdu_tx->len = sizeof(struct pdu_adv_connect_ind);
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
lrpa = ctrl_lrpa_get(rl_idx); lrpa = ull_filter_lll_lrpa_get(rl_idx);
if (_radio.scanner.rpa_gen && lrpa) { if (lll->rpa_gen && lrpa) {
pdu_tx->tx_addr = 1; pdu_tx->tx_addr = 1;
memcpy(&pdu_tx->connect_ind.init_addr[0], lrpa->val, memcpy(&pdu_tx->connect_ind.init_addr[0], lrpa->val,
BDADDR_SIZE); 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)) { if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
ftr->extra = ull_pdu_rx_alloc(); 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); 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->rx_addr = pdu_adv_rx->tx_addr;
pdu_tx->len = sizeof(struct pdu_adv_scan_req); pdu_tx->len = sizeof(struct pdu_adv_scan_req);
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
lrpa = ctrl_lrpa_get(rl_idx); lrpa = ull_filter_lll_lrpa_get(rl_idx);
if (_radio.scanner.rpa_gen && lrpa) { if (lll->rpa_gen && lrpa) {
pdu_tx->tx_addr = 1; pdu_tx->tx_addr = 1;
memcpy(&pdu_tx->scan_req.scan_addr[0], lrpa->val, memcpy(&pdu_tx->scan_req.scan_addr[0], lrpa->val,
BDADDR_SIZE); BDADDR_SIZE);
@ -941,10 +951,11 @@ static inline bool isr_scan_tgta_check(struct lll_scan *lll, bool init,
bool *dir_report) bool *dir_report)
{ {
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (ctrl_rl_addr_resolve(pdu->rx_addr, if (ull_filter_lll_rl_addr_resolve(pdu->rx_addr,
pdu->direct_ind.tgt_addr, rl_idx)) { pdu->direct_ind.tgt_addr, rl_idx)) {
return true; 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: /* Initiator generating RPAs, and could not resolve TargetA:
* discard * discard
*/ */

View file

@ -33,13 +33,14 @@
#include "ll.h" #include "ll.h"
#include "ll_feat.h" #include "ll_feat.h"
#include "lll.h" #include "lll.h"
#include "lll_filter.h"
#include "lll_adv.h" #include "lll_adv.h"
#include "lll_scan.h" #include "lll_scan.h"
#include "lll_conn.h" #include "lll_conn.h"
#include "ull_adv_types.h" #include "ull_adv_types.h"
#include "ull_scan_types.h" #include "ull_scan_types.h"
#include "ull_conn_types.h" #include "ull_conn_types.h"
#include "ull_filter.h"
#include "ull_internal.h" #include "ull_internal.h"
#include "ull_adv_internal.h" #include "ull_adv_internal.h"
#include "ull_scan_internal.h" #include "ull_scan_internal.h"
@ -294,6 +295,11 @@ int ll_init(struct k_sem *sem_rx)
} }
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN */
/* reset whitelist, resolving list and initialise RPA timeout*/
if (IS_ENABLED(CONFIG_BT_CTLR_FILTER)) {
ull_filter_reset(true);
}
return 0; return 0;
} }
@ -341,6 +347,11 @@ void ll_reset(void)
MFIFO_INIT(tx_ack); MFIFO_INIT(tx_ack);
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN */
/* reset whitelist and resolving list */
if (IS_ENABLED(CONFIG_BT_CTLR_FILTER)) {
ull_filter_reset(false);
}
/* Re-initialize ULL internals */ /* Re-initialize ULL internals */
/* Re-initialize the prep mfifo */ /* Re-initialize the prep mfifo */
@ -615,7 +626,7 @@ void ll_rx_dequeue(void)
ull_adv_is_enabled(0); ull_adv_is_enabled(0);
if (!bm) { if (!bm) {
ll_adv_scan_state_cb(0); ull_filter_adv_scan_state_cb(0);
} }
} }
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN */
@ -688,7 +699,7 @@ void ll_rx_mem_release(void **node_rx)
if (!ull_adv_is_enabled_get(0)) if (!ull_adv_is_enabled_get(0))
#endif #endif
{ {
ll_adv_scan_state_cb(0); ull_filter_adv_scan_state_cb(0);
} }
#endif #endif
break; break;

View file

@ -33,6 +33,8 @@
#include "ull_adv_types.h" #include "ull_adv_types.h"
#include "ull_scan_types.h" #include "ull_scan_types.h"
#include "ull_conn_types.h" #include "ull_conn_types.h"
#include "ull_filter.h"
#include "ull_adv_internal.h" #include "ull_adv_internal.h"
#include "ull_scan_internal.h" #include "ull_scan_internal.h"
#include "ull_conn_internal.h" #include "ull_conn_internal.h"
@ -472,21 +474,21 @@ u8_t ll_adv_enable(u8_t enable)
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
/* Prepare whitelist and optionally resolving list */ /* Prepare whitelist and optionally resolving list */
ll_filters_adv_update(lll->filter_policy); ull_filter_adv_update(lll->filter_policy);
if (adv->own_addr_type == BT_ADDR_LE_PUBLIC_ID || if (adv->own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
adv->own_addr_type == BT_ADDR_LE_RANDOM_ID) { adv->own_addr_type == BT_ADDR_LE_RANDOM_ID) {
/* Look up the resolving list */ /* Look up the resolving list */
rl_idx = ll_rl_find(adv->id_addr_type, adv->id_addr, rl_idx = ull_filter_rl_find(adv->id_addr_type,
NULL); adv->id_addr, NULL);
if (rl_idx != FILTER_IDX_NONE) { if (rl_idx != FILTER_IDX_NONE) {
/* Generate RPAs if required */ /* Generate RPAs if required */
ll_rl_rpa_update(false); ull_filter_rpa_update(false);
} }
ll_rl_pdu_adv_update(adv, rl_idx, pdu_adv); ull_filter_adv_pdu_update(adv, rl_idx, pdu_adv);
ll_rl_pdu_adv_update(adv, rl_idx, pdu_scan); ull_filter_adv_pdu_update(adv, rl_idx, pdu_scan);
priv = true; priv = true;
} }
#endif /* !CONFIG_BT_CTLR_PRIVACY */ #endif /* !CONFIG_BT_CTLR_PRIVACY */
@ -669,7 +671,7 @@ u8_t ll_adv_enable(u8_t enable)
#endif /* CONFIG_BT_PERIPHERAL */ #endif /* CONFIG_BT_PERIPHERAL */
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
_radio.advertiser.rl_idx = rl_idx; adv->rl_idx = rl_idx;
#else #else
ARG_UNUSED(rl_idx); ARG_UNUSED(rl_idx);
#endif /* CONFIG_BT_CTLR_PRIVACY */ #endif /* CONFIG_BT_CTLR_PRIVACY */
@ -859,11 +861,11 @@ u8_t ll_adv_enable(u8_t enable)
if (_radio.advertiser.is_mesh) { if (_radio.advertiser.is_mesh) {
_radio.scanner.is_enabled = 1; _radio.scanner.is_enabled = 1;
ll_adv_scan_state_cb(BIT(0) | BIT(1)); ull_filter_adv_scan_state_cb(BIT(0) | BIT(1));
} }
#else /* !CONFIG_BT_HCI_MESH_EXT */ #else /* !CONFIG_BT_HCI_MESH_EXT */
if (!ull_scan_is_enabled_get(0)) { if (!ull_scan_is_enabled_get(0)) {
ll_adv_scan_state_cb(BIT(0)); ull_filter_adv_scan_state_cb(BIT(0));
} }
#endif /* !CONFIG_BT_HCI_MESH_EXT */ #endif /* !CONFIG_BT_HCI_MESH_EXT */
#endif /* CONFIG_BT_CTLR_PRIVACY */ #endif /* CONFIG_BT_CTLR_PRIVACY */
@ -1201,7 +1203,7 @@ static inline u8_t disable(u16_t handle)
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
if (!ull_scan_is_enabled_get(0)) { if (!ull_scan_is_enabled_get(0)) {
ll_adv_scan_state_cb(0); ull_filter_adv_scan_state_cb(0);
} }
#endif /* CONFIG_BT_CTLR_PRIVACY */ #endif /* CONFIG_BT_CTLR_PRIVACY */

View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2018-2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
void ull_filter_adv_scan_state_cb(u8_t bm);
void ull_filter_adv_update(u8_t adv_fp);
void ull_filter_scan_update(u8_t scan_fp);
void ull_filter_rpa_update(bool timeout);
void ull_filter_adv_pdu_update(struct ll_adv_set *adv, u8_t idx,
struct pdu_adv *pdu);
u8_t ull_filter_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free);
void ull_filter_reset(bool init);

View file

@ -10,10 +10,10 @@
#include "util/util.h" #include "util/util.h"
#include "util/memq.h" #include "util/memq.h"
#include "util/mayfly.h"
#include "hal/ticker.h" #include "hal/ticker.h"
#include "hal/ccm.h" #include "hal/ccm.h"
#include "util/mayfly.h"
#include "ticker/ticker.h" #include "ticker/ticker.h"
#include "pdu.h" #include "pdu.h"
@ -23,13 +23,17 @@
#include "lll.h" #include "lll.h"
#include "lll_vendor.h" #include "lll_vendor.h"
#include "lll_clock.h" #include "lll_clock.h"
#include "lll_adv.h"
#include "lll_scan.h" #include "lll_scan.h"
#include "lll_conn.h" #include "lll_conn.h"
#include "lll_master.h" #include "lll_master.h"
#include "lll_filter.h"
#include "lll_tim_internal.h" #include "lll_tim_internal.h"
#include "ull_adv_types.h"
#include "ull_scan_types.h" #include "ull_scan_types.h"
#include "ull_conn_types.h" #include "ull_conn_types.h"
#include "ull_filter.h"
#include "ull_internal.h" #include "ull_internal.h"
#include "ull_scan_internal.h" #include "ull_scan_internal.h"
@ -47,7 +51,7 @@ static void access_addr_get(u8_t access_addr[]);
u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window, u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t filter_policy, u8_t peer_addr_type, 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) u16_t interval, u16_t latency, u16_t timeout)
{ {
struct lll_conn *conn_lll; struct lll_conn *conn_lll;
@ -57,7 +61,6 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
struct ll_conn *conn; struct ll_conn *conn;
memq_link_t *link; memq_link_t *link;
u8_t access_addr[4]; u8_t access_addr[4];
u32_t err;
u8_t hop; u8_t hop;
scan = ull_scan_is_disabled_get(0); scan = ull_scan_is_disabled_get(0);
@ -82,16 +85,10 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED; return BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
} }
err = ull_scan_params_set(scan, 0, scan_interval, scan_window, ull_scan_params_set(lll, 0, scan_interval, scan_window, filter_policy);
own_addr_type, filter_policy);
if (err) {
ll_conn_release(conn);
ll_rx_link_release(link);
return err;
}
lll->adv_addr_type = peer_addr_type; lll->adv_addr_type = peer_addr_type;
memcpy(lll->adv_addr, p_peer_addr, BDADDR_SIZE); memcpy(lll->adv_addr, peer_addr, BDADDR_SIZE);
lll->conn_timeout = timeout; lll->conn_timeout = timeout;
lll->conn_ticks_slot = 0; /* TODO: */ lll->conn_ticks_slot = 0; /* TODO: */
@ -236,23 +233,26 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
lll_hdr_init(&conn->lll, conn); lll_hdr_init(&conn->lll, conn);
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
ll_filters_scan_update(filter_policy); ull_filter_scan_update(filter_policy);
if (!filter_policy && ctrl_rl_enabled()) { if (!filter_policy && ull_filter_lll_rl_enabled()) {
/* Look up the resolving list */ /* Look up the resolving list */
rl_idx = ll_rl_find(peer_addr_type, peer_addr, NULL); lll->rl_idx = ull_filter_rl_find(peer_addr_type, peer_addr,
NULL);
} }
if (own_addr_type == BT_ADDR_LE_PUBLIC_ID || if (own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
own_addr_type == BT_ADDR_LE_RANDOM_ID) { own_addr_type == BT_ADDR_LE_RANDOM_ID) {
/* Generate RPAs if required */ /* Generate RPAs if required */
ll_rl_rpa_update(false); ull_filter_rpa_update(false);
own_addr_type &= 0x1; own_addr_type &= 0x1;
rpa_gen = 1; lll->rpa_gen = 1;
} }
#endif #endif
scan->own_addr_type = own_addr_type;
/* wait for stable clocks */ /* wait for stable clocks */
lll_clock_wait(); lll_clock_wait();
@ -434,8 +434,39 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
cc = (void *)pdu; cc = (void *)pdu;
cc->status = 0U; cc->status = 0U;
cc->role = 0U; cc->role = 0U;
cc->peer_addr_type = scan->lll.adv_addr_type;
memcpy(cc->peer_addr, scan->lll.adv_addr, BDADDR_SIZE); #if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t rl_idx;
cc->own_addr_type = pdu->tx_addr;
memcpy(&cc->own_addr[0], &pdu->connect_ind.init_addr[0], BDADDR_SIZE);
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
rl_idx = *((u8_t *)ftr->extra);
} else {
rl_idx = (u8_t)((u32_t)ftr->extra & 0xFF);
}
if (rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */
/* Store identity address */
ll_rl_id_addr_get(rl_idx, &cc->peer_addr_type,
&cc->peer_addr[0]);
/* Mark it as identity address from RPA (0x02, 0x03) */
cc->peer_addr_type += 2;
/* Store peer RPA */
memcpy(&cc->peer_rpa[0], &pdu->connect_ind.adv_addr[0],
BDADDR_SIZE);
} else {
memset(&cc->peer_rpa[0], 0x0, BDADDR_SIZE);
#else
if (1) {
#endif /* CONFIG_BT_CTLR_PRIVACY */
cc->peer_addr_type = scan->lll.adv_addr_type;
memcpy(cc->peer_addr, scan->lll.adv_addr, BDADDR_SIZE);
}
cc->interval = lll->interval; cc->interval = lll->interval;
cc->latency = lll->latency; cc->latency = lll->latency;
cc->timeout = scan->lll.conn_timeout; cc->timeout = scan->lll.conn_timeout;
@ -560,134 +591,6 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
#else #else
ARG_UNUSED(mayfly_was_enabled); ARG_UNUSED(mayfly_was_enabled);
#endif #endif
#if 0
/* Populate the master context */
conn->handle = mem_index_get(conn, _radio.conn_pool,
CONNECTION_T_SIZE);
/* Prepare the rx packet structure */
node_rx->hdr.handle = conn->handle;
node_rx->hdr.type = NODE_RX_TYPE_CONNECTION;
/* prepare connection complete structure */
pdu_data = (void *)node_rx->pdu;
cc = (void *)pdu_data->lldata;
cc->status = 0x00;
cc->role = 0x00;
#if defined(CONFIG_BT_CTLR_PRIVACY)
cc->own_addr_type = pdu_adv_tx->tx_addr;
memcpy(&cc->own_addr[0], &pdu_adv_tx->connect_ind.init_addr[0],
BDADDR_SIZE);
if (irkmatch_ok && rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */
/* Store identity address */
ll_rl_id_addr_get(rl_idx, &cc->peer_addr_type,
&cc->peer_addr[0]);
/* Mark it as identity address from RPA (0x02, 0x03) */
cc->peer_addr_type += 2;
/* Store peer RPA */
memcpy(&cc->peer_rpa[0],
&pdu_adv_tx->connect_ind.adv_addr[0],
BDADDR_SIZE);
} else {
memset(&cc->peer_rpa[0], 0x0, BDADDR_SIZE);
#else
if (1) {
#endif /* CONFIG_BT_CTLR_PRIVACY */
cc->peer_addr_type = pdu_adv_tx->rx_addr;
memcpy(&cc->peer_addr[0],
&pdu_adv_tx->connect_ind.adv_addr[0],
BDADDR_SIZE);
}
cc->interval = _radio.scanner.conn_interval;
cc->latency = _radio.scanner.conn_latency;
cc->timeout = _radio.scanner.conn_timeout;
cc->mca = pdu_adv_tx->connect_ind.sca;
/* enqueue connection complete structure into queue */
rx_fc_lock(conn->handle);
packet_rx_enqueue();
/* Use Channel Selection Algorithm #2 if peer too supports it */
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
struct node_rx_cs *cs;
/* Generate LE Channel Selection Algorithm event */
node_rx = packet_rx_reserve_get(3);
LL_ASSERT(node_rx);
node_rx->hdr.handle = conn->handle;
node_rx->hdr.type = NODE_RX_TYPE_CHAN_SEL_ALGO;
pdu_data = (void *)node_rx->pdu;
cs = (void *)pdu_data->lldata;
if (pdu_adv_rx->chan_sel) {
u16_t aa_ls =
((u16_t)conn->access_addr[1] << 8) |
conn->access_addr[0];
u16_t aa_ms =
((u16_t)conn->access_addr[3] << 8) |
conn->access_addr[2];
conn->data_chan_sel = 1;
conn->data_chan_id = aa_ms ^ aa_ls;
cs->csa = 0x01;
} else {
cs->csa = 0x00;
}
packet_rx_enqueue();
}
/* Calculate master slot */
conn->hdr.ticks_active_to_start = _radio.ticks_active_to_start;
conn->hdr.ticks_xtal_to_start = HAL_TICKER_US_TO_TICKS(
EVENT_OVERHEAD_XTAL_US);
conn->hdr.ticks_preempt_to_start = HAL_TICKER_US_TO_TICKS(
EVENT_OVERHEAD_PREEMPT_MIN_US);
conn->hdr.ticks_slot = _radio.scanner.ticks_conn_slot;
ticks_slot_offset = MAX(conn->hdr.ticks_active_to_start,
conn->hdr.ticks_xtal_to_start);
/* Stop Scanner */
ticker_status = ticker_stop(TICKER_INSTANCE_ID_CTLR,
TICKER_USER_ID_LLL,
TICKER_ID_SCAN_BASE,
ticker_stop_scan_assert,
(void *)__LINE__);
ticker_stop_scan_assert(ticker_status, (void *)__LINE__);
/* Scanner stop can expire while here in this ISR.
* Deferred attempt to stop can fail as it would have
* expired, hence ignore failure.
*/
ticker_stop(TICKER_INSTANCE_ID_CTLR,
TICKER_USER_ID_LLL,
TICKER_ID_SCAN_STOP, NULL, NULL);
/* Start master */
ticker_status =
ticker_start(TICKER_INSTANCE_ID_CTLR,
TICKER_USER_ID_LLL,
TICKER_ID_CONN_BASE +
conn->handle,
(_radio.ticks_anchor - ticks_slot_offset),
HAL_TICKER_US_TO_TICKS(conn_space_us),
HAL_TICKER_US_TO_TICKS(conn_interval_us),
HAL_TICKER_REMAINDER(conn_interval_us),
TICKER_NULL_LAZY,
(ticks_slot_offset + conn->hdr.ticks_slot),
event_master_prepare, conn,
ticker_success_assert, (void *)__LINE__);
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
(ticker_status == TICKER_STATUS_BUSY));
#endif
} }
void ull_master_ticker_cb(u32_t ticks_at_expire, u32_t remainder, u16_t lazy, void ull_master_ticker_cb(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,

View file

@ -29,6 +29,7 @@
#include "ull_adv_types.h" #include "ull_adv_types.h"
#include "ull_scan_types.h" #include "ull_scan_types.h"
#include "ull_filter.h"
#include "ull_internal.h" #include "ull_internal.h"
#include "ull_adv_internal.h" #include "ull_adv_internal.h"
@ -58,8 +59,11 @@ u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
} }
return ull_scan_params_set(scan, type, interval, window, own_addr_type, scan->own_addr_type = own_addr_type;
filter_policy);
ull_scan_params_set(&scan->lll, type, interval, window, filter_policy);
return 0;
} }
u8_t ll_scan_enable(u8_t enable) u8_t ll_scan_enable(u8_t enable)
@ -107,12 +111,9 @@ int ull_scan_reset(void)
return 0; return 0;
} }
u8_t ull_scan_params_set(struct ll_scan_set *scan, u8_t type, void ull_scan_params_set(struct lll_scan *lll, u8_t type, u16_t interval,
u16_t interval, u16_t window, u16_t window, u8_t filter_policy)
u8_t own_addr_type, u8_t filter_policy)
{ {
struct lll_scan *lll = &scan->lll;
/* type value: /* type value:
* 0000b - legacy 1M passive * 0000b - legacy 1M passive
* 0001b - legacy 1M active * 0001b - legacy 1M active
@ -134,10 +135,6 @@ u8_t ull_scan_params_set(struct ll_scan_set *scan, u8_t type,
lll->filter_policy = filter_policy; lll->filter_policy = filter_policy;
lll->interval = interval; lll->interval = interval;
lll->ticks_window = HAL_TICKER_US_TO_TICKS((u64_t)window * 625U); lll->ticks_window = HAL_TICKER_US_TO_TICKS((u64_t)window * 625U);
scan->own_addr_type = own_addr_type;
return 0;
} }
u8_t ull_scan_enable(struct ll_scan_set *scan) u8_t ull_scan_enable(struct ll_scan_set *scan)
@ -151,13 +148,13 @@ u8_t ull_scan_enable(struct ll_scan_set *scan)
u32_t ret; u32_t ret;
#if defined(CONFIG_BT_CTLR_PRIVACY) #if defined(CONFIG_BT_CTLR_PRIVACY)
ll_filters_scan_update(scan->filter_policy); ull_filter_scan_update(lll->filter_policy);
if ((scan->type & 0x1) && if ((lll->type & 0x1) &&
(scan->own_addr_type == BT_ADDR_LE_PUBLIC_ID || (scan->own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
scan->own_addr_type == BT_ADDR_LE_RANDOM_ID)) { scan->own_addr_type == BT_ADDR_LE_RANDOM_ID)) {
/* Generate RPAs if required */ /* Generate RPAs if required */
ll_rl_rpa_update(false); ull_filter_rpa_update(false);
lll->rpa_gen = 1; lll->rpa_gen = 1;
lll->rl_idx = FILTER_IDX_NONE; lll->rl_idx = FILTER_IDX_NONE;
} }
@ -245,7 +242,7 @@ u8_t ull_scan_enable(struct ll_scan_set *scan)
if (!ull_adv_is_enabled_get(0)) if (!ull_adv_is_enabled_get(0))
#endif #endif
{ {
ll_adv_scan_state_cb(BIT(1)); ull_filter_adv_scan_state_cb(BIT(1));
} }
#endif #endif
@ -436,7 +433,7 @@ static u8_t disable(u16_t handle)
if (!ull_adv_is_enabled_get(0)) if (!ull_adv_is_enabled_get(0))
#endif #endif
{ {
ll_adv_scan_state_cb(0); ull_filter_adv_scan_state_cb(0);
} }
#endif #endif

View file

@ -10,9 +10,8 @@ int ull_scan_init(void);
int ull_scan_reset(void); int ull_scan_reset(void);
/* Set scan parameters */ /* Set scan parameters */
u8_t ull_scan_params_set(struct ll_scan_set *scan, u8_t type, void ull_scan_params_set(struct lll_scan *lll, u8_t type, u16_t interval,
u16_t interval, u16_t window, u16_t window, u8_t filter_policy);
u8_t own_addr_type, u8_t filter_policy);
/* Enable and start scanning/initiating role */ /* Enable and start scanning/initiating role */
u8_t ull_scan_enable(struct ll_scan_set *scan); u8_t ull_scan_enable(struct ll_scan_set *scan);

View file

@ -4,32 +4,33 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stddef.h> #include <zephyr.h>
#include <stdbool.h> #include <bluetooth/hci.h>
#include <toolchain.h>
#include <zephyr/types.h>
#include <misc/byteorder.h> #include <misc/byteorder.h>
#include <misc/util.h>
#include "util/util.h"
#include "util/memq.h"
#include "util/mayfly.h"
#include "hal/ticker.h" #include "hal/ticker.h"
#include "hal/ccm.h" #include "hal/ccm.h"
#include "util/memq.h"
#include "util/mayfly.h"
#include "ticker/ticker.h" #include "ticker/ticker.h"
#include "util/util.h"
#include "pdu.h" #include "pdu.h"
#include "ll.h"
#include "lll.h" #include "lll.h"
#include "lll_vendor.h" #include "lll_vendor.h"
#include "lll_adv.h" #include "lll_adv.h"
#include "lll_conn.h" #include "lll_conn.h"
#include "lll_slave.h" #include "lll_slave.h"
#include "lll_filter.h"
#include "lll_tim_internal.h" #include "lll_tim_internal.h"
#include "ull_adv_types.h" #include "ull_adv_types.h"
#include "ull_conn_types.h" #include "ull_conn_types.h"
#include "ull_filter.h"
#include "ull_internal.h" #include "ull_internal.h"
#include "ull_adv_internal.h" #include "ull_adv_internal.h"
@ -121,15 +122,52 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
sizeof(lll->slave.force)); sizeof(lll->slave.force));
#endif #endif
chan_sel = pdu_adv->chan_sel; #if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t own_addr_type = pdu_adv->rx_addr;
u8_t own_addr[BDADDR_SIZE];
u8_t rl_idx;
memcpy(own_addr, &pdu_adv->connect_ind.adv_addr[0], BDADDR_SIZE);
#endif
peer_addr_type = pdu_adv->tx_addr; peer_addr_type = pdu_adv->tx_addr;
memcpy(peer_addr, pdu_adv->connect_ind.init_addr, BDADDR_SIZE); memcpy(peer_addr, pdu_adv->connect_ind.init_addr, BDADDR_SIZE);
chan_sel = pdu_adv->chan_sel;
cc = (void *)pdu_adv; cc = (void *)pdu_adv;
cc->status = 0U; cc->status = 0U;
cc->role = 1U; cc->role = 1U;
cc->peer_addr_type = peer_addr_type;
memcpy(cc->peer_addr, peer_addr, BDADDR_SIZE); #if defined(CONFIG_BT_CTLR_PRIVACY)
cc->own_addr_type = own_addr_type;
memcpy(&cc->own_addr[0], &own_addr[0], BDADDR_SIZE);
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
rl_idx = *((u8_t *)ftr->extra);
} else {
rl_idx = (u8_t)((u32_t)ftr->extra & 0xFF);
}
if (rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */
/* Store identity address */
ll_rl_id_addr_get(rl_idx, &cc->peer_addr_type,
&cc->peer_addr[0]);
/* Mark it as identity address from RPA (0x02, 0x03) */
cc->peer_addr_type += 2;
/* Store peer RPA */
memcpy(&cc->peer_rpa[0], &peer_addr[0], BDADDR_SIZE);
} else {
memset(&cc->peer_rpa[0], 0x0, BDADDR_SIZE);
#else
if (1) {
#endif /* CONFIG_BT_CTLR_PRIVACY */
cc->peer_addr_type = peer_addr_type;
memcpy(cc->peer_addr, peer_addr, BDADDR_SIZE);
}
cc->interval = lll->interval; cc->interval = lll->interval;
cc->latency = lll->latency; cc->latency = lll->latency;
cc->timeout = timeout; cc->timeout = timeout;
@ -177,91 +215,6 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
ll_rx_put(link, rx); ll_rx_put(link, rx);
ll_rx_sched(); ll_rx_sched();
#if 0
/* Prepare the rx packet structure */
node_rx->hdr.handle = conn->handle;
node_rx->hdr.type = NODE_RX_TYPE_CONNECTION;
/* prepare connection complete structure */
pdu_data = (void *)node_rx->pdu_data;
radio_le_conn_cmplt = (void *)pdu_data->lldata;
radio_le_conn_cmplt->status = 0x00;
radio_le_conn_cmplt->role = 0x01;
#if defined(CONFIG_BT_CTLR_PRIVACY)
radio_le_conn_cmplt->own_addr_type = pdu_adv->rx_addr;
memcpy(&radio_le_conn_cmplt->own_addr[0],
&pdu_adv->connect_ind.adv_addr[0], BDADDR_SIZE);
if (rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */
/* Store identity address */
ll_rl_id_addr_get(rl_idx,
&radio_le_conn_cmplt->peer_addr_type,
&radio_le_conn_cmplt->peer_addr[0]);
/* Mark it as identity address from RPA (0x02, 0x03) */
radio_le_conn_cmplt->peer_addr_type += 2;
/* Store peer RPA */
memcpy(&radio_le_conn_cmplt->peer_rpa[0],
&pdu_adv->connect_ind.init_addr[0],
BDADDR_SIZE);
} else {
memset(&radio_le_conn_cmplt->peer_rpa[0], 0x0,
BDADDR_SIZE);
#else
if (1) {
#endif /* CONFIG_BT_CTLR_PRIVACY */
radio_le_conn_cmplt->peer_addr_type = pdu_adv->tx_addr;
memcpy(&radio_le_conn_cmplt->peer_addr[0],
&pdu_adv->connect_ind.init_addr[0],
BDADDR_SIZE);
}
radio_le_conn_cmplt->interval =
pdu_adv->connect_ind.interval;
radio_le_conn_cmplt->latency =
pdu_adv->connect_ind.latency;
radio_le_conn_cmplt->timeout =
pdu_adv->connect_ind.timeout;
radio_le_conn_cmplt->mca =
pdu_adv->connect_ind.sca;
/* enqueue connection complete structure into queue */
rx_fc_lock(conn->handle);
packet_rx_enqueue();
/* Use Channel Selection Algorithm #2 if peer too supports it */
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
struct radio_le_chan_sel_algo *le_chan_sel_algo;
/* Generate LE Channel Selection Algorithm event */
node_rx = packet_rx_reserve_get(3);
LL_ASSERT(node_rx);
node_rx->hdr.handle = conn->handle;
node_rx->hdr.type = NODE_RX_TYPE_CHAN_SEL_ALGO;
pdu_data = (void *)node_rx->pdu_data;
le_chan_sel_algo = (void *)pdu_data->lldata;
if (pdu_adv->chan_sel) {
u16_t aa_ls =
((u16_t)conn->access_addr[1] << 8) |
conn->access_addr[0];
u16_t aa_ms =
((u16_t)conn->access_addr[3] << 8) |
conn->access_addr[2];
conn->data_chan_sel = 1;
conn->data_chan_id = aa_ms ^ aa_ls;
le_chan_sel_algo->chan_sel_algo = 0x01;
} else {
le_chan_sel_algo->chan_sel_algo = 0x00;
}
packet_rx_enqueue();
}
#endif
/* TODO: active_to_start feature port */ /* TODO: active_to_start feature port */
conn->evt.ticks_active_to_start = 0U; conn->evt.ticks_active_to_start = 0U;