Bluetooth: controller: Set local RPA field only when generated

Set the local RPA field of the enhanced connection complete event only
when the address was generated by the controller. If the host has
set an RPA and this one was used the controller should return all
zeroes.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-04-23 16:54:50 +02:00 committed by Carles Cufí
commit e9b39cd304
10 changed files with 40 additions and 55 deletions

View file

@ -2871,19 +2871,8 @@ static void le_conn_complete(struct pdu_data *pdu_data, u16_t handle,
memcpy(&leecc->peer_addr.a.val[0], &node_rx->peer_addr[0],
BDADDR_SIZE);
/* Note: this could be an RPA set as the random address by
* the Host instead of generated by the controller. That said,
* this should make no difference.
*/
if ((node_rx->own_addr_type) &&
((node_rx->own_addr[5] & 0xc0) == 0x40)) {
memcpy(&leecc->local_rpa.val[0], &node_rx->own_addr[0],
BDADDR_SIZE);
} else {
(void)memset(&leecc->local_rpa.val[0], 0x0,
BDADDR_SIZE);
}
memcpy(&leecc->local_rpa.val[0], &node_rx->local_rpa[0],
BDADDR_SIZE);
memcpy(&leecc->peer_rpa.val[0], &node_rx->peer_rpa[0],
BDADDR_SIZE);

View file

@ -191,6 +191,7 @@ struct node_rx_ftr {
u32_t us_radio_rdy;
u8_t rssi;
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t lrpa_used:1;
u8_t rl_idx;
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)

View file

@ -42,6 +42,7 @@ struct lll_resolvelist {
#endif
};
bool ull_filter_lll_lrpa_used(u8_t rl_idx);
extern bt_addr_t *ull_filter_lll_lrpa_get(u8_t rl_idx);
extern u8_t *ull_filter_lll_irks_get(u8_t *count);
extern u8_t ull_filter_lll_rl_idx(bool whitelist, u8_t devmatch_id);

View file

@ -864,6 +864,7 @@ static inline u32_t isr_rx_pdu(struct lll_scan *lll, u8_t devmatch_ok,
#if defined(CONFIG_BT_CTLR_PRIVACY)
ftr->rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE;
ftr->lrpa_used = lll->rpa_gen && lrpa;
#endif /* CONFIG_BT_CTLR_PRIVACY */
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {

View file

@ -435,7 +435,6 @@ u8_t ll_adv_enable(u8_t enable)
u32_t ticks_anchor;
#endif /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
volatile u32_t ret_cb = TICKER_STATUS_BUSY;
u8_t rl_idx = FILTER_IDX_NONE;
u32_t ticks_slot_overhead;
struct pdu_adv *pdu_scan;
struct pdu_adv *pdu_adv;
@ -491,22 +490,24 @@ u8_t ll_adv_enable(u8_t enable)
bool priv = false;
#if defined(CONFIG_BT_CTLR_PRIVACY)
lll->rl_idx = FILTER_IDX_NONE;
/* Prepare whitelist and optionally resolving list */
ull_filter_adv_update(lll->filter_policy);
if (adv->own_addr_type == BT_ADDR_LE_PUBLIC_ID ||
adv->own_addr_type == BT_ADDR_LE_RANDOM_ID) {
/* Look up the resolving list */
rl_idx = ull_filter_rl_find(adv->id_addr_type,
adv->id_addr, NULL);
lll->rl_idx = ull_filter_rl_find(adv->id_addr_type,
adv->id_addr, NULL);
if (rl_idx != FILTER_IDX_NONE) {
if (lll->rl_idx != FILTER_IDX_NONE) {
/* Generate RPAs if required */
ull_filter_rpa_update(false);
}
ull_filter_adv_pdu_update(adv, rl_idx, pdu_adv);
ull_filter_adv_pdu_update(adv, rl_idx, pdu_scan);
ull_filter_adv_pdu_update(adv, pdu_adv);
ull_filter_adv_pdu_update(adv, pdu_scan);
priv = true;
}
@ -714,12 +715,6 @@ u8_t ll_adv_enable(u8_t enable)
}
#endif /* CONFIG_BT_PERIPHERAL */
#if defined(CONFIG_BT_CTLR_PRIVACY)
lll->rl_idx = rl_idx;
#else
ARG_UNUSED(rl_idx);
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
const u8_t phy = lll->phy_p;
#else

View file

@ -281,8 +281,7 @@ struct node_rx_cc {
u8_t peer_addr[BDADDR_SIZE];
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t peer_rpa[BDADDR_SIZE];
u8_t own_addr_type;
u8_t own_addr[BDADDR_SIZE];
u8_t local_rpa[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
u16_t interval;
u16_t latency;

View file

@ -574,12 +574,12 @@ void ull_filter_rpa_update(bool timeout)
}
#if defined(CONFIG_BT_BROADCASTER)
void ull_filter_adv_pdu_update(struct ll_adv_set *adv, u8_t idx,
struct pdu_adv *pdu)
void ull_filter_adv_pdu_update(struct ll_adv_set *adv, struct pdu_adv *pdu)
{
u8_t *adva = pdu->type == PDU_ADV_TYPE_SCAN_RSP ?
&pdu->scan_rsp.addr[0] :
&pdu->adv_ind.addr[0];
u8_t idx = adv->lll.rl_idx;
/* AdvA */
if (idx < ARRAY_SIZE(rl) && rl[idx].lirk) {
@ -655,6 +655,11 @@ void ull_filter_reset(bool init)
}
#if defined(CONFIG_BT_CTLR_PRIVACY)
bool ull_filter_lll_lrpa_used(u8_t rl_idx)
{
return rl_idx < ARRAY_SIZE(rl) && rl[rl_idx].lirk;
}
bt_addr_t *ull_filter_lll_lrpa_get(u8_t rl_idx)
{
if ((rl_idx >= ARRAY_SIZE(rl)) || !rl[rl_idx].lirk ||
@ -959,15 +964,14 @@ static void rpa_adv_refresh(struct ll_adv_set *adv)
{
struct pdu_adv *prev;
struct pdu_adv *pdu;
u8_t rl_idx, idx;
u8_t idx;
if (adv->own_addr_type != BT_ADDR_LE_PUBLIC_ID &&
adv->own_addr_type != BT_ADDR_LE_RANDOM_ID) {
return;
}
rl_idx = ull_filter_rl_find(adv->id_addr_type, adv->id_addr, NULL);
if (rl_idx >= ARRAY_SIZE(rl)) {
if (adv->lll.rl_idx >= ARRAY_SIZE(rl)) {
return;
}
@ -982,7 +986,7 @@ static void rpa_adv_refresh(struct ll_adv_set *adv)
pdu->chan_sel = 0;
}
ull_filter_adv_pdu_update(adv, rl_idx, pdu);
ull_filter_adv_pdu_update(adv, pdu);
memcpy(&pdu->adv_ind.data[0], &prev->adv_ind.data[0],
prev->len - BDADDR_SIZE);

View file

@ -8,7 +8,6 @@ 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);
void ull_filter_adv_pdu_update(struct ll_adv_set *adv, 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

@ -456,13 +456,6 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
pdu_tx = (void *)((struct node_rx_pdu *)rx)->pdu;
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t own_addr_type = pdu_tx->tx_addr;
u8_t own_addr[BDADDR_SIZE];
u8_t rl_idx = ftr->rl_idx;
memcpy(own_addr, &pdu_tx->connect_ind.init_addr[0], BDADDR_SIZE);
#endif
peer_addr_type = pdu_tx->rx_addr;
memcpy(peer_addr, &pdu_tx->connect_ind.adv_addr[0], BDADDR_SIZE);
@ -474,11 +467,16 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
cc->role = 0U;
#if defined(CONFIG_BT_CTLR_PRIVACY)
cc->own_addr_type = own_addr_type;
memcpy(&cc->own_addr[0], &own_addr[0], BDADDR_SIZE);
u8_t rl_idx = ftr->rl_idx;
if (ftr->lrpa_used) {
memcpy(&cc->local_rpa[0], &pdu_tx->connect_ind.init_addr[0],
BDADDR_SIZE);
} else {
memset(&cc->local_rpa[0], 0x0, 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, &cc->peer_addr_type,
&cc->peer_addr[0]);

View file

@ -126,14 +126,6 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
memcpy((void *)&conn->slave.force, &lll->access_addr[0],
sizeof(conn->slave.force));
#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 = ftr->rl_idx;
memcpy(own_addr, &pdu_adv->connect_ind.adv_addr[0], BDADDR_SIZE);
#endif
peer_addr_type = pdu_adv->tx_addr;
memcpy(peer_addr, pdu_adv->connect_ind.init_addr, BDADDR_SIZE);
@ -144,8 +136,14 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
cc->role = 1U;
#if defined(CONFIG_BT_CTLR_PRIVACY)
cc->own_addr_type = own_addr_type;
memcpy(&cc->own_addr[0], &own_addr[0], BDADDR_SIZE);
u8_t rl_idx = ftr->rl_idx;
if (ull_filter_lll_lrpa_used(adv->lll.rl_idx)) {
memcpy(&cc->local_rpa[0], &pdu_adv->connect_ind.adv_addr[0],
BDADDR_SIZE);
} else {
memset(&cc->local_rpa[0], 0x0, BDADDR_SIZE);
}
if (rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */