Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 67 additions & 21 deletions subsys/bluetooth/host/id.c
Original file line number Diff line number Diff line change
Expand Up @@ -1965,7 +1965,7 @@
#endif /* defined(CONFIG_BT_CENTRAL) */

#if defined(CONFIG_BT_OBSERVER)
static bool is_adv_using_rand_addr(void)
static bool is_legacy_adv_enabled(void)
{
struct bt_le_ext_adv *adv;

Expand All @@ -1981,8 +1981,28 @@

adv = bt_le_adv_lookup_legacy();

return adv && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
}

static bool is_legacy_adv_using_id_addr(void)
{
struct bt_le_ext_adv *adv;

if (!IS_ENABLED(CONFIG_BT_BROADCASTER) ||
(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
/* When advertising is not enabled or is using extended

Check notice on line 1994 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:1994 - (IS_ENABLED(CONFIG_BT_EXT_ADV) && - BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) { + (IS_ENABLED(CONFIG_BT_EXT_ADV) && BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {

Check notice on line 1994 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:1994 - (IS_ENABLED(CONFIG_BT_EXT_ADV) && - BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) { + (IS_ENABLED(CONFIG_BT_EXT_ADV) && BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
* advertising HCI commands then only the scanner uses the set
* random address command.
*/
return false;
}

adv = bt_le_adv_lookup_legacy();

return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED)
&& atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY);
}

Check notice on line 2005 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:2005 - return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED) - && atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY); + return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED) && + atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY);

Check notice on line 2005 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:2005 - return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED) - && atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY); + return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED) && + atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY);

int bt_id_set_scan_own_addr(bool active_scan, uint8_t *own_addr_type)
{
Expand Down Expand Up @@ -2014,20 +2034,30 @@
* (through Kconfig).
* Use same RPA as legacy advertiser if advertising.
*/
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
!is_adv_using_rand_addr()) {
err = bt_id_set_private_addr(BT_ID_DEFAULT);
if (err) {
if (active_scan || !is_adv_using_rand_addr()) {
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
/* When using legacy advertising commands, the scanner and advertiser
* share the same address, so we cannot change it.
* When using extended advertising commands, however, the advertising
* sets have their own addresses, so we can always change the scanner
* address here.
*/
if (is_legacy_adv_using_id_addr()) {
if (bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
} else {
*own_addr_type = BT_HCI_OWN_ADDR_PUBLIC;
}
} else if (is_legacy_adv_enabled()) {
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
} else {
err = bt_id_set_private_addr(BT_ID_DEFAULT);
if (err) {
return err;
}

LOG_WRN("Ignoring failure to set address for passive scan (%d)",
err);
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
}

*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
} else if (IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
} else {
if (bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
/* If scanning with Identity Address we must set the
* random identity address for both active and passive
Expand Down Expand Up @@ -2143,23 +2173,39 @@
* problem.
*/
#if defined(CONFIG_BT_OBSERVER)
bool scan_enabled = false;
bool scan_disabled = false;
bool dev_scanning = atomic_test_bit(bt_dev.flags,
BT_DEV_SCANNING);

/* If active scan with NRPA is ongoing refresh NRPA */
if (!IS_ENABLED(CONFIG_BT_PRIVACY) &&
!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) {
scan_enabled = true;
bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);
dev_scanning) {
err = bt_le_scan_set_enable(BT_HCI_LE_SCAN_DISABLE);

Check notice on line 2184 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:2184 - bool dev_scanning = atomic_test_bit(bt_dev.flags, - BT_DEV_SCANNING); + bool dev_scanning = atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING); /* If active scan with NRPA is ongoing refresh NRPA */ if (!IS_ENABLED(CONFIG_BT_PRIVACY) && - !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) && - dev_scanning) { + !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) && dev_scanning) {

Check notice on line 2184 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:2184 - bool dev_scanning = atomic_test_bit(bt_dev.flags, - BT_DEV_SCANNING); + bool dev_scanning = atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING); /* If active scan with NRPA is ongoing refresh NRPA */ if (!IS_ENABLED(CONFIG_BT_PRIVACY) && - !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) && - dev_scanning) { + !IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) && dev_scanning) {
scan_disabled = err == 0;
}
#endif /* defined(CONFIG_BT_OBSERVER) */
err = bt_id_set_adv_private_addr(adv);
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;

#if defined(CONFIG_BT_OBSERVER)
if (scan_enabled) {
/* If we are scanning with the identity address, it does
* not make sense to set an NRPA.
*/
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) ||
!dev_scanning) {
err = bt_id_set_adv_private_addr(adv);

Check notice on line 2193 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:2193 - if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) || - !dev_scanning) { + if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) || !dev_scanning) {

Check notice on line 2193 in subsys/bluetooth/host/id.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/bluetooth/host/id.c:2193 - if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) || - !dev_scanning) { + if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) || !dev_scanning) {
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
} else {
if (id_addr->type == BT_ADDR_LE_RANDOM) {
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
} else if (id_addr->type == BT_ADDR_LE_PUBLIC) {
*own_addr_type = BT_HCI_OWN_ADDR_PUBLIC;
}
}

if (scan_disabled) {
bt_le_scan_set_enable(BT_HCI_LE_SCAN_ENABLE);
}
#else
err = bt_id_set_adv_private_addr(adv);
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
#endif /* defined(CONFIG_BT_OBSERVER) */
} else {
err = bt_id_set_adv_private_addr(adv);
Expand Down
102 changes: 102 additions & 0 deletions tests/bluetooth/host/id/bt_id_set_adv_own_addr/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include "mocks/crypto.h"
#include "mocks/scan.h"
#include "mocks/scan_expects.h"
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/net_buf.h"
#include "mocks/net_buf_expects.h"
#include "testing_common_defs.h"

#include <zephyr/bluetooth/hci.h>
Expand All @@ -24,6 +28,7 @@ static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixt
memset(&bt_dev, 0x00, sizeof(struct bt_dev));

CRYPTO_FFF_FAKES_LIST(RESET_FAKE);
HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
}

ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
Expand Down Expand Up @@ -232,6 +237,7 @@ ZTEST(bt_id_set_adv_own_addr, test_observer_scanning_re_enabled_after_updating_a

Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
Z_TEST_SKIP_IFDEF(CONFIG_BT_EXT_ADV);
Z_TEST_SKIP_IFDEF(CONFIG_BT_SCAN_WITH_IDENTITY);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_OBSERVER);

options &= ~BT_LE_ADV_OPT_CONN;
Expand All @@ -241,6 +247,102 @@ ZTEST(bt_id_set_adv_own_addr, test_observer_scanning_re_enabled_after_updating_a
atomic_set_bit(bt_dev.flags, BT_DEV_SCANNING);

bt_id_set_adv_own_addr(&adv, options, true, &own_addr_type);
zassert_true(own_addr_type == BT_HCI_OWN_ADDR_RANDOM,
"Address type reference was incorrectly set");

expect_call_count_bt_le_scan_set_enable(2, expected_args_history);
}

/*
* Test setting the advertiser address while 'CONFIG_BT_SCAN_WITH_IDENTITY' is enabled
* and scanning is ongoing. The scanner is using a random identity address.
*
* Constraints:
* - Options 'BT_LE_ADV_OPT_CONN' bit isn't set
*
* Expected behaviour:
* - Scanning is not disabled.
* - The advertiser doesn't attempt to change the identity addr with bt_id_set_adv_private_addr()
* - The advertiser uses the same identity address as the scanner.
*/
ZTEST(bt_id_set_adv_own_addr, test_set_adv_own_addr_while_scanning_with_identity_random)
{
uint32_t options = 0;
struct bt_le_ext_adv adv = {0};
struct net_buf net_buff;
int err;
uint8_t scan_own_addr_type = BT_ADDR_LE_ANONYMOUS;
uint8_t adv_own_addr_type = BT_ADDR_LE_ANONYMOUS;

Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
Z_TEST_SKIP_IFDEF(CONFIG_BT_EXT_ADV);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_OBSERVER);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_SCAN_WITH_IDENTITY);

bt_hci_cmd_alloc_fake.return_val = &net_buff;
bt_hci_cmd_send_sync_fake.return_val = 0;

options &= ~BT_LE_ADV_OPT_CONN;
bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], BT_STATIC_RANDOM_LE_ADDR_1);

err = bt_id_set_scan_own_addr(false, &scan_own_addr_type);

expect_single_call_bt_hci_cmd_alloc();
expect_single_call_bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_RANDOM_ADDRESS);

zassert_ok(err, "Unexpected error code '%d' was returned", err);
zassert_true(scan_own_addr_type == BT_HCI_OWN_ADDR_RANDOM,
"Address type reference was incorrectly set");

atomic_set_bit(bt_dev.flags, BT_DEV_SCANNING);

bt_id_set_adv_own_addr(&adv, options, true, &adv_own_addr_type);
zassert_true(adv_own_addr_type == BT_HCI_OWN_ADDR_RANDOM,
"Address type reference was incorrectly set");

expect_call_count_bt_le_scan_set_enable(0, NULL);
}

/*
* Test setting the advertiser address while 'CONFIG_BT_SCAN_WITH_IDENTITY' is enabled
* and scanning is ongoing. The scanner is using a public identity address.
*
* Constraints:
* - Options 'BT_LE_ADV_OPT_CONN' bit isn't set
*
* Expected behaviour:
* - Scanning is not disabled.
* - The advertiser doesn't attempt to change the identity addr with bt_id_set_adv_private_addr()
* - The advertiser uses the same identity address as the scanner.
*/
ZTEST(bt_id_set_adv_own_addr, test_set_adv_own_addr_while_scanning_with_identity_public)
{
uint32_t options = 0;
struct bt_le_ext_adv adv = {0};
int err;
uint8_t scan_own_addr_type = BT_ADDR_LE_ANONYMOUS;
uint8_t adv_own_addr_type = BT_ADDR_LE_ANONYMOUS;

Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
Z_TEST_SKIP_IFDEF(CONFIG_BT_EXT_ADV);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_OBSERVER);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_SCAN_WITH_IDENTITY);

options &= ~BT_LE_ADV_OPT_CONN;

bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], BT_LE_ADDR);

err = bt_id_set_scan_own_addr(false, &scan_own_addr_type);

zassert_ok(err, "Unexpected error code '%d' was returned", err);
zassert_true(scan_own_addr_type == BT_HCI_OWN_ADDR_PUBLIC,
"Address type reference was incorrectly set");

atomic_set_bit(bt_dev.flags, BT_DEV_SCANNING);

bt_id_set_adv_own_addr(&adv, options, true, &adv_own_addr_type);
zassert_true(adv_own_addr_type == BT_HCI_OWN_ADDR_PUBLIC,
"Address type reference was incorrectly set");

expect_call_count_bt_le_scan_set_enable(0, NULL);
}
4 changes: 4 additions & 0 deletions tests/bluetooth/host/id/bt_id_set_adv_own_addr/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ tests:
extra_configs:
- CONFIG_BT_SMP=y
- CONFIG_BT_PRIVACY=y
bluetooth.host.bt_id_set_adv_own_addr.scan_with_identity:
type: unit
extra_configs:
- CONFIG_BT_SCAN_WITH_IDENTITY=y
77 changes: 77 additions & 0 deletions tests/bluetooth/host/id/bt_id_set_scan_own_addr/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "mocks/crypto.h"
#include "mocks/hci_core.h"
#include "mocks/rpa.h"
#include "mocks/adv.h"
#include "mocks/adv_expects.h"
#include "testing_common_defs.h"

#include <zephyr/bluetooth/hci.h>
Expand Down Expand Up @@ -75,6 +77,81 @@ ZTEST(bt_id_set_scan_own_addr, test_set_nrpa_scan_address_no_privacy)
"Address type reference was incorrectly set");
}

/*
* Test setting scan own address while 'CONFIG_BT_PRIVACY' isn't enabled.
* Advertising is ongoing and uses a random device address.
*
* Constraints:
* - bt_id_set_private_addr() succeeds and returns 0
* - 'CONFIG_BT_SCAN_WITH_IDENTITY' isn't enabled
* - 'CONFIG_BT_PRIVACY' isn't enabled
*
* Expected behaviour:
* - bt_id_set_scan_own_addr() returns 0
* - Address type reference is updated
*/
ZTEST(bt_id_set_scan_own_addr, test_set_nrpa_scan_address_no_privacy_adv_ongoing_random_identity)
{
int err;
struct bt_le_ext_adv *adv = &bt_dev.adv;
uint8_t own_addr_type = BT_ADDR_LE_ANONYMOUS;

Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
Z_TEST_SKIP_IFDEF(CONFIG_BT_SCAN_WITH_IDENTITY);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_BROADCASTER);

bt_rand_fake.custom_fake = bt_rand_custom_fake;
bt_le_adv_lookup_legacy_fake.return_val = adv;

bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], BT_STATIC_RANDOM_LE_ADDR_1);

atomic_set_bit(adv->flags, BT_ADV_ENABLED);

err = bt_id_set_scan_own_addr(false, &own_addr_type);

zassert_ok(err, "Unexpected error code '%d' was returned", err);
zassert_true(own_addr_type == BT_HCI_OWN_ADDR_RANDOM,
"Address type reference was incorrectly set");
}

/*
* Test setting scan own address while 'CONFIG_BT_PRIVACY' isn't enabled.
* Advertising is ongoing and uses a public device address.
*
* Constraints:
* - bt_id_set_private_addr() succeeds and returns 0
* - 'CONFIG_BT_SCAN_WITH_IDENTITY' isn't enabled
* - 'CONFIG_BT_PRIVACY' isn't enabled
*
* Expected behaviour:
* - bt_id_set_scan_own_addr() returns 0
* - Address type reference is updated
*/
ZTEST(bt_id_set_scan_own_addr, test_set_nrpa_scan_address_no_privacy_adv_ongoing_public_identity)
{
int err;
struct bt_le_ext_adv *adv = &bt_dev.adv;
uint8_t own_addr_type = BT_ADDR_LE_ANONYMOUS;

Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
Z_TEST_SKIP_IFDEF(CONFIG_BT_SCAN_WITH_IDENTITY);
Z_TEST_SKIP_IFNDEF(CONFIG_BT_BROADCASTER);

bt_rand_fake.custom_fake = bt_rand_custom_fake;
bt_le_adv_lookup_legacy_fake.return_val = adv;

bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], BT_LE_ADDR);

atomic_set_bit(adv->flags, BT_ADV_ENABLED);
atomic_set_bit(adv->flags, BT_ADV_USE_IDENTITY);

err = bt_id_set_scan_own_addr(false, &own_addr_type);

zassert_ok(err, "Unexpected error code '%d' was returned", err);
zassert_true(own_addr_type == BT_HCI_OWN_ADDR_PUBLIC,
"Address type reference was incorrectly set");
}

/*
* Test setting scan own address while 'CONFIG_BT_PRIVACY' isn't enabled.
* If 'CONFIG_BT_SCAN_WITH_IDENTITY' is enabled and the default identity has an RPA address of type
Expand Down
4 changes: 4 additions & 0 deletions tests/bluetooth/host/id/bt_id_set_scan_own_addr/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ tests:
- CONFIG_BT_SCAN_WITH_IDENTITY=y
- CONFIG_BT_SMP=y
- CONFIG_BT_PRIVACY=y
bluetooth.host.bt_id_set_scan_own_addr.scan_while_advertising:
type: unit
extra_configs:
- CONFIG_BT_BROADCASTER=y
Loading