Bluetooth: controller: Fix directed adv filtering
The specification states that filter policies shall be ignored for directed advertising, so reflect this behaviour in the code. Additionally when the local device is using RPAs but the peer uses an identity address, the resolving list index needs to be updated when traversing the RL to reflect that there has indeed been a device match even though the IRK match did not happen. Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
968e4089d1
commit
7b02b06b41
3 changed files with 29 additions and 18 deletions
|
@ -713,13 +713,13 @@ static u32_t isr_rx_adv_sr_report(struct pdu_adv *pdu_adv_rx, u8_t rssi_ready)
|
||||||
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
#endif /* CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY */
|
||||||
|
|
||||||
static inline bool isr_adv_sr_check(struct pdu_adv *pdu, u8_t devmatch_ok,
|
static inline bool isr_adv_sr_check(struct pdu_adv *pdu, u8_t devmatch_ok,
|
||||||
u8_t rl_idx)
|
u8_t *rl_idx)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||||
return ((((_radio.advertiser.filter_policy & 0x01) == 0) &&
|
return ((((_radio.advertiser.filter_policy & 0x01) == 0) &&
|
||||||
ctrl_rl_allowed(pdu->tx_addr,
|
ctrl_rl_allowed(pdu->tx_addr,
|
||||||
pdu->payload.scan_req.scan_addr)) ||
|
pdu->payload.scan_req.scan_addr, rl_idx)) ||
|
||||||
(devmatch_ok) || (ctrl_irk_whitelisted(rl_idx))) &&
|
(devmatch_ok) || (ctrl_irk_whitelisted(*rl_idx))) &&
|
||||||
(1 /** @todo own addr match check */);
|
(1 /** @todo own addr match check */);
|
||||||
#else
|
#else
|
||||||
return (((_radio.advertiser.filter_policy & 0x01) == 0) ||
|
return (((_radio.advertiser.filter_policy & 0x01) == 0) ||
|
||||||
|
@ -731,10 +731,6 @@ static inline bool isr_adv_sr_check(struct pdu_adv *pdu, u8_t devmatch_ok,
|
||||||
static inline bool isr_adv_ci_tgta_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
static inline bool isr_adv_ci_tgta_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
||||||
u8_t rl_idx)
|
u8_t rl_idx)
|
||||||
{
|
{
|
||||||
if (adv->type != PDU_ADV_TYPE_DIRECT_IND) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||||
if (rl_idx != FILTER_IDX_NONE) {
|
if (rl_idx != FILTER_IDX_NONE) {
|
||||||
return rl_idx == _radio.advertiser.rl_idx;
|
return rl_idx == _radio.advertiser.rl_idx;
|
||||||
|
@ -757,20 +753,30 @@ static inline bool isr_adv_ci_adva_check(struct pdu_adv *adv,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isr_adv_ci_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
static inline bool isr_adv_ci_check(struct pdu_adv *adv, struct pdu_adv *ci,
|
||||||
u8_t devmatch_ok, u8_t rl_idx)
|
u8_t devmatch_ok, u8_t *rl_idx)
|
||||||
{
|
{
|
||||||
|
/* 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) &&
|
||||||
|
#else
|
||||||
|
return (1) &&
|
||||||
|
#endif
|
||||||
|
isr_adv_ci_adva_check(adv, ci) &&
|
||||||
|
isr_adv_ci_tgta_check(adv, ci, *rl_idx);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
|
||||||
return ((((_radio.advertiser.filter_policy & 0x02) == 0) &&
|
return ((((_radio.advertiser.filter_policy & 0x02) == 0) &&
|
||||||
ctrl_rl_allowed(ci->tx_addr,
|
ctrl_rl_allowed(ci->tx_addr,
|
||||||
ci->payload.connect_ind.init_addr)) ||
|
ci->payload.connect_ind.init_addr, rl_idx)) ||
|
||||||
(devmatch_ok) || (ctrl_irk_whitelisted(rl_idx))) &&
|
(devmatch_ok) || (ctrl_irk_whitelisted(*rl_idx))) &&
|
||||||
isr_adv_ci_adva_check(adv, ci) &&
|
isr_adv_ci_adva_check(adv, ci);
|
||||||
isr_adv_ci_tgta_check(adv, ci, rl_idx);
|
|
||||||
#else
|
#else
|
||||||
return (((_radio.advertiser.filter_policy & 0x02) == 0) ||
|
return (((_radio.advertiser.filter_policy & 0x02) == 0) ||
|
||||||
(devmatch_ok)) &&
|
(devmatch_ok)) &&
|
||||||
isr_adv_ci_adva_check(adv, ci) &&
|
isr_adv_ci_adva_check(adv, ci);
|
||||||
isr_adv_ci_tgta_check(adv, ci, rl_idx);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +798,7 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
|
||||||
|
|
||||||
if ((pdu_adv->type == PDU_ADV_TYPE_SCAN_REQ) &&
|
if ((pdu_adv->type == PDU_ADV_TYPE_SCAN_REQ) &&
|
||||||
(pdu_adv->len == sizeof(struct pdu_adv_payload_scan_req)) &&
|
(pdu_adv->len == sizeof(struct pdu_adv_payload_scan_req)) &&
|
||||||
isr_adv_sr_check(pdu_adv, devmatch_ok, rl_idx)) {
|
isr_adv_sr_check(pdu_adv, devmatch_ok, &rl_idx)) {
|
||||||
|
|
||||||
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
#if defined(CONFIG_BLUETOOTH_CONTROLLER_SCAN_REQ_NOTIFY)
|
||||||
if (!IS_ENABLED(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) ||
|
if (!IS_ENABLED(CONFIG_BLUETOOTH_CONTROLLER_ADV_EXT) ||
|
||||||
|
@ -818,7 +824,7 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((pdu_adv->type == PDU_ADV_TYPE_CONNECT_IND) &&
|
} else if ((pdu_adv->type == PDU_ADV_TYPE_CONNECT_IND) &&
|
||||||
(pdu_adv->len == sizeof(struct pdu_adv_payload_connect_ind)) &&
|
(pdu_adv->len == sizeof(struct pdu_adv_payload_connect_ind)) &&
|
||||||
isr_adv_ci_check(_pdu_adv, pdu_adv, devmatch_ok, rl_idx) &&
|
isr_adv_ci_check(_pdu_adv, pdu_adv, devmatch_ok, &rl_idx) &&
|
||||||
((_radio.fc_ena == 0) || (_radio.fc_req == _radio.fc_ack)) &&
|
((_radio.fc_ena == 0) || (_radio.fc_req == _radio.fc_ack)) &&
|
||||||
(_radio.advertiser.conn)) {
|
(_radio.advertiser.conn)) {
|
||||||
struct radio_le_conn_cmplt *radio_le_conn_cmplt;
|
struct radio_le_conn_cmplt *radio_le_conn_cmplt;
|
||||||
|
|
|
@ -397,7 +397,7 @@ u8_t ll_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free)
|
||||||
return FILTER_IDX_NONE;
|
return FILTER_IDX_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr)
|
bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
@ -415,6 +415,11 @@ bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j == BDADDR_SIZE) {
|
if (j == BDADDR_SIZE) {
|
||||||
|
if (*rl_idx == FILTER_IDX_NONE) {
|
||||||
|
*rl_idx = i;
|
||||||
|
} else {
|
||||||
|
LL_ASSERT(*rl_idx == i);
|
||||||
|
}
|
||||||
return !rl[i].pirk || rl[i].dev;
|
return !rl[i].pirk || rl[i].dev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,5 +27,5 @@ bool ctrl_rl_enabled(void);
|
||||||
void ll_rl_rpa_update(bool timeout);
|
void ll_rl_rpa_update(bool timeout);
|
||||||
|
|
||||||
u8_t ll_rl_find(u8_t id_addr_type, u8_t *id_addr, u8_t *free);
|
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);
|
bool ctrl_rl_allowed(u8_t id_addr_type, u8_t *id_addr, u8_t *rl_idx);
|
||||||
void ll_rl_pdu_adv_update(int idx, struct pdu_adv *pdu);
|
void ll_rl_pdu_adv_update(int idx, struct pdu_adv *pdu);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue