Bluetooth: controller: Translate addresses in adv reports

Advertising reports generated by a scanner require the controller to
look up the resolving list to supply the host with an ID address instead
of the RPA that has been sent over the air.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Carles Cufi 2017-08-04 07:13:29 +02:00
commit 3a35859410
6 changed files with 61 additions and 22 deletions

View file

@ -1628,8 +1628,11 @@ static void le_advertising_report(struct pdu_data *pdu_data, u8_t *b,
struct pdu_adv *adv = (struct pdu_adv *)pdu_data;
struct bt_hci_evt_le_advertising_info *adv_info;
u8_t data_len;
u8_t *rssi;
u8_t info_len;
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
u8_t rl_idx;
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
u8_t *rssi;
if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
!(le_event_mask & BT_EVT_MASK_LE_ADVERTISING_REPORT)) {
@ -1692,9 +1695,25 @@ fill_report:
adv_info = (void *)(((u8_t *)sep) + sizeof(*sep));
adv_info->evt_type = c_adv_type[adv->type];
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
rl_idx = b[offsetof(struct radio_pdu_node_rx, pdu_data) +
offsetof(struct pdu_adv, payload) + adv->len + 1];
if (rl_idx < ll_rl_size_get()) {
/* Store identity address */
ll_rl_id_addr_get(rl_idx, &adv_info->addr.type,
&adv_info->addr.a.val[0]);
/* Mark it as identity address from RPA (0x02, 0x03) */
adv_info->addr.type += 2;
} else {
#else
if (1) {
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
adv_info->addr.type = adv->tx_addr;
memcpy(&adv_info->addr.a.val[0], &adv->payload.adv_ind.addr[0],
sizeof(bt_addr_t));
}
adv_info->length = data_len;
memcpy(&adv_info->data[0], &adv->payload.adv_ind.data[0], data_len);

View file

@ -40,6 +40,7 @@ u32_t ll_wl_clear(void);
u32_t ll_wl_add(bt_addr_le_t *addr);
u32_t ll_wl_remove(bt_addr_le_t *addr);
void ll_rl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr);
u32_t ll_rl_size_get(void);
u32_t ll_rl_clear(void);
u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],

View file

@ -15,6 +15,7 @@
#include <bluetooth/hci.h>
#include <misc/util.h>
#include "ll.h"
#include "hal/cpu.h"
#include "hal/rand.h"
#include "hal/ecb.h"
@ -365,7 +366,7 @@ u32_t radio_init(void *hf_clock, u8_t sca, u8_t connection_count_max,
/* initialise rx memory size and count */
_radio.packet_data_octets_max = packet_data_octets_max;
if ((PDU_AC_SIZE_MAX + 1) <
if ((PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA) <
(offsetof(struct pdu_data, payload) +
_radio.packet_data_octets_max)) {
_radio.packet_rx_data_pool_size =
@ -375,7 +376,7 @@ u32_t radio_init(void *hf_clock, u8_t sca, u8_t connection_count_max,
} else {
_radio.packet_rx_data_pool_size =
(MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) +
(PDU_AC_SIZE_MAX + 1)) * rx_count_max);
(PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA)) * rx_count_max);
}
_radio.packet_rx_data_size = PACKET_RX_DATA_SIZE_MIN;
_radio.packet_rx_data_count = (_radio.packet_rx_data_pool_size /
@ -932,7 +933,7 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
if (rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */
/* Store identity address */
ctrl_id_addr_get(rl_idx,
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) */
@ -1083,7 +1084,7 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
return 1;
}
static u32_t isr_rx_scan_report(u8_t rssi_ready)
static u32_t isr_rx_scan_report(u8_t rssi_ready, u8_t rl_idx)
{
struct radio_pdu_node_rx *radio_pdu_node_rx;
struct pdu_adv *pdu_adv_rx;
@ -1124,6 +1125,12 @@ static u32_t isr_rx_scan_report(u8_t rssi_ready)
pdu_adv_rx->len] =
(rssi_ready) ? (radio_rssi_get() & 0x7f) : 0x7f;
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
/* save the resolving list index */
((u8_t *)pdu_adv_rx)[offsetof(struct pdu_adv, payload) +
pdu_adv_rx->len + 1] = rl_idx;
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
packet_rx_enqueue();
return 0;
@ -1349,7 +1356,7 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
if (irkmatch_ok && rl_idx != FILTER_IDX_NONE) {
/* TODO: store rl_idx instead if safe */
/* Store identity address */
ctrl_id_addr_get(rl_idx,
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) */
@ -1477,7 +1484,9 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
u32_t err;
/* save the adv packet */
err = isr_rx_scan_report(rssi_ready);
err = isr_rx_scan_report(rssi_ready,
irkmatch_ok ? rl_idx :
FILTER_IDX_NONE);
if (err) {
return err;
}
@ -1532,7 +1541,9 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
u32_t err;
/* save the scan response packet */
err = isr_rx_scan_report(rssi_ready);
err = isr_rx_scan_report(rssi_ready,
irkmatch_ok ? rl_idx :
FILTER_IDX_NONE);
if (err) {
return err;
}
@ -6562,11 +6573,13 @@ static inline void event_len_prep(struct connection *conn)
}
/* calculate the new rx node size and new count */
if (conn->max_rx_octets < (PDU_AC_SIZE_MAX + 1)) {
if (conn->max_rx_octets < (PDU_AC_SIZE_MAX +
PDU_AC_SIZE_EXTRA)) {
_radio.packet_rx_data_size =
MROUND(offsetof(struct radio_pdu_node_rx,
pdu_data) +
(PDU_AC_SIZE_MAX + 1));
(PDU_AC_SIZE_MAX +
PDU_AC_SIZE_EXTRA));
} else {
_radio.packet_rx_data_size =
packet_rx_data_size;

View file

@ -261,10 +261,17 @@ struct pdu_data_q_tx {
struct radio_pdu_node_tx *node_tx;
};
/* Extra bytes for enqueued rx_node metadata: rssi and resolving index */
#if defined(CONFIG_BLUETOOTH_CONTROLLER_PRIVACY)
#define PDU_AC_SIZE_EXTRA 2
#else
#define PDU_AC_SIZE_EXTRA 1
#endif /* CONFIG_BLUETOOTH_CONTROLLER_PRIVACY */
/* Minimum Rx Data allocation size */
#define PACKET_RX_DATA_SIZE_MIN \
MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) + \
(PDU_AC_SIZE_MAX + 1))
(PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA))
/* Minimum Tx Ctrl allocation size */
#define PACKET_TX_CTRL_SIZE_MIN \
@ -284,13 +291,13 @@ struct pdu_data_q_tx {
#define LL_MEM_RX_POOL_SZ (MROUND(offsetof(struct radio_pdu_node_rx,\
pdu_data) + ((\
(PDU_AC_SIZE_MAX + 1) < \
(PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA) < \
(offsetof(struct pdu_data, payload) + \
RADIO_LL_LENGTH_OCTETS_RX_MAX)) ? \
(offsetof(struct pdu_data, payload) + \
RADIO_LL_LENGTH_OCTETS_RX_MAX) \
: \
(PDU_AC_SIZE_MAX + 1))) * \
(PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA))) * \
(RADIO_PACKET_COUNT_RX_MAX + 3))
#define LL_MEM_RX_LINK_POOL (sizeof(void *) * 2 * ((RADIO_PACKET_COUNT_RX_MAX +\

View file

@ -447,7 +447,7 @@ bool ctrl_rl_idx_allowed(u8_t irkmatch_ok, u8_t rl_idx)
return !rl[rl_idx].pirk || rl[rl_idx].dev;
}
void ctrl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr)
void ll_rl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr)
{
LL_ASSERT(rl_idx < CONFIG_BLUETOOTH_CONTROLLER_RL_SIZE);
LL_ASSERT(rl[rl_idx].taken);

View file

@ -23,7 +23,6 @@ bt_addr_t *ctrl_lrpa_get(u8_t rl_idx);
u8_t *ctrl_irks_get(u8_t *count);
u8_t ctrl_rl_idx(bool whitelist, u8_t devmatch_id);
u8_t ctrl_rl_irk_idx(u8_t irkmatch_id);
void ctrl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr);
bool ctrl_irk_whitelisted(u8_t rl_idx);
bool ctrl_rl_enabled(void);