Skip to content

Commit 43223a1

Browse files
olivier-le-sagedanieldegrasse
authored andcommitted
bluetooth: host: Fix uninitialized own_addr_type for legacy scan+adv
In 25c993e a new case was introduced where own_addr_type is not set by bt_id_set_scan_own_addr properly. This led to issues for users where increasing their zephyr version led to failures to start scanning after advertising in the case where CONFIG_BT_SCAN_WITH_IDENTITY=n and legacy advertising commands are used. Signed-off-by: Olivier Lesage <olivier.lesage@nordicsemi.no>
1 parent 0654fb4 commit 43223a1

File tree

3 files changed

+123
-12
lines changed

3 files changed

+123
-12
lines changed

subsys/bluetooth/host/id.c

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,7 @@ int bt_id_set_create_conn_own_addr(bool use_filter, uint8_t *own_addr_type)
17891789
#endif /* defined(CONFIG_BT_CENTRAL) */
17901790

17911791
#if defined(CONFIG_BT_OBSERVER)
1792-
static bool is_adv_using_rand_addr(void)
1792+
static bool is_legacy_adv_enabled(void)
17931793
{
17941794
struct bt_le_ext_adv *adv;
17951795

@@ -1805,7 +1805,27 @@ static bool is_adv_using_rand_addr(void)
18051805

18061806
adv = bt_le_adv_lookup_legacy();
18071807

1808-
return adv && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
1808+
return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
1809+
}
1810+
1811+
static bool is_legacy_adv_using_id_addr(void)
1812+
{
1813+
struct bt_le_ext_adv *adv;
1814+
1815+
if (!IS_ENABLED(CONFIG_BT_BROADCASTER) ||
1816+
(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
1817+
BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
1818+
/* When advertising is not enabled or is using extended
1819+
* advertising HCI commands then only the scanner uses the set
1820+
* random address command.
1821+
*/
1822+
return false;
1823+
}
1824+
1825+
adv = bt_le_adv_lookup_legacy();
1826+
1827+
return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED)
1828+
&& atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY);
18091829
}
18101830

18111831
int bt_id_set_scan_own_addr(bool active_scan, uint8_t *own_addr_type)
@@ -1838,20 +1858,30 @@ int bt_id_set_scan_own_addr(bool active_scan, uint8_t *own_addr_type)
18381858
* (through Kconfig).
18391859
* Use same RPA as legacy advertiser if advertising.
18401860
*/
1841-
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
1842-
!is_adv_using_rand_addr()) {
1843-
err = bt_id_set_private_addr(BT_ID_DEFAULT);
1844-
if (err) {
1845-
if (active_scan || !is_adv_using_rand_addr()) {
1861+
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
1862+
/* When using legacy advertising commands, the scanner and advertiser
1863+
* share the same address, so we cannot change it.
1864+
* When using extended advertising commands, however, the advertising
1865+
* sets have their own addresses, so we can always change the scanner
1866+
* address here.
1867+
*/
1868+
if (is_legacy_adv_using_id_addr()) {
1869+
if (bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
1870+
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
1871+
} else {
1872+
*own_addr_type = BT_HCI_OWN_ADDR_PUBLIC;
1873+
}
1874+
} else if (is_legacy_adv_enabled()) {
1875+
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
1876+
} else {
1877+
err = bt_id_set_private_addr(BT_ID_DEFAULT);
1878+
if (err) {
18461879
return err;
18471880
}
18481881

1849-
LOG_WRN("Ignoring failure to set address for passive scan (%d)",
1850-
err);
1882+
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
18511883
}
1852-
1853-
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
1854-
} else if (IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
1884+
} else {
18551885
if (bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
18561886
/* If scanning with Identity Address we must set the
18571887
* random identity address for both active and passive

tests/bluetooth/host/id/bt_id_set_scan_own_addr/src/main.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "mocks/crypto.h"
88
#include "mocks/hci_core.h"
99
#include "mocks/rpa.h"
10+
#include "mocks/adv.h"
11+
#include "mocks/adv_expects.h"
1012
#include "testing_common_defs.h"
1113

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

80+
/*
81+
* Test setting scan own address while 'CONFIG_BT_PRIVACY' isn't enabled.
82+
* Advertising is ongoing and uses a random device address.
83+
*
84+
* Constraints:
85+
* - bt_id_set_private_addr() succeeds and returns 0
86+
* - 'CONFIG_BT_SCAN_WITH_IDENTITY' isn't enabled
87+
* - 'CONFIG_BT_PRIVACY' isn't enabled
88+
*
89+
* Expected behaviour:
90+
* - bt_id_set_scan_own_addr() returns 0
91+
* - Address type reference is updated
92+
*/
93+
ZTEST(bt_id_set_scan_own_addr, test_set_nrpa_scan_address_no_privacy_adv_ongoing_random_identity)
94+
{
95+
int err;
96+
struct bt_le_ext_adv *adv = &bt_dev.adv;
97+
uint8_t own_addr_type = BT_ADDR_LE_ANONYMOUS;
98+
99+
Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
100+
Z_TEST_SKIP_IFDEF(CONFIG_BT_SCAN_WITH_IDENTITY);
101+
Z_TEST_SKIP_IFNDEF(CONFIG_BT_BROADCASTER);
102+
103+
bt_rand_fake.custom_fake = bt_rand_custom_fake;
104+
bt_le_adv_lookup_legacy_fake.return_val = adv;
105+
106+
bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], BT_STATIC_RANDOM_LE_ADDR_1);
107+
108+
atomic_set_bit(adv->flags, BT_ADV_ENABLED);
109+
110+
err = bt_id_set_scan_own_addr(false, &own_addr_type);
111+
112+
zassert_ok(err, "Unexpected error code '%d' was returned", err);
113+
zassert_true(own_addr_type == BT_HCI_OWN_ADDR_RANDOM,
114+
"Address type reference was incorrectly set");
115+
}
116+
117+
/*
118+
* Test setting scan own address while 'CONFIG_BT_PRIVACY' isn't enabled.
119+
* Advertising is ongoing and uses a public device address.
120+
*
121+
* Constraints:
122+
* - bt_id_set_private_addr() succeeds and returns 0
123+
* - 'CONFIG_BT_SCAN_WITH_IDENTITY' isn't enabled
124+
* - 'CONFIG_BT_PRIVACY' isn't enabled
125+
*
126+
* Expected behaviour:
127+
* - bt_id_set_scan_own_addr() returns 0
128+
* - Address type reference is updated
129+
*/
130+
ZTEST(bt_id_set_scan_own_addr, test_set_nrpa_scan_address_no_privacy_adv_ongoing_public_identity)
131+
{
132+
int err;
133+
struct bt_le_ext_adv *adv = &bt_dev.adv;
134+
uint8_t own_addr_type = BT_ADDR_LE_ANONYMOUS;
135+
136+
Z_TEST_SKIP_IFDEF(CONFIG_BT_PRIVACY);
137+
Z_TEST_SKIP_IFDEF(CONFIG_BT_SCAN_WITH_IDENTITY);
138+
Z_TEST_SKIP_IFNDEF(CONFIG_BT_BROADCASTER);
139+
140+
bt_rand_fake.custom_fake = bt_rand_custom_fake;
141+
bt_le_adv_lookup_legacy_fake.return_val = adv;
142+
143+
bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], BT_LE_ADDR);
144+
145+
atomic_set_bit(adv->flags, BT_ADV_ENABLED);
146+
atomic_set_bit(adv->flags, BT_ADV_USE_IDENTITY);
147+
148+
err = bt_id_set_scan_own_addr(false, &own_addr_type);
149+
150+
zassert_ok(err, "Unexpected error code '%d' was returned", err);
151+
zassert_true(own_addr_type == BT_HCI_OWN_ADDR_PUBLIC,
152+
"Address type reference was incorrectly set");
153+
}
154+
78155
/*
79156
* Test setting scan own address while 'CONFIG_BT_PRIVACY' isn't enabled.
80157
* If 'CONFIG_BT_SCAN_WITH_IDENTITY' is enabled and the default identity has an RPA address of type

tests/bluetooth/host/id/bt_id_set_scan_own_addr/testcase.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ tests:
2020
- CONFIG_BT_SCAN_WITH_IDENTITY=y
2121
- CONFIG_BT_SMP=y
2222
- CONFIG_BT_PRIVACY=y
23+
bluetooth.host.bt_id_set_scan_own_addr.scan_while_advertising:
24+
type: unit
25+
extra_configs:
26+
- CONFIG_BT_BROADCASTER=y

0 commit comments

Comments
 (0)