From 081879d9538eaa7906a2cddd9ce86d76249bcefd Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 21 Apr 2026 17:33:46 +0530 Subject: [PATCH] fix(nimble): Fix identity addr replacement in adv report --- nimble/host/include/host/ble_gap.h | 13 +++++++++++++ nimble/host/src/ble_hs_hci_evt.c | 18 +++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index c1d0b3e80..66ab3704a 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -529,6 +529,19 @@ struct ble_gap_disc_desc { * event type (BLE_ADDR_ANY otherwise). */ ble_addr_t direct_addr; +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + /** Over-the-air advertiser address as received from the controller. + * + * When host-based privacy is enabled and the peer is a bonded device using + * a resolvable private address (RPA), `addr` is replaced with the stored + * identity address so applications can correlate against their bond + * records. This field always carries the original on-air address (RPA + * when resolvable, or the same value as `addr` otherwise) so applications + * that need the OTA address (e.g. for display or direct connect) can use + * it. Populated only when BLE_HOST_BASED_PRIVACY is enabled. + */ + ble_addr_t ota_addr; +#endif }; struct ble_gap_repeat_pairing { diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index c9efef319..6b06ad905 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -1014,14 +1014,22 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len) memcpy(desc.addr.val, rpt->addr, BLE_DEV_ADDR_LEN); #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + + /* Preserve the on-air (OTA) address before any identity-address swap + * below, so applications that need the actual advertised address (RPA + * when the peer is using privacy) can access it via desc.ota_addr. + */ + desc.ota_addr = desc.addr; + struct ble_hs_resolv_entry *rl = NULL; ble_hs_lock(); rl = ble_hs_resolv_rpa_addr(desc.addr.val, desc.addr.type); if (rl != NULL) { - if(desc.addr.type == 1) { - rl->rl_isrpa = 1; - } + if (desc.addr.type == 1) { + rl->rl_isrpa = 1; + } + memcpy(desc.addr.val, rl->rl_identity_addr, BLE_DEV_ADDR_LEN); desc.addr.type = rl->rl_addr_type; } @@ -1062,6 +1070,10 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, const void *data, unsigned int l memcpy(desc.direct_addr.val, ev->reports[i].dir_addr, BLE_DEV_ADDR_LEN); desc.rssi = ev->reports[i].rssi; +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + /* Directed adv path does not perform identity-swap; mirror OTA addr. */ + desc.ota_addr = desc.addr; +#endif ble_gap_rx_adv_report(&desc); }