diff --git a/include/bluetooth/addr.h b/include/bluetooth/addr.h index bd6669baa08..a2d31da550d 100644 --- a/include/bluetooth/addr.h +++ b/include/bluetooth/addr.h @@ -29,6 +29,12 @@ extern "C" { #define BT_ADDR_LE_RANDOM 0x01 #define BT_ADDR_LE_PUBLIC_ID 0x02 #define BT_ADDR_LE_RANDOM_ID 0x03 +#define BT_ADDR_LE_UNRESOLVED 0xFE /* Resolvable Private Address + * (Controller unable to resolve) + */ +#define BT_ADDR_LE_ANONYMOUS 0xFF /* No address provided + * (anonymous advertisement) + */ /** Length in bytes of a standard Bluetooth address */ #define BT_ADDR_SIZE 6 diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 7558c953afd..30b08e706b9 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -5095,6 +5095,41 @@ static void le_ext_adv_legacy_report(struct pdu_data *pdu_data, memcpy(&adv_info->data[0], &adv->adv_ind.data[0], data_len); } +static uint8_t ext_adv_direct_addr_type(struct lll_scan *lll, + bool resolved, bool direct, + uint8_t rx_addr_type, + const uint8_t *const rx_addr) +{ + if (0) { +#if defined(CONFIG_BT_CTLR_PRIVACY) + } else if (resolved) { + if (!direct) { + struct ll_scan_set *scan; + + scan = HDR_LLL2ULL(lll); + if ((rx_addr_type == lll->init_addr_type) && + !memcmp(lll->init_addr, rx_addr, BDADDR_SIZE)) { + return scan->own_addr_type; + } else { + return scan->own_addr_type | BIT(1); + } + } else { + return BT_ADDR_LE_UNRESOLVED; + } +#endif /* CONFIG_BT_CTLR_PRIVACY */ + } else { + if (!direct) { + struct ll_scan_set *scan; + + scan = HDR_LLL2ULL(lll); + + return scan->own_addr_type; + } else { + return BT_ADDR_LE_UNRESOLVED; + } + } +} + static void node_rx_extra_list_release(struct node_rx_pdu *node_rx_extra) { while (node_rx_extra) { @@ -5219,6 +5254,7 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, do { struct pdu_adv_adi *adi_curr = NULL; uint8_t direct_addr_type_curr = 0U; + bool direct_resolved_curr = false; uint8_t *direct_addr_curr = NULL; uint8_t adv_addr_type_curr = 0U; struct pdu_adv_com_ext_adv *p; @@ -5238,6 +5274,8 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, #if defined(CONFIG_BT_CTLR_PRIVACY) uint8_t rl_idx_curr = node_rx_curr->hdr.rx_ftr.rl_idx; + + direct_resolved_curr = node_rx_curr->hdr.rx_ftr.direct_resolved; #endif /* CONFIG_BT_CTLR_PRIVACY */ /* The Link Layer currently returns RSSI as an absolute value */ @@ -5278,14 +5316,21 @@ static void le_ext_adv_report(struct pdu_data *pdu_data, } if (h->tgt_addr) { + struct lll_scan *lll; bt_addr_le_t addr; - direct_addr_type_curr = adv->rx_addr; + lll = node_rx->hdr.rx_ftr.param; + direct_addr_type_curr = + ext_adv_direct_addr_type(lll, + direct_resolved_curr, + direct_curr, + adv->rx_addr, ptr); direct_addr_curr = ptr; + ptr += BDADDR_SIZE; addr.type = adv->rx_addr; - (void)memcpy(addr.a.val, ptr, sizeof(bt_addr_t)); - ptr += BDADDR_SIZE; + (void)memcpy(addr.a.val, direct_addr_curr, + sizeof(bt_addr_t)); BT_DBG(" TgtA: %s", bt_addr_le_str(&addr)); } diff --git a/subsys/bluetooth/controller/ll_sw/lll.h b/subsys/bluetooth/controller/ll_sw/lll.h index e1905a0e217..cde58b903c0 100644 --- a/subsys/bluetooth/controller/ll_sw/lll.h +++ b/subsys/bluetooth/controller/ll_sw/lll.h @@ -280,7 +280,21 @@ struct node_rx_ftr { uint32_t ticks_anchor; uint32_t radio_end_us; uint8_t rssi; + +#if defined(CONFIG_BT_CTLR_PRIVACY) + uint8_t rl_idx; + uint8_t lrpa_used:1; +#endif /* CONFIG_BT_CTLR_PRIVACY */ + +#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) + uint8_t direct:1; +#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ + #if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_OBSERVER) +#if defined(CONFIG_BT_CTLR_PRIVACY) + uint8_t direct_resolved:1; +#endif /* CONFIG_BT_CTLR_PRIVACY */ + uint8_t aux_lll_sched:1; uint8_t aux_w4next:1; uint8_t aux_failed:1; @@ -292,13 +306,7 @@ struct node_rx_ftr { uint8_t scan_req:1; uint8_t scan_rsp:1; #endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_OBSERVER */ -#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) - uint8_t direct:1; -#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ -#if defined(CONFIG_BT_CTLR_PRIVACY) - uint8_t lrpa_used:1; - uint8_t rl_idx; -#endif /* CONFIG_BT_CTLR_PRIVACY */ + #if defined(CONFIG_BT_HCI_MESH_EXT) uint8_t chan_idx; #endif /* CONFIG_BT_HCI_MESH_EXT */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c index 2cb733af546..65aa7f39e27 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c @@ -92,8 +92,8 @@ static inline bool isr_scan_tgta_rpa_check(struct lll_scan *lll, bool *dir_report); static inline bool isr_scan_rsp_adva_matches(struct pdu_adv *srsp); static int isr_rx_scan_report(struct lll_scan *lll, uint8_t rssi_ready, - uint8_t phy_flags_rx, uint8_t rl_idx, - bool dir_report); + uint8_t phy_flags_rx, uint8_t irkmatch_ok, + uint8_t rl_idx, bool dir_report); int lll_scan_init(void) { @@ -1304,8 +1304,7 @@ static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx, /* save the adv packet */ err = isr_rx_scan_report(lll, rssi_ready, phy_flags_rx, - irkmatch_ok ? rl_idx : FILTER_IDX_NONE, - false); + irkmatch_ok, rl_idx, false); if (err) { return err; } @@ -1409,9 +1408,7 @@ static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx, /* save the scan response packet */ err = isr_rx_scan_report(lll, rssi_ready, phy_flags_rx, - irkmatch_ok ? rl_idx : - FILTER_IDX_NONE, - dir_report); + irkmatch_ok, rl_idx, dir_report); if (err) { /* Auxiliary PDU LLL scanning has been setup */ if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) && @@ -1499,8 +1496,8 @@ static inline bool isr_scan_rsp_adva_matches(struct pdu_adv *srsp) } static int isr_rx_scan_report(struct lll_scan *lll, uint8_t rssi_ready, - uint8_t phy_flags_rx, uint8_t rl_idx, - bool dir_report) + uint8_t phy_flags_rx, uint8_t irkmatch_ok, + uint8_t rl_idx, bool dir_report) { struct node_rx_pdu *node_rx; int err = 0; @@ -1581,12 +1578,18 @@ static int isr_rx_scan_report(struct lll_scan *lll, uint8_t rssi_ready, BT_HCI_LE_RSSI_NOT_AVAILABLE; #if defined(CONFIG_BT_CTLR_PRIVACY) /* save the resolving list index. */ - node_rx->hdr.rx_ftr.rl_idx = rl_idx; + node_rx->hdr.rx_ftr.rl_idx = irkmatch_ok ? rl_idx : FILTER_IDX_NONE; + +#if defined(CONFIG_BT_CTLR_ADV_EXT) + node_rx->hdr.rx_ftr.direct_resolved = (rl_idx != FILTER_IDX_NONE); +#endif /* CONFIG_BT_CTLR_ADV_EXT */ #endif /* CONFIG_BT_CTLR_PRIVACY */ + #if defined(CONFIG_BT_CTLR_EXT_SCAN_FP) /* save the directed adv report flag */ node_rx->hdr.rx_ftr.direct = dir_report; #endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */ + #if defined(CONFIG_BT_HCI_MESH_EXT) if (node_rx->hdr.type == NODE_RX_TYPE_MESH_REPORT) { /* save channel and anchor point ticks. */