1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_address_manager.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/common/host_error.h"
18 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
19 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
20 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
21 #include "pw_bluetooth_sapphire/internal/host/testing/mock_controller.h"
22
23 namespace bt::gap {
24 namespace {
25
26 using testing::CommandTransaction;
27 using testing::MockController;
28
29 using TestingBase = testing::FakeDispatcherControllerTest<MockController>;
30
31 const DeviceAddress kPublic(DeviceAddress::Type::kLEPublic,
32 {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
33
34 class LowEnergyAddressManagerTest : public TestingBase {
35 public:
36 LowEnergyAddressManagerTest() = default;
37 ~LowEnergyAddressManagerTest() override = default;
38
39 protected:
SetUp()40 void SetUp() override {
41 TestingBase::SetUp();
42 addr_mgr_ = std::make_unique<LowEnergyAddressManager>(
43 kPublic,
44 [this] { return IsRandomAddressChangeAllowed(); },
45 cmd_channel()->AsWeakPtr(),
46 dispatcher());
47 ASSERT_EQ(kPublic, addr_mgr()->identity_address());
48 ASSERT_FALSE(addr_mgr()->irk());
49 addr_mgr_->register_address_changed_callback(
50 [&](auto) { address_changed_cb_count_++; });
51 }
52
TearDown()53 void TearDown() override {
54 addr_mgr_ = nullptr;
55 TestingBase::TearDown();
56 }
57
EnsureLocalAddress(std::optional<DeviceAddress::Type> address_type=std::nullopt,LowEnergyAddressManager::AddressCallback callback=nullptr)58 std::optional<DeviceAddress> EnsureLocalAddress(
59 std::optional<DeviceAddress::Type> address_type = std::nullopt,
60 LowEnergyAddressManager::AddressCallback callback = nullptr) {
61 std::optional<DeviceAddress> address = std::nullopt;
62 if (callback) {
63 addr_mgr()->EnsureLocalAddress(address_type, std::move(callback));
64 } else {
65 addr_mgr()->EnsureLocalAddress(
66 address_type,
67 [&](fit::result<HostError, const DeviceAddress> result) {
68 if (result.is_error()) {
69 return;
70 }
71
72 address = result.value();
73 });
74 }
75 RunUntilIdle();
76 return address;
77 }
78
79 // Called by |addr_mgr_|.
IsRandomAddressChangeAllowed() const80 bool IsRandomAddressChangeAllowed() const {
81 return random_address_change_allowed_;
82 }
83
addr_mgr() const84 LowEnergyAddressManager* addr_mgr() const { return addr_mgr_.get(); }
85
set_random_address_change_allowed(bool value)86 void set_random_address_change_allowed(bool value) {
87 random_address_change_allowed_ = value;
88 }
89
address_changed_cb_count() const90 size_t address_changed_cb_count() const { return address_changed_cb_count_; }
91
92 private:
93 std::unique_ptr<LowEnergyAddressManager> addr_mgr_;
94 bool random_address_change_allowed_ = true;
95 size_t address_changed_cb_count_ = 0;
96
97 BT_DISALLOW_COPY_ASSIGN_AND_MOVE(LowEnergyAddressManagerTest);
98 };
99
TEST_F(LowEnergyAddressManagerTest,DefaultState)100 TEST_F(LowEnergyAddressManagerTest, DefaultState) {
101 EXPECT_EQ(kPublic, EnsureLocalAddress());
102 }
103
TEST_F(LowEnergyAddressManagerTest,EnablePrivacy)104 TEST_F(LowEnergyAddressManagerTest, EnablePrivacy) {
105 // Respond with success.
106 const StaticByteBuffer kResponse(0x0E,
107 4, // Command Complete, 4 bytes,
108 1, // 1 allowed packet
109 0x05,
110 0x20, // opcode: HCI_LE_Set_Random_Address
111 0x00 // status: success
112 );
113 EXPECT_CMD_PACKET_OUT(
114 test_device(), hci_spec::kLESetRandomAddress, &kResponse);
115
116 const UInt128 kIrk{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
117 int hci_cmd_count = 0;
118 DeviceAddress addr;
119 test_device()->SetTransactionCallback([&](const auto& rx) {
120 hci_cmd_count++;
121
122 const auto addr_bytes = rx.view(sizeof(hci_spec::CommandHeader));
123 ASSERT_EQ(6u, addr_bytes.size());
124 addr = DeviceAddress(DeviceAddress::Type::kLERandom,
125 DeviceAddressBytes(addr_bytes));
126 });
127
128 addr_mgr()->set_irk(kIrk);
129 ASSERT_TRUE(addr_mgr()->irk());
130 EXPECT_EQ(kIrk, *addr_mgr()->irk());
131 EXPECT_FALSE(addr_mgr()->PrivacyEnabled());
132
133 addr_mgr()->EnablePrivacy(true);
134 // Privacy is now considered enabled.
135 // Even though Privacy is enabled, the LE address has not been changed so no
136 // notifications.
137 EXPECT_EQ(address_changed_cb_count(), 0u);
138 // Further requests to enable should not trigger additional HCI commands.
139 addr_mgr()->EnablePrivacy(true);
140 RunUntilIdle();
141
142 EXPECT_TRUE(addr_mgr()->PrivacyEnabled());
143 // We should have received a HCI command with a RPA resolvable using |kIrk|.
144 EXPECT_EQ(1, hci_cmd_count);
145 EXPECT_TRUE(addr.IsResolvablePrivate());
146 EXPECT_TRUE(sm::util::IrkCanResolveRpa(kIrk, addr));
147 // The new random address should be returned.
148 EXPECT_EQ(addr, EnsureLocalAddress());
149 // The address is updated so the listener should be notified.
150 EXPECT_EQ(address_changed_cb_count(), 1u);
151
152 // Assign a new IRK. The new address should be used when it gets refreshed.
153 // Re-enable privacy with a new IRK. The latest IRK should be used.
154 const UInt128 kIrk2{{15, 14, 14, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
155 addr_mgr()->set_irk(kIrk2);
156 ASSERT_TRUE(addr_mgr()->irk());
157 EXPECT_EQ(kIrk2, *addr_mgr()->irk());
158
159 // Returns the same address.
160 EXPECT_EQ(addr, EnsureLocalAddress());
161 EXPECT_FALSE(sm::util::IrkCanResolveRpa(kIrk2, addr));
162
163 // Re-enable privacy to trigger a refresh.
164 EXPECT_CMD_PACKET_OUT(
165 test_device(), hci_spec::kLESetRandomAddress, &kResponse);
166 addr_mgr()->EnablePrivacy(false);
167 // Disabling Privacy should result in the Public address being used so we
168 // expect a notification.
169 EXPECT_EQ(address_changed_cb_count(), 2u);
170 addr_mgr()->EnablePrivacy(true);
171 RunUntilIdle();
172
173 EXPECT_EQ(addr, EnsureLocalAddress());
174 EXPECT_TRUE(addr.IsResolvablePrivate());
175 EXPECT_TRUE(sm::util::IrkCanResolveRpa(kIrk2, addr));
176 EXPECT_EQ(address_changed_cb_count(), 3u);
177 }
178
TEST_F(LowEnergyAddressManagerTest,EnablePrivacyNoIrk)179 TEST_F(LowEnergyAddressManagerTest, EnablePrivacyNoIrk) {
180 // Respond with success.
181 const StaticByteBuffer kResponse(0x0E,
182 4, // Command Complete, 4 bytes,
183 1, // 1 allowed packet
184 0x05,
185 0x20, // opcode: HCI_LE_Set_Random_Address
186 0x00 // status: success
187 );
188 EXPECT_CMD_PACKET_OUT(
189 test_device(), hci_spec::kLESetRandomAddress, &kResponse);
190
191 int hci_cmd_count = 0;
192 DeviceAddress addr;
193 test_device()->SetTransactionCallback([&](const auto& rx) {
194 hci_cmd_count++;
195
196 const auto addr_bytes = rx.view(sizeof(hci_spec::CommandHeader));
197 ASSERT_EQ(6u, addr_bytes.size());
198 addr = DeviceAddress(DeviceAddress::Type::kLERandom,
199 DeviceAddressBytes(addr_bytes));
200 });
201
202 addr_mgr()->EnablePrivacy(true);
203
204 // Privacy is now considered enabled. Further requests to enable should not
205 // trigger additional HCI commands.
206 EXPECT_EQ(address_changed_cb_count(), 0u);
207 addr_mgr()->EnablePrivacy(true);
208 RunUntilIdle();
209
210 // We should have received a HCI command with a NRPA.
211 EXPECT_EQ(1, hci_cmd_count);
212 EXPECT_TRUE(addr.IsNonResolvablePrivate());
213
214 // The new random address should be returned.
215 EXPECT_EQ(addr, EnsureLocalAddress());
216 EXPECT_EQ(address_changed_cb_count(), 1u);
217 }
218
TEST_F(LowEnergyAddressManagerTest,EnablePrivacyHciError)219 TEST_F(LowEnergyAddressManagerTest, EnablePrivacyHciError) {
220 // Respond with error.
221 const StaticByteBuffer kErrorResponse(
222 0x0E,
223 4, // Command Complete, 4 bytes,
224 1, // 1 allowed packet
225 0x05,
226 0x20, // opcode: HCI_LE_Set_Random_Address
227 0x0C // status: Command Disallowed
228 );
229 // The second time respond with success.
230 const StaticByteBuffer kSuccessResponse(
231 0x0E,
232 4, // Command Complete, 4 bytes,
233 1, // 1 allowed packet
234 0x05,
235 0x20, // opcode: HCI_LE_Set_Random_Address
236 0x00 // status: success
237 );
238 EXPECT_CMD_PACKET_OUT(
239 test_device(), hci_spec::kLESetRandomAddress, &kErrorResponse);
240 EXPECT_CMD_PACKET_OUT(
241 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
242
243 addr_mgr()->EnablePrivacy(true);
244
245 // Request the new address and run the event loop. The old address should be
246 // returned due to the failure.
247 EXPECT_EQ(kPublic, EnsureLocalAddress());
248 // Address hasn't changed so no notifications.
249 EXPECT_EQ(address_changed_cb_count(), 0u);
250
251 // Requesting the address a second time while address update is disallowed
252 // should return the old address without sending HCI commands.
253 int hci_count = 0;
254 test_device()->SetTransactionCallback([&] { hci_count++; });
255 set_random_address_change_allowed(false);
256 EXPECT_EQ(kPublic, EnsureLocalAddress());
257 EXPECT_EQ(0, hci_count);
258 // Address hasn't changed so no notifications.
259 EXPECT_EQ(address_changed_cb_count(), 0u);
260
261 // Requesting the address a third time while address update is allowed should
262 // configure and return the new address.
263 set_random_address_change_allowed(true);
264 EXPECT_TRUE(EnsureLocalAddress()->IsNonResolvablePrivate());
265 EXPECT_EQ(1, hci_count);
266 EXPECT_EQ(address_changed_cb_count(), 1u);
267 }
268
TEST_F(LowEnergyAddressManagerTest,EnablePrivacyWhileAddressChangeIsDisallowed)269 TEST_F(LowEnergyAddressManagerTest,
270 EnablePrivacyWhileAddressChangeIsDisallowed) {
271 const auto kSuccessResponse =
272 StaticByteBuffer(0x0E,
273 4, // Command Complete, 4 bytes,
274 1, // 1 allowed packet
275 0x05,
276 0x20, // opcode: HCI_LE_Set_Random_Address
277 0x00 // status: success
278 );
279 EXPECT_CMD_PACKET_OUT(
280 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
281
282 int hci_count = 0;
283 test_device()->SetTransactionCallback([&] { hci_count++; });
284 set_random_address_change_allowed(false);
285
286 // No HCI commands should be sent while disallowed.
287 addr_mgr()->EnablePrivacy(true);
288 RunUntilIdle();
289 EXPECT_EQ(0, hci_count);
290
291 EXPECT_TRUE(addr_mgr()->PrivacyEnabled());
292 EXPECT_EQ(kPublic, EnsureLocalAddress());
293 EXPECT_EQ(0, hci_count);
294 // Address hasn't changed so no notifications.
295 EXPECT_EQ(address_changed_cb_count(), 0u);
296
297 // Requesting the address while address change is allowed should configure and
298 // return the new address.
299 set_random_address_change_allowed(true);
300 EXPECT_TRUE(EnsureLocalAddress()->IsNonResolvablePrivate());
301 EXPECT_EQ(1, hci_count);
302 // Address has changed.
303 EXPECT_EQ(address_changed_cb_count(), 1u);
304 }
305
TEST_F(LowEnergyAddressManagerTest,AddressExpiration)306 TEST_F(LowEnergyAddressManagerTest, AddressExpiration) {
307 const auto kSuccessResponse =
308 StaticByteBuffer(0x0E,
309 4, // Command Complete, 4 bytes,
310 1, // 1 allowed packet
311 0x05,
312 0x20, // opcode: HCI_LE_Set_Random_Address
313 0x00 // status: success
314 );
315 EXPECT_CMD_PACKET_OUT(
316 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
317 EXPECT_CMD_PACKET_OUT(
318 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
319
320 addr_mgr()->EnablePrivacy(true);
321 auto addr1 = EnsureLocalAddress();
322 EXPECT_TRUE(addr1->IsNonResolvablePrivate());
323 // Address has changed.
324 EXPECT_EQ(address_changed_cb_count(), 1u);
325
326 // Requesting the address again should keep returning the same address without
327 // sending any HCI commands.
328 int hci_count = 0;
329 test_device()->SetTransactionCallback([&] { hci_count++; });
330 EXPECT_EQ(addr1, EnsureLocalAddress());
331 EXPECT_EQ(addr1, EnsureLocalAddress());
332 EXPECT_EQ(addr1, EnsureLocalAddress());
333 EXPECT_EQ(addr1, EnsureLocalAddress());
334 EXPECT_EQ(addr1, EnsureLocalAddress());
335 EXPECT_EQ(0, hci_count);
336 // Address hasn't changed so no notifications.
337 EXPECT_EQ(address_changed_cb_count(), 1u);
338
339 // A new address should be generated and configured after the random address
340 // interval.
341 RunFor(kPrivateAddressTimeout);
342 EXPECT_EQ(1, hci_count);
343 // Address has changed due to timeout.
344 EXPECT_EQ(address_changed_cb_count(), 2u);
345
346 // Requesting the address again should return the new address.
347 auto addr2 = EnsureLocalAddress();
348 EXPECT_TRUE(addr2->IsNonResolvablePrivate());
349 EXPECT_NE(addr1, addr2);
350 EXPECT_EQ(1, hci_count);
351 // The new address was already reported after timeout so no other
352 // notification.
353 EXPECT_EQ(address_changed_cb_count(), 2u);
354 }
355
TEST_F(LowEnergyAddressManagerTest,AddressExpirationWhileAddressChangeIsDisallowed)356 TEST_F(LowEnergyAddressManagerTest,
357 AddressExpirationWhileAddressChangeIsDisallowed) {
358 const auto kSuccessResponse =
359 StaticByteBuffer(0x0E,
360 4, // Command Complete, 4 bytes,
361 1, // 1 allowed packet
362 0x05,
363 0x20, // opcode: HCI_LE_Set_Random_Address
364 0x00 // status: success
365 );
366 EXPECT_CMD_PACKET_OUT(
367 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
368 EXPECT_CMD_PACKET_OUT(
369 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
370
371 addr_mgr()->EnablePrivacy(true);
372 auto addr1 = EnsureLocalAddress();
373 EXPECT_TRUE(addr1->IsNonResolvablePrivate());
374
375 // Requesting the address again should keep returning the same address without
376 // sending any HCI commands.
377 int hci_count = 0;
378 test_device()->SetTransactionCallback([&] { hci_count++; });
379 EXPECT_EQ(addr1, EnsureLocalAddress());
380 EXPECT_EQ(addr1, EnsureLocalAddress());
381 EXPECT_EQ(addr1, EnsureLocalAddress());
382 EXPECT_EQ(addr1, EnsureLocalAddress());
383 EXPECT_EQ(addr1, EnsureLocalAddress());
384 EXPECT_EQ(0, hci_count);
385
386 // After the interval ends, the address should be marked as expired but should
387 // not send an HCI command while the command is disallowed.
388 set_random_address_change_allowed(false);
389 RunFor(kPrivateAddressTimeout);
390 EXPECT_EQ(addr1, EnsureLocalAddress());
391 EXPECT_EQ(0, hci_count);
392
393 // Requesting the address again while the command is allowed should configure
394 // and return the new address.
395 set_random_address_change_allowed(true);
396 auto addr2 = EnsureLocalAddress();
397 EXPECT_TRUE(addr2->IsNonResolvablePrivate());
398 EXPECT_NE(addr1, addr2);
399 EXPECT_EQ(1, hci_count);
400 }
401
TEST_F(LowEnergyAddressManagerTest,DisablePrivacy)402 TEST_F(LowEnergyAddressManagerTest, DisablePrivacy) {
403 // Enable privacy.
404 const auto kSuccessResponse =
405 StaticByteBuffer(0x0E,
406 4, // Command Complete, 4 bytes,
407 1, // 1 allowed packet
408 0x05,
409 0x20, // opcode: HCI_LE_Set_Random_Address
410 0x00 // status: success
411 );
412 EXPECT_CMD_PACKET_OUT(
413 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
414
415 addr_mgr()->EnablePrivacy(true);
416 EXPECT_TRUE(EnsureLocalAddress()->IsNonResolvablePrivate());
417 // Address has changed to an NRPA.
418 EXPECT_EQ(address_changed_cb_count(), 1u);
419
420 // Disable privacy.
421 addr_mgr()->EnablePrivacy(false);
422
423 // The public address should be returned for the local address.
424 EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress()->type());
425 // Address has change to public since Privacy is disabled.
426 EXPECT_EQ(address_changed_cb_count(), 2u);
427
428 // No HCI commands should get sent after private address interval expires.
429 int hci_count = 0;
430 test_device()->SetTransactionCallback([&] { hci_count++; });
431 RunFor(kPrivateAddressTimeout);
432 EXPECT_EQ(0, hci_count);
433 EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress()->type());
434 }
435
TEST_F(LowEnergyAddressManagerTest,DisablePrivacyDuringAddressChange)436 TEST_F(LowEnergyAddressManagerTest, DisablePrivacyDuringAddressChange) {
437 const auto kSuccessResponse =
438 StaticByteBuffer(0x0E,
439 4, // Command Complete, 4 bytes,
440 1, // 1 allowed packet
441 0x05,
442 0x20, // opcode: HCI_LE_Set_Random_Address
443 0x00 // status: success
444 );
445 EXPECT_CMD_PACKET_OUT(
446 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
447
448 int hci_count = 0;
449 test_device()->SetTransactionCallback([&] { hci_count++; });
450
451 // Enable and disable in quick succession. HCI command should be sent but the
452 // local address shouldn't take effect.
453 addr_mgr()->EnablePrivacy(true);
454 addr_mgr()->EnablePrivacy(false);
455 EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress()->type());
456 EXPECT_EQ(1, hci_count);
457
458 // No HCI commands should get sent after private address interval expires.
459 RunFor(kPrivateAddressTimeout);
460 EXPECT_EQ(1, hci_count);
461 EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress()->type());
462 }
463
TEST_F(LowEnergyAddressManagerTest,MultipleAddressChangedCallbacksAreNotified)464 TEST_F(LowEnergyAddressManagerTest,
465 MultipleAddressChangedCallbacksAreNotified) {
466 // The |LowEnergyAddressManagerTest| registers an address changed callback on
467 // construction. Register another.
468 size_t cb_count2 = 0;
469 addr_mgr()->register_address_changed_callback([&](auto) { cb_count2++; });
470
471 // Enable privacy.
472 const auto kSuccessResponse =
473 StaticByteBuffer(0x0E,
474 4, // Command Complete, 4 bytes,
475 1, // 1 allowed packet
476 0x05,
477 0x20, // opcode: HCI_LE_Set_Random_Address
478 0x00 // status: success
479 );
480 EXPECT_CMD_PACKET_OUT(
481 test_device(), hci_spec::kLESetRandomAddress, &kSuccessResponse);
482
483 addr_mgr()->EnablePrivacy(true);
484 EXPECT_TRUE(EnsureLocalAddress()->IsNonResolvablePrivate());
485 // Address has changed to an NRPA. Both callbacks should be notified.
486 EXPECT_EQ(address_changed_cb_count(), 1u);
487 EXPECT_EQ(cb_count2, 1u);
488
489 // Before privacy is disabled, another callback is registered.
490 size_t cb_count3 = 0;
491 addr_mgr()->register_address_changed_callback([&](auto) { cb_count3++; });
492 EXPECT_EQ(cb_count3, 0u);
493
494 // Disable privacy.
495 addr_mgr()->EnablePrivacy(false);
496
497 // The public address should be returned for the local address.
498 EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress()->type());
499 // Address has changed - all callbacks should be notified.
500 EXPECT_EQ(address_changed_cb_count(), 2u);
501 EXPECT_EQ(cb_count2, 2u);
502 EXPECT_EQ(cb_count3, 1u);
503 }
504
TEST_F(LowEnergyAddressManagerTest,EnsureLocalAddressRandomAddressWithoutPrivacyEnabledFails)505 TEST_F(LowEnergyAddressManagerTest,
506 EnsureLocalAddressRandomAddressWithoutPrivacyEnabledFails) {
507 EXPECT_FALSE(addr_mgr()->PrivacyEnabled());
508
509 std::optional<HostError> res;
510 auto cb = [&](fit::result<HostError, const DeviceAddress> result) {
511 if (result.is_error()) {
512 res = result.error_value();
513 }
514 };
515
516 // Explicitly requesting a random address type while privacy is disabled will
517 // result in an error.
518 std::optional<DeviceAddress> local_address =
519 EnsureLocalAddress(DeviceAddress::Type::kLERandom, std::move(cb));
520 EXPECT_FALSE(local_address.has_value());
521 EXPECT_EQ(HostError::kInvalidParameters, res.value());
522
523 // Address hasn't changed so no notifications.
524 EXPECT_EQ(address_changed_cb_count(), 0u);
525 }
526
TEST_F(LowEnergyAddressManagerTest,EnsureLocalAddressReturnsPublic)527 TEST_F(LowEnergyAddressManagerTest, EnsureLocalAddressReturnsPublic) {
528 EXPECT_FALSE(addr_mgr()->PrivacyEnabled());
529
530 // The public address should be returned for the local address by default when
531 // privacy is disabled.
532 EXPECT_EQ(DeviceAddress::Type::kLEPublic, EnsureLocalAddress()->type());
533
534 // Successfully enable privacy.
535 const StaticByteBuffer kResponse(0x0E,
536 4, // Command Complete, 4 bytes,
537 1, // 1 allowed packet
538 0x05,
539 0x20, // opcode: HCI_LE_Set_Random_Address
540 0x00 // status: success
541 );
542 EXPECT_CMD_PACKET_OUT(
543 test_device(), hci_spec::kLESetRandomAddress, &kResponse);
544 addr_mgr()->EnablePrivacy(true);
545 RunUntilIdle();
546 EXPECT_EQ(address_changed_cb_count(), 1u);
547
548 // The public address should be returned for the local address when explicitly
549 // requesting the public address type, even if privacy is enabled.
550 EXPECT_EQ(DeviceAddress::Type::kLEPublic,
551 EnsureLocalAddress(DeviceAddress::Type::kLEPublic)->type());
552 }
553
554 } // namespace
555 } // namespace bt::gap
556