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:
parent
c5c87c38eb
commit
b928cef69c
14 changed files with 935 additions and 1006 deletions
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) &&
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
14
subsys/bluetooth/controller/ll_sw/ull_filter.h
Normal file
14
subsys/bluetooth/controller/ll_sw/ull_filter.h
Normal 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);
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue