Bluetooth: controller: Privacy filtering in scanner and initiator
This commit introduces controller-based privacy for both the scanner and the initiator roles. All the features in the specification are implemented except: * RPA resolution for directed advertising (TargetA address) * RPA generation for scan requests and conn ind packets Follow-up patches will cover the 2 items of functionality still missing from the basic implementation. Hosts not using controller-based privacy should not be affected by this change. Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
3002f36d37
commit
af93255aa5
7 changed files with 208 additions and 62 deletions
|
@ -112,8 +112,14 @@ struct scanner {
|
|||
u8_t adv_addr_type:1;
|
||||
u8_t init_addr_type:1;
|
||||
|
||||
u8_t adv_addr[BDADDR_SIZE];
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
u8_t rpa_gen:1;
|
||||
/* initiator only */
|
||||
u8_t rl_idx;
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
u8_t init_addr[BDADDR_SIZE];
|
||||
u8_t adv_addr[BDADDR_SIZE];
|
||||
|
||||
u32_t ticks_window;
|
||||
|
||||
u16_t conn_interval;
|
||||
|
@ -726,15 +732,16 @@ static inline bool isr_adv_sr_check(struct pdu_adv *adv, struct pdu_adv *sr,
|
|||
{
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
return ((((_radio.advertiser.filter_policy & 0x01) == 0) &&
|
||||
ctrl_rl_allowed(sr->tx_addr,
|
||||
sr->payload.scan_req.scan_addr, rl_idx)) ||
|
||||
ctrl_rl_addr_allowed(sr->tx_addr,
|
||||
sr->payload.scan_req.scan_addr,
|
||||
rl_idx)) ||
|
||||
(devmatch_ok) || (ctrl_irk_whitelisted(*rl_idx))) &&
|
||||
isr_adv_sr_adva_check(adv, sr);
|
||||
#else
|
||||
return (((_radio.advertiser.filter_policy & 0x01) == 0) ||
|
||||
(devmatch_ok)) &&
|
||||
isr_adv_sr_adva_check(adv, sr);
|
||||
#endif
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
}
|
||||
|
||||
static inline bool isr_adv_ci_tgta_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
||||
|
@ -744,7 +751,7 @@ static inline bool isr_adv_ci_tgta_check(struct pdu_adv *adv, struct pdu_adv *ci
|
|||
if (rl_idx != FILTER_IDX_NONE) {
|
||||
return rl_idx == _radio.advertiser.rl_idx;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
return (adv->rx_addr == ci->tx_addr) &&
|
||||
!memcmp(adv->payload.direct_ind.tgt_addr,
|
||||
ci->payload.connect_ind.init_addr, BDADDR_SIZE);
|
||||
|
@ -767,8 +774,9 @@ static inline bool isr_adv_ci_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
|||
/* LL 4.3.2: filter policy shall be ignored for directed adv */
|
||||
if (adv->type == PDU_ADV_TYPE_DIRECT_IND) {
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
return ctrl_rl_allowed(ci->tx_addr,
|
||||
ci->payload.connect_ind.init_addr, rl_idx) &&
|
||||
return ctrl_rl_addr_allowed(ci->tx_addr,
|
||||
ci->payload.connect_ind.init_addr,
|
||||
rl_idx) &&
|
||||
#else
|
||||
return (1) &&
|
||||
#endif
|
||||
|
@ -778,15 +786,16 @@ static inline bool isr_adv_ci_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
|||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
return ((((_radio.advertiser.filter_policy & 0x02) == 0) &&
|
||||
ctrl_rl_allowed(ci->tx_addr,
|
||||
ci->payload.connect_ind.init_addr, rl_idx)) ||
|
||||
ctrl_rl_addr_allowed(ci->tx_addr,
|
||||
ci->payload.connect_ind.init_addr,
|
||||
rl_idx)) ||
|
||||
(devmatch_ok) || (ctrl_irk_whitelisted(*rl_idx))) &&
|
||||
isr_adv_ci_adva_check(adv, ci);
|
||||
#else
|
||||
return (((_radio.advertiser.filter_policy & 0x02) == 0) ||
|
||||
(devmatch_ok)) &&
|
||||
isr_adv_ci_adva_check(adv, ci);
|
||||
#endif
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
}
|
||||
|
||||
static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
|
||||
|
@ -797,7 +806,8 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
|
|||
struct radio_pdu_node_rx *radio_pdu_node_rx;
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
/* An IRK match implies address resolution enabled */
|
||||
u8_t rl_idx = irkmatch_ok ? ctrl_rl_idx(irkmatch_id) : FILTER_IDX_NONE;
|
||||
u8_t rl_idx = irkmatch_ok ? ctrl_rl_irk_idx(irkmatch_id) :
|
||||
FILTER_IDX_NONE;
|
||||
#else
|
||||
u8_t rl_idx = FILTER_IDX_NONE;
|
||||
#endif
|
||||
|
@ -1097,7 +1107,71 @@ static u32_t isr_rx_scan_report(u8_t rssi_ready)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready)
|
||||
static inline bool isr_rx_scan_check(u8_t irkmatch_ok, u8_t devmatch_ok,
|
||||
u8_t rl_idx)
|
||||
{
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
return ((((_radio.scanner.filter_policy & 0x01) == 0) &&
|
||||
(!devmatch_ok || ctrl_rl_idx_allowed(irkmatch_ok, rl_idx))) ||
|
||||
devmatch_ok || ctrl_irk_whitelisted(rl_idx));
|
||||
#else
|
||||
return ((_radio.scanner.filter_policy & 0x01) == 0) ||
|
||||
devmatch_ok;
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
}
|
||||
|
||||
static inline bool isr_scan_init_adva_check(struct pdu_adv *pdu,
|
||||
u8_t rl_idx)
|
||||
{
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
/* Only applies to initiator with no whitelist */
|
||||
if (rl_idx != FILTER_IDX_NONE) {
|
||||
return (rl_idx == _radio.scanner.rl_idx);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
return ((_radio.scanner.adv_addr_type == pdu->tx_addr) &&
|
||||
(memcmp(&_radio.scanner.adv_addr[0],
|
||||
&pdu->payload.adv_ind.addr[0], BDADDR_SIZE) == 0));
|
||||
}
|
||||
|
||||
static inline bool isr_scan_tgta_check(bool init, struct pdu_adv *pdu,
|
||||
u8_t rl_idx)
|
||||
{
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
if (ctrl_rl_addr_resolve(pdu->rx_addr,
|
||||
pdu->payload.direct_ind.tgt_addr, rl_idx)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (((!init || _radio.scanner.rl_idx == FILTER_IDX_NONE) &&
|
||||
#else
|
||||
return (((1) &&
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
((_radio.scanner.init_addr_type == pdu->rx_addr) &&
|
||||
(memcmp(&_radio.scanner.init_addr[0],
|
||||
&pdu->payload.direct_ind.tgt_addr[0],
|
||||
BDADDR_SIZE) == 0))) ||
|
||||
/* allow directed adv packets where TargetA address
|
||||
* is resolvable private address (scanner only)
|
||||
*/
|
||||
(((_radio.scanner.filter_policy & 0x02) != 0) &&
|
||||
(pdu->rx_addr != 0) &&
|
||||
((pdu->payload.direct_ind.tgt_addr[5] & 0xc0) ==
|
||||
0x40)));
|
||||
}
|
||||
|
||||
static inline bool isr_scan_init_check(struct pdu_adv *pdu, u8_t rl_idx)
|
||||
{
|
||||
return ((((_radio.scanner.filter_policy & 0x01) != 0) ||
|
||||
isr_scan_init_adva_check(pdu, rl_idx)) &&
|
||||
((pdu->type == PDU_ADV_TYPE_ADV_IND) ||
|
||||
((pdu->type == PDU_ADV_TYPE_DIRECT_IND) &&
|
||||
(/* allow directed adv packets addressed to this device */
|
||||
isr_scan_tgta_check(true, pdu, rl_idx)))));
|
||||
}
|
||||
|
||||
static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
|
||||
u8_t irkmatch_id, u8_t rl_idx, u8_t rssi_ready)
|
||||
{
|
||||
struct pdu_adv *pdu_adv_rx;
|
||||
|
||||
|
@ -1107,25 +1181,7 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready)
|
|||
/* Initiator */
|
||||
if ((_radio.scanner.conn) && ((_radio.fc_ena == 0) ||
|
||||
(_radio.fc_req == _radio.fc_ack)) &&
|
||||
(((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) &&
|
||||
(((_radio.scanner.filter_policy & 0x01) != 0) ||
|
||||
((_radio.scanner.adv_addr_type == pdu_adv_rx->tx_addr) &&
|
||||
(memcmp(&_radio.scanner.adv_addr[0],
|
||||
&pdu_adv_rx->payload.adv_ind.addr[0],
|
||||
BDADDR_SIZE) == 0)))) ||
|
||||
((pdu_adv_rx->type == PDU_ADV_TYPE_DIRECT_IND) &&
|
||||
(/* allow directed adv packets addressed to this device */
|
||||
((_radio.scanner.init_addr_type == pdu_adv_rx->rx_addr) &&
|
||||
(memcmp(&_radio.scanner.init_addr[0],
|
||||
&pdu_adv_rx->payload.direct_ind.tgt_addr[0],
|
||||
BDADDR_SIZE) == 0)) ||
|
||||
/* allow directed adv packets where initiator address
|
||||
* is resolvable private address
|
||||
*/
|
||||
(((_radio.scanner.filter_policy & 0x02) != 0) &&
|
||||
(pdu_adv_rx->rx_addr != 0) &&
|
||||
((pdu_adv_rx->payload.direct_ind.tgt_addr[5] & 0xc0) ==
|
||||
0x40))))) &&
|
||||
isr_scan_init_check(pdu_adv_rx, rl_idx) &&
|
||||
((radio_tmr_end_get() + 502) <
|
||||
(TICKER_TICKS_TO_US(_radio.scanner.hdr.ticks_slot) -
|
||||
RADIO_TICKER_START_PART_US))) {
|
||||
|
@ -1166,11 +1222,19 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready)
|
|||
pdu_adv_tx->chan_sel = 0;
|
||||
}
|
||||
|
||||
pdu_adv_tx->tx_addr = _radio.scanner.init_addr_type;
|
||||
pdu_adv_tx->rx_addr = pdu_adv_rx->tx_addr;
|
||||
pdu_adv_tx->len = sizeof(struct pdu_adv_payload_connect_ind);
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
/*@todo: obtain RPA based on rl_idx if rl_idx != NONE and
|
||||
* own address > 0x01 */
|
||||
pdu_adv_tx->tx_addr = _radio.scanner.init_addr_type;
|
||||
memcpy(&pdu_adv_tx->payload.connect_ind.init_addr[0],
|
||||
&_radio.scanner.init_addr[0], BDADDR_SIZE);
|
||||
#else
|
||||
pdu_adv_tx->tx_addr = _radio.scanner.init_addr_type;
|
||||
memcpy(&pdu_adv_tx->payload.connect_ind.init_addr[0],
|
||||
&_radio.scanner.init_addr[0], BDADDR_SIZE);
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
memcpy(&pdu_adv_tx->payload.connect_ind.adv_addr[0],
|
||||
&pdu_adv_rx->payload.adv_ind.addr[0], BDADDR_SIZE);
|
||||
memcpy(&pdu_adv_tx->payload.connect_ind.lldata.
|
||||
|
@ -1370,11 +1434,19 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready)
|
|||
/* prepare the scan request packet */
|
||||
pdu_adv_tx = (struct pdu_adv *)radio_pkt_scratch_get();
|
||||
pdu_adv_tx->type = PDU_ADV_TYPE_SCAN_REQ;
|
||||
pdu_adv_tx->tx_addr = _radio.scanner.init_addr_type;
|
||||
pdu_adv_tx->rx_addr = pdu_adv_rx->tx_addr;
|
||||
pdu_adv_tx->len = sizeof(struct pdu_adv_payload_scan_req);
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
/*@todo: obtain RPA based on rl_idx if rl_idx != NONE and
|
||||
* own address > 0x01 */
|
||||
pdu_adv_tx->tx_addr = _radio.scanner.init_addr_type;
|
||||
memcpy(&pdu_adv_tx->payload.scan_req.scan_addr[0],
|
||||
&_radio.scanner.init_addr[0], BDADDR_SIZE);
|
||||
#else
|
||||
pdu_adv_tx->tx_addr = _radio.scanner.init_addr_type;
|
||||
memcpy(&pdu_adv_tx->payload.scan_req.scan_addr[0],
|
||||
&_radio.scanner.init_addr[0], BDADDR_SIZE);
|
||||
#endif
|
||||
memcpy(&pdu_adv_tx->payload.scan_req.adv_addr[0],
|
||||
&pdu_adv_rx->payload.adv_ind.addr[0], BDADDR_SIZE);
|
||||
|
||||
|
@ -1393,16 +1465,7 @@ static inline u32_t isr_rx_scan(u8_t irkmatch_id, u8_t rssi_ready)
|
|||
else if (((pdu_adv_rx->type == PDU_ADV_TYPE_ADV_IND) ||
|
||||
((pdu_adv_rx->type == PDU_ADV_TYPE_DIRECT_IND) &&
|
||||
(/* allow directed adv packets addressed to this device */
|
||||
((_radio.scanner.init_addr_type == pdu_adv_rx->rx_addr) &&
|
||||
(memcmp(&_radio.scanner.init_addr[0],
|
||||
&pdu_adv_rx->payload.direct_ind.tgt_addr[0],
|
||||
BDADDR_SIZE) == 0)) ||
|
||||
/* allow directed adv packets where initiator address
|
||||
* is resolvable private address
|
||||
*/
|
||||
(((_radio.scanner.filter_policy & 0x02) != 0) &&
|
||||
(pdu_adv_rx->rx_addr != 0) &&
|
||||
((pdu_adv_rx->payload.direct_ind.tgt_addr[5] & 0xc0) == 0x40)))) ||
|
||||
isr_scan_tgta_check(false, pdu_adv_rx, rl_idx))) ||
|
||||
(pdu_adv_rx->type == PDU_ADV_TYPE_NONCONN_IND) ||
|
||||
(pdu_adv_rx->type == PDU_ADV_TYPE_SCAN_IND) ||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT)
|
||||
|
@ -2997,6 +3060,7 @@ static inline void isr_radio_state_rx(u8_t trx_done, u8_t crc_ok,
|
|||
u8_t rssi_ready)
|
||||
{
|
||||
u32_t err;
|
||||
u8_t rl_idx;
|
||||
|
||||
if (!((trx_done) || ((SILENT_CONNECTION) &&
|
||||
(_radio.role == ROLE_SLAVE)))) {
|
||||
|
@ -3021,10 +3085,19 @@ static inline void isr_radio_state_rx(u8_t trx_done, u8_t crc_ok,
|
|||
break;
|
||||
|
||||
case ROLE_SCAN:
|
||||
if ((crc_ok) &&
|
||||
(((_radio.scanner.filter_policy & 0x01) == 0) ||
|
||||
(devmatch_ok) || (irkmatch_ok))) {
|
||||
err = isr_rx_scan(irkmatch_id, rssi_ready);
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_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;
|
||||
#else
|
||||
rl_idx = FILTER_IDX_NONE;
|
||||
#endif
|
||||
if (crc_ok &&
|
||||
isr_rx_scan_check(irkmatch_ok, devmatch_ok, rl_idx)) {
|
||||
err = isr_rx_scan(devmatch_ok, devmatch_id, irkmatch_id,
|
||||
rl_idx, rssi_ready);
|
||||
} else {
|
||||
err = 1;
|
||||
}
|
||||
|
@ -8768,7 +8841,8 @@ u32_t radio_adv_filter_pol_get(void)
|
|||
}
|
||||
|
||||
u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr,
|
||||
u16_t interval, u16_t window, u8_t filter_policy)
|
||||
u16_t interval, u16_t window, u8_t filter_policy,
|
||||
u8_t rpa_gen, u8_t rl_idx)
|
||||
{
|
||||
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
|
||||
u32_t ticks_slot_offset;
|
||||
|
@ -8787,6 +8861,11 @@ u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr,
|
|||
_radio.scanner.phy = type >> 1;
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT */
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
_radio.scanner.rpa_gen = rpa_gen;
|
||||
_radio.scanner.rl_idx = rl_idx;
|
||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
|
||||
|
||||
_radio.scanner.init_addr_type = init_addr_type;
|
||||
memcpy(&_radio.scanner.init_addr[0], init_addr, BDADDR_SIZE);
|
||||
_radio.scanner.ticks_window =
|
||||
|
|
|
@ -340,9 +340,9 @@ u32_t radio_adv_disable(void);
|
|||
u32_t radio_adv_is_enabled(void);
|
||||
u32_t radio_adv_filter_pol_get(void);
|
||||
/* Downstream - Scanner */
|
||||
u32_t radio_scan_enable(u8_t type, u8_t init_addr_type,
|
||||
u8_t *init_addr, u16_t interval,
|
||||
u16_t window, u8_t filter_policy);
|
||||
u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr,
|
||||
u16_t interval, u16_t window, u8_t filter_policy,
|
||||
u8_t rpa_gen, u8_t rl_idx);
|
||||
u32_t radio_scan_disable(void);
|
||||
u32_t radio_scan_is_enabled(void);
|
||||
u32_t radio_scan_filter_pol_get(void);
|
||||
|
|
|
@ -337,7 +337,7 @@ u32_t ll_adv_enable(u8_t enable)
|
|||
{
|
||||
struct radio_adv_data *radio_scan_data;
|
||||
struct radio_adv_data *radio_adv_data;
|
||||
int rl_idx = FILTER_IDX_NONE;
|
||||
u8_t rl_idx = FILTER_IDX_NONE;
|
||||
struct pdu_adv *pdu_scan;
|
||||
struct pdu_adv *pdu_adv;
|
||||
u32_t status;
|
||||
|
|
|
@ -221,7 +221,24 @@ u8_t *ctrl_irks_get(u8_t *count)
|
|||
return (u8_t *)peer_irks;
|
||||
}
|
||||
|
||||
u8_t ctrl_rl_idx(u8_t irkmatch_id)
|
||||
u8_t ctrl_rl_idx(bool whitelist, u8_t devmatch_id)
|
||||
{
|
||||
u8_t i;
|
||||
|
||||
if (whitelist) {
|
||||
LL_ASSERT(devmatch_id < ARRAY_SIZE(wl));
|
||||
LL_ASSERT(wl[devmatch_id].taken);
|
||||
i = wl[devmatch_id].rl_idx;
|
||||
} else {
|
||||
LL_ASSERT(devmatch_id < ARRAY_SIZE(rl));
|
||||
i = devmatch_id;
|
||||
LL_ASSERT(rl[i].taken);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
u8_t ctrl_rl_irk_idx(u8_t irkmatch_id)
|
||||
{
|
||||
u8_t i;
|
||||
|
||||
|
@ -349,7 +366,7 @@ static void filter_rl_update(void)
|
|||
filter_clear(&rl_filter);
|
||||
|
||||
for (i = 0; i < CONFIG_BLUETOOTH_CONTROLLER_RL_SIZE; i++) {
|
||||
if (rl[i].taken && (!rl[i].pirk || rl[i].dev)) {
|
||||
if (rl[i].taken) {
|
||||
filter_insert(&rl_filter, i, rl[i].id_addr_type,
|
||||
rl[i].id_addr.val);
|
||||
}
|
||||
|
@ -403,11 +420,28 @@ u8_t ll_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free)
|
|||
return FILTER_IDX_NONE;
|
||||
}
|
||||
|
||||
bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx)
|
||||
bool ctrl_rl_idx_allowed(u8_t irkmatch_ok, u8_t rl_idx)
|
||||
{
|
||||
/* If AR is disabled or we don't know the device or we matched an IRK
|
||||
* then we're all set.
|
||||
*/
|
||||
if (!rl_enable || rl_idx >= ARRAY_SIZE(rl) || irkmatch_ok) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LL_ASSERT(rl_idx < CONFIG_BLUETOOTH_CONTROLLER_RL_SIZE);
|
||||
LL_ASSERT(rl[rl_idx].taken);
|
||||
|
||||
return !rl[rl_idx].pirk || rl[rl_idx].dev;
|
||||
}
|
||||
|
||||
bool ctrl_rl_addr_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* If AR is disabled or we matched an IRK then we're all set */
|
||||
/* If AR is disabled or we matched an IRK then we're all set. No hw
|
||||
* filters are used in this case.
|
||||
*/
|
||||
if (!rl_enable || *rl_idx != FILTER_IDX_NONE) {
|
||||
return true;
|
||||
}
|
||||
|
@ -431,6 +465,20 @@ bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ctrl_rl_addr_resolve(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx)
|
||||
{
|
||||
/* Unable to resolve if AR is disabled, no RL entry or no local IRK */
|
||||
if (!rl_enable || rl_idx >= ARRAY_SIZE(rl) || !rl[rl_idx].lirk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((id_addr_type != 0) && ((id_addr[5] & 0xc0) == 0x40)) {
|
||||
/*@todo: resolve address */
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ctrl_rl_enabled(void)
|
||||
{
|
||||
return rl_enable;
|
||||
|
|
|
@ -20,12 +20,15 @@ void ll_filters_scan_update(u8_t scan_fp);
|
|||
|
||||
struct ll_filter *ctrl_filter_get(bool whitelist);
|
||||
u8_t *ctrl_irks_get(u8_t *count);
|
||||
u8_t ctrl_rl_idx(u8_t irkmatch_id);
|
||||
u8_t ctrl_rl_idx(bool whitelist, u8_t devmatch_id);
|
||||
u8_t ctrl_rl_irk_idx(u8_t irkmatch_id);
|
||||
bool ctrl_irk_whitelisted(u8_t rl_idx);
|
||||
|
||||
bool ctrl_rl_enabled(void);
|
||||
void ll_rl_rpa_update(bool timeout);
|
||||
|
||||
u8_t ll_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free);
|
||||
bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx);
|
||||
bool ctrl_rl_addr_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx);
|
||||
bool ctrl_rl_addr_resolve(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx);
|
||||
bool ctrl_rl_idx_allowed(u8_t irkmatch_ok, u8_t rl_idx);
|
||||
void ll_rl_pdu_adv_update(int idx, struct pdu_adv *pdu);
|
||||
|
|
|
@ -22,6 +22,8 @@ u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
|
|||
u16_t timeout)
|
||||
{
|
||||
u32_t status;
|
||||
u8_t rpa_gen = 0;
|
||||
u8_t rl_idx = FILTER_IDX_NONE;
|
||||
|
||||
if (radio_scan_is_enabled()) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
|
@ -36,13 +38,23 @@ u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
|
|||
|
||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||
ll_filters_scan_update(filter_policy);
|
||||
|
||||
if (!filter_policy && ctrl_rl_enabled()) {
|
||||
/* Look up the resolving list */
|
||||
rl_idx = ll_rl_find(peer_addr_type, peer_addr, NULL);
|
||||
}
|
||||
|
||||
if (own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
|
||||
own_addr_type == BT_ADDR_LE_RANDOM_ID) {
|
||||
|
||||
/* Generate RPAs if required */
|
||||
ll_rl_rpa_update(false);
|
||||
own_addr_type &= 0x1;
|
||||
rpa_gen = 1;
|
||||
}
|
||||
#endif
|
||||
return radio_scan_enable(0, own_addr_type,
|
||||
ll_addr_get(own_addr_type, NULL),
|
||||
scan_interval, scan_window, filter_policy);
|
||||
scan_interval, scan_window,
|
||||
filter_policy, rpa_gen, rl_idx);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
|
|||
u32_t ll_scan_enable(u8_t enable)
|
||||
{
|
||||
u32_t status;
|
||||
u8_t rpa_gen = 0;
|
||||
|
||||
if (!enable) {
|
||||
return radio_scan_disable();
|
||||
|
@ -76,12 +77,15 @@ u32_t ll_scan_enable(u8_t enable)
|
|||
ll_scan.own_addr_type == BT_ADDR_LE_RANDOM_ID)) {
|
||||
/* Generate RPAs if required */
|
||||
ll_rl_rpa_update(false);
|
||||
rpa_gen = 1;
|
||||
}
|
||||
#endif
|
||||
status = radio_scan_enable(ll_scan.type, ll_scan.own_addr_type,
|
||||
ll_addr_get(ll_scan.own_addr_type, NULL),
|
||||
status = radio_scan_enable(ll_scan.type, ll_scan.own_addr_type & 0x1,
|
||||
ll_addr_get(ll_scan.own_addr_type & 0x1,
|
||||
NULL),
|
||||
ll_scan.interval, ll_scan.window,
|
||||
ll_scan.filter_policy);
|
||||
ll_scan.filter_policy, rpa_gen,
|
||||
FILTER_IDX_NONE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue