Skip to content

Commit 7d59ac1

Browse files
joerchannordicjm
authored andcommitted
[nrf fromtree] Bluetooth: host: Fix RPA timeout expiration
Fix RPA timeout expiration when BT_EXT_ADV has been enabled. Always invalidate the device RPA on RPA timeout. This RPA is used by the scan roles, and the advertiser that was started using the bt_le_adv_start API. Call the RPA expire callback only on advertising sets that are enabled and not being limited by a timeout and not using the identity address. On RPA timeout always invalidate the RPA of advertising sets that are disabled. Fixes: #51208 Fixes: #51228 Fixes: #51247 Signed-off-by: Joakim Andersson <[email protected]> (cherry picked from commit d63ae60)
1 parent bb26bf8 commit 7d59ac1

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

subsys/bluetooth/host/hci_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ enum {
8787
* of the RPA timeout.
8888
*/
8989
BT_ADV_RPA_VALID,
90+
/* The private random address of the advertiser is being updated. */
91+
BT_ADV_RPA_UPDATE,
9092
/* The advertiser set is limited by a timeout, or number of advertising
9193
* events, or both.
9294
*/

subsys/bluetooth/host/id.c

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,10 @@ int bt_id_set_adv_random_addr(struct bt_le_ext_adv *adv,
184184
return 0;
185185
}
186186

187-
static void adv_rpa_invalidate(struct bt_le_ext_adv *adv, void *data)
187+
static void adv_disabled_rpa_invalidate(struct bt_le_ext_adv *adv, void *data)
188188
{
189-
if (!atomic_test_bit(adv->flags, BT_ADV_LIMITED)) {
189+
/* Don't invalidate RPA of enabled advertising set. */
190+
if (!atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
190191
atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);
191192
}
192193
}
@@ -199,8 +200,13 @@ static void le_rpa_invalidate(void)
199200
atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);
200201
}
201202

203+
/* Invalidate RPA of advertising sets that are disabled.
204+
*
205+
* Enabled advertising set have to call rpa_expired callback first to
206+
* determine if the RPA of the advertising set should be rotated.
207+
*/
202208
if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
203-
bt_le_ext_adv_foreach(adv_rpa_invalidate, NULL);
209+
bt_le_ext_adv_foreach(adv_disabled_rpa_invalidate, NULL);
204210
}
205211
}
206212

@@ -387,41 +393,35 @@ int bt_id_set_adv_private_addr(struct bt_le_ext_adv *adv)
387393
#if defined(CONFIG_BT_EXT_ADV) && defined(CONFIG_BT_PRIVACY)
388394
static void adv_disable_rpa(struct bt_le_ext_adv *adv, void *data)
389395
{
390-
uint8_t adv_index = bt_le_ext_adv_get_index(adv);
391-
bool *adv_disabled = data;
392396
bool rpa_invalid = true;
393397

394-
adv_disabled[adv_index] = false;
395-
396-
/* Invalidate RPA only for non-limited advertising sets. */
397-
if (atomic_test_bit(adv->flags, BT_ADV_LIMITED)) {
398-
return;
399-
}
400-
401398
/* Disable advertising sets to prepare them for RPA update. */
402399
if (atomic_test_bit(adv->flags, BT_ADV_ENABLED) &&
400+
!atomic_test_bit(adv->flags, BT_ADV_LIMITED) &&
403401
!atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY)) {
404402
bt_le_adv_set_enable_ext(adv, false, NULL);
405403

406-
adv_disabled[adv_index] = true;
407-
}
404+
atomic_set_bit(adv->flags, BT_ADV_RPA_UPDATE);
408405

409-
/* Notify the user about the RPA timeout and set the RPA validity. */
410-
if (adv->cb && adv->cb->rpa_expired) {
411-
rpa_invalid = adv->cb->rpa_expired(adv);
412-
}
406+
/* Notify the user about the RPA timeout and set the RPA validity. */
407+
if (adv->cb && adv->cb->rpa_expired) {
408+
rpa_invalid = adv->cb->rpa_expired(adv);
409+
}
413410

414-
if (rpa_invalid) {
415-
atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);
411+
if (rpa_invalid) {
412+
atomic_clear_bit(adv->flags, BT_ADV_RPA_VALID);
413+
} else {
414+
/* Submit the timeout in case no advertising set updates their RPA
415+
* in the current period. This makes sure that the RPA timer is running.
416+
*/
417+
le_rpa_timeout_submit();
418+
}
416419
}
417420
}
418421

419422
static void adv_enable_rpa(struct bt_le_ext_adv *adv, void *data)
420423
{
421-
uint8_t adv_index = bt_le_ext_adv_get_index(adv);
422-
bool *adv_disabled = data;
423-
424-
if (adv_disabled[adv_index]) {
424+
if (atomic_test_and_clear_bit(adv->flags, BT_ADV_RPA_UPDATE)) {
425425
int err;
426426

427427
err = bt_id_set_adv_private_addr(adv);
@@ -438,16 +438,9 @@ static void adv_enable_rpa(struct bt_le_ext_adv *adv, void *data)
438438
static void adv_update_rpa_foreach(void)
439439
{
440440
#if defined(CONFIG_BT_EXT_ADV) && defined(CONFIG_BT_PRIVACY)
441-
bool adv_disabled[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
442-
443-
bt_le_ext_adv_foreach(adv_disable_rpa, adv_disabled);
441+
bt_le_ext_adv_foreach(adv_disable_rpa, NULL);
444442

445-
/* Submit the timeout in case all sets use the same
446-
* RPA for the next rotation period.
447-
*/
448-
le_rpa_timeout_submit();
449-
450-
bt_le_ext_adv_foreach(adv_enable_rpa, adv_disabled);
443+
bt_le_ext_adv_foreach(adv_enable_rpa, NULL);
451444
#endif
452445
}
453446

@@ -462,8 +455,6 @@ static void le_update_private_addr(void)
462455
IS_ENABLED(CONFIG_BT_EXT_ADV) &&
463456
BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features)) {
464457
adv_update_rpa_foreach();
465-
} else {
466-
le_rpa_invalidate();
467458
}
468459

469460
#if defined(CONFIG_BT_OBSERVER)
@@ -528,6 +519,7 @@ static void le_force_rpa_timeout(void)
528519

529520
k_work_cancel_delayable_sync(&bt_dev.rpa_update, &sync);
530521
#endif
522+
le_rpa_invalidate();
531523
le_update_private_addr();
532524
}
533525

@@ -549,6 +541,8 @@ static void rpa_timeout(struct k_work *work)
549541
}
550542
}
551543

544+
le_rpa_invalidate();
545+
552546
if (IS_ENABLED(CONFIG_BT_BROADCASTER)) {
553547
bt_le_ext_adv_foreach(adv_is_private_enabled, &adv_enabled);
554548
}
@@ -558,7 +552,6 @@ static void rpa_timeout(struct k_work *work)
558552
atomic_test_bit(bt_dev.flags, BT_DEV_INITIATING) ||
559553
(atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
560554
atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)))) {
561-
le_rpa_invalidate();
562555
return;
563556
}
564557

0 commit comments

Comments
 (0)