Skip to content

Commit b0ab105

Browse files
olivier-le-sagerlubos
authored andcommitted
[nrf fromtree] 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 <[email protected]> (cherry picked from commit 43223a1)
1 parent 964736d commit b0ab105

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
@@ -1965,7 +1965,7 @@ int bt_id_set_create_conn_own_addr(bool use_filter, uint8_t *own_addr_type)
19651965
#endif /* defined(CONFIG_BT_CENTRAL) */
19661966

19671967
#if defined(CONFIG_BT_OBSERVER)
1968-
static bool is_adv_using_rand_addr(void)
1968+
static bool is_legacy_adv_enabled(void)
19691969
{
19701970
struct bt_le_ext_adv *adv;
19711971

@@ -1981,7 +1981,27 @@ static bool is_adv_using_rand_addr(void)
19811981

19821982
adv = bt_le_adv_lookup_legacy();
19831983

1984-
return adv && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
1984+
return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED);
1985+
}
1986+
1987+
static bool is_legacy_adv_using_id_addr(void)
1988+
{
1989+
struct bt_le_ext_adv *adv;
1990+
1991+
if (!IS_ENABLED(CONFIG_BT_BROADCASTER) ||
1992+
(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
1993+
BT_DEV_FEAT_LE_EXT_ADV(bt_dev.le.features))) {
1994+
/* When advertising is not enabled or is using extended
1995+
* advertising HCI commands then only the scanner uses the set
1996+
* random address command.
1997+
*/
1998+
return false;
1999+
}
2000+
2001+
adv = bt_le_adv_lookup_legacy();
2002+
2003+
return adv != NULL && atomic_test_bit(adv->flags, BT_ADV_ENABLED)
2004+
&& atomic_test_bit(adv->flags, BT_ADV_USE_IDENTITY);
19852005
}
19862006

19872007
int bt_id_set_scan_own_addr(bool active_scan, uint8_t *own_addr_type)
@@ -2014,20 +2034,30 @@ int bt_id_set_scan_own_addr(bool active_scan, uint8_t *own_addr_type)
20142034
* (through Kconfig).
20152035
* Use same RPA as legacy advertiser if advertising.
20162036
*/
2017-
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
2018-
!is_adv_using_rand_addr()) {
2019-
err = bt_id_set_private_addr(BT_ID_DEFAULT);
2020-
if (err) {
2021-
if (active_scan || !is_adv_using_rand_addr()) {
2037+
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
2038+
/* When using legacy advertising commands, the scanner and advertiser
2039+
* share the same address, so we cannot change it.
2040+
* When using extended advertising commands, however, the advertising
2041+
* sets have their own addresses, so we can always change the scanner
2042+
* address here.
2043+
*/
2044+
if (is_legacy_adv_using_id_addr()) {
2045+
if (bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
2046+
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
2047+
} else {
2048+
*own_addr_type = BT_HCI_OWN_ADDR_PUBLIC;
2049+
}
2050+
} else if (is_legacy_adv_enabled()) {
2051+
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
2052+
} else {
2053+
err = bt_id_set_private_addr(BT_ID_DEFAULT);
2054+
if (err) {
20222055
return err;
20232056
}
20242057

2025-
LOG_WRN("Ignoring failure to set address for passive scan (%d)",
2026-
err);
2058+
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
20272059
}
2028-
2029-
*own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
2030-
} else if (IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY)) {
2060+
} else {
20312061
if (bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_RANDOM) {
20322062
/* If scanning with Identity Address we must set the
20332063
* 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)