• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/hci/low_energy_connector.h"
16 
17 #include <vector>
18 
19 #include "pw_async/heap_dispatcher.h"
20 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
21 #include "pw_bluetooth_sapphire/internal/host/hci-spec/defaults.h"
22 #include "pw_bluetooth_sapphire/internal/host/hci/fake_local_address_delegate.h"
23 #include "pw_bluetooth_sapphire/internal/host/hci/fake_low_energy_connection.h"
24 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
25 #include "pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
26 #include "pw_bluetooth_sapphire/internal/host/testing/fake_peer.h"
27 
28 namespace bt::hci {
29 namespace {
30 
31 using bt::testing::FakeController;
32 using bt::testing::FakePeer;
33 using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
34 
35 const DeviceAddress kLocalAddress(DeviceAddress::Type::kLEPublic, {0xFF});
36 const DeviceAddress kRandomAddress(DeviceAddress::Type::kLERandom, {0xFE});
37 const DeviceAddress kTestAddress(DeviceAddress::Type::kLEPublic, {1});
38 const hci_spec::LEPreferredConnectionParameters kTestParams(6, 6, 1, 10);
39 constexpr pw::chrono::SystemClock::duration kConnectTimeout =
40     std::chrono::seconds(10);
41 constexpr pw::chrono::SystemClock::duration kPwConnectTimeout =
42     std::chrono::seconds(10);
43 
44 class LowEnergyConnectorTest : public TestingBase {
45  public:
46   LowEnergyConnectorTest() = default;
47   ~LowEnergyConnectorTest() override = default;
48 
49  protected:
50   // TestingBase overrides:
SetUp()51   void SetUp() override {
52     TestingBase::SetUp();
53     InitializeACLDataChannel();
54 
55     FakeController::Settings settings;
56     settings.ApplyLegacyLEConfig();
57     test_device()->set_settings(settings);
58 
59     fake_address_delegate_.set_local_address(kLocalAddress);
60     connector_ = std::make_unique<LowEnergyConnector>(
61         transport()->GetWeakPtr(),
62         &fake_address_delegate_,
63         dispatcher(),
64         fit::bind_member<&LowEnergyConnectorTest::OnIncomingConnectionCreated>(
65             this));
66 
67     test_device()->set_connection_state_callback(
68         fit::bind_member<&LowEnergyConnectorTest::OnConnectionStateChanged>(
69             this));
70   }
71 
TearDown()72   void TearDown() override {
73     connector_ = nullptr;
74     in_connections_.clear();
75     test_device()->Stop();
76     TestingBase::TearDown();
77   }
78 
heap_dispatcher()79   pw::async::HeapDispatcher& heap_dispatcher() { return heap_dispatcher_; }
80 
DeleteConnector()81   void DeleteConnector() { connector_ = nullptr; }
82 
83   bool request_canceled = false;
84 
in_connections() const85   const std::vector<std::unique_ptr<LowEnergyConnection>>& in_connections()
86       const {
87     return in_connections_;
88   }
connector() const89   LowEnergyConnector* connector() const { return connector_.get(); }
fake_address_delegate()90   FakeLocalAddressDelegate* fake_address_delegate() {
91     return &fake_address_delegate_;
92   }
93 
94  private:
OnIncomingConnectionCreated(hci_spec::ConnectionHandle handle,pw::bluetooth::emboss::ConnectionRole role,const DeviceAddress & peer_address,const hci_spec::LEConnectionParameters & conn_params)95   void OnIncomingConnectionCreated(
96       hci_spec::ConnectionHandle handle,
97       pw::bluetooth::emboss::ConnectionRole role,
98       const DeviceAddress& peer_address,
99       const hci_spec::LEConnectionParameters& conn_params) {
100     in_connections_.push_back(
101         std::make_unique<testing::FakeLowEnergyConnection>(
102             handle,
103             kLocalAddress,
104             peer_address,
105             role,
106             transport()->GetWeakPtr()));
107   }
108 
OnConnectionStateChanged(const DeviceAddress & address,hci_spec::ConnectionHandle handle,bool connected,bool canceled)109   void OnConnectionStateChanged(const DeviceAddress& address,
110                                 hci_spec::ConnectionHandle handle,
111                                 bool connected,
112                                 bool canceled) {
113     request_canceled = canceled;
114   }
115 
116   FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
117   std::unique_ptr<LowEnergyConnector> connector_;
118 
119   // Incoming connections.
120   std::vector<std::unique_ptr<LowEnergyConnection>> in_connections_;
121   pw::async::HeapDispatcher heap_dispatcher_{dispatcher()};
122 
123   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyConnectorTest);
124 };
125 
126 using HCI_LowEnergyConnectorTest = LowEnergyConnectorTest;
127 
TEST_F(LowEnergyConnectorTest,CreateConnection)128 TEST_F(LowEnergyConnectorTest, CreateConnection) {
129   auto fake_peer =
130       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
131   test_device()->AddPeer(std::move(fake_peer));
132 
133   EXPECT_FALSE(connector()->request_pending());
134   EXPECT_FALSE(connector()->pending_peer_address());
135 
136   Result<> status = fit::ok();
137   std::unique_ptr<LowEnergyConnection> conn;
138   bool callback_called = false;
139 
140   auto callback = [&](auto cb_status, auto cb_conn) {
141     status = cb_status;
142     conn = std::move(cb_conn);
143     callback_called = true;
144   };
145 
146   bool ret = connector()->CreateConnection(
147       /*use_accept_list=*/false,
148       kTestAddress,
149       hci_spec::defaults::kLEScanInterval,
150       hci_spec::defaults::kLEScanWindow,
151       kTestParams,
152       callback,
153       kPwConnectTimeout);
154   EXPECT_TRUE(ret);
155   EXPECT_TRUE(connector()->request_pending());
156   EXPECT_EQ(connector()->pending_peer_address().value(), kTestAddress);
157 
158   ret = connector()->CreateConnection(
159       /*use_accept_list=*/false,
160       kTestAddress,
161       hci_spec::defaults::kLEScanInterval,
162       hci_spec::defaults::kLEScanWindow,
163       kTestParams,
164       callback,
165       kPwConnectTimeout);
166   EXPECT_FALSE(ret);
167 
168   RunUntilIdle();
169 
170   EXPECT_FALSE(connector()->request_pending());
171   EXPECT_FALSE(connector()->pending_peer_address());
172   EXPECT_TRUE(callback_called);
173   EXPECT_EQ(fit::ok(), status);
174   EXPECT_TRUE(in_connections().empty());
175 
176   ASSERT_TRUE(conn);
177   EXPECT_EQ(1u, conn->handle());
178   EXPECT_EQ(kLocalAddress, conn->local_address());
179   EXPECT_EQ(kTestAddress, conn->peer_address());
180   conn->Disconnect(
181       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
182 }
183 
184 // Controller reports error from HCI Command Status event.
TEST_F(LowEnergyConnectorTest,CreateConnectionStatusError)185 TEST_F(LowEnergyConnectorTest, CreateConnectionStatusError) {
186   auto fake_peer =
187       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
188   fake_peer->set_connect_status(
189       pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED);
190   test_device()->AddPeer(std::move(fake_peer));
191 
192   EXPECT_FALSE(connector()->request_pending());
193 
194   Result<> status = fit::ok();
195   std::unique_ptr<LowEnergyConnection> conn;
196   bool callback_called = false;
197 
198   auto callback = [&](auto cb_status, auto cb_conn) {
199     status = cb_status;
200     conn = std::move(cb_conn);
201     callback_called = true;
202   };
203 
204   bool ret = connector()->CreateConnection(
205       /*use_accept_list=*/false,
206       kTestAddress,
207       hci_spec::defaults::kLEScanInterval,
208       hci_spec::defaults::kLEScanWindow,
209       kTestParams,
210       callback,
211       kPwConnectTimeout);
212   EXPECT_TRUE(ret);
213   EXPECT_TRUE(connector()->request_pending());
214 
215   RunUntilIdle();
216 
217   EXPECT_FALSE(connector()->request_pending());
218   EXPECT_TRUE(callback_called);
219   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED),
220             status);
221   EXPECT_FALSE(conn);
222   EXPECT_TRUE(in_connections().empty());
223 }
224 
225 // Controller reports error from HCI LE Connection Complete event
TEST_F(LowEnergyConnectorTest,CreateConnectionEventError)226 TEST_F(LowEnergyConnectorTest, CreateConnectionEventError) {
227   auto fake_peer =
228       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
229   fake_peer->set_connect_response(
230       pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_SECURITY);
231   test_device()->AddPeer(std::move(fake_peer));
232 
233   EXPECT_FALSE(connector()->request_pending());
234 
235   Result<> status = fit::ok();
236   std::unique_ptr<LowEnergyConnection> conn;
237   bool callback_called = false;
238 
239   auto callback = [&](auto cb_status, auto cb_conn) {
240     status = cb_status;
241     callback_called = true;
242     conn = std::move(cb_conn);
243   };
244 
245   bool ret = connector()->CreateConnection(
246       /*use_accept_list=*/false,
247       kTestAddress,
248       hci_spec::defaults::kLEScanInterval,
249       hci_spec::defaults::kLEScanWindow,
250       kTestParams,
251       callback,
252       kPwConnectTimeout);
253   EXPECT_TRUE(ret);
254   EXPECT_TRUE(connector()->request_pending());
255 
256   RunUntilIdle();
257 
258   EXPECT_FALSE(connector()->request_pending());
259   EXPECT_TRUE(callback_called);
260   EXPECT_EQ(
261       ToResult(pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_SECURITY),
262       status);
263   EXPECT_TRUE(in_connections().empty());
264   EXPECT_FALSE(conn);
265 }
266 
267 // Controller reports error from HCI LE Connection Complete event
TEST_F(LowEnergyConnectorTest,Cancel)268 TEST_F(LowEnergyConnectorTest, Cancel) {
269   auto fake_peer =
270       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
271 
272   // Make sure the pending connect remains pending.
273   fake_peer->set_force_pending_connect(true);
274   test_device()->AddPeer(std::move(fake_peer));
275 
276   hci::Result<> status = fit::ok();
277   std::unique_ptr<LowEnergyConnection> conn;
278   bool callback_called = false;
279 
280   auto callback = [&](auto cb_status, auto cb_conn) {
281     status = cb_status;
282     callback_called = true;
283     conn = std::move(cb_conn);
284   };
285 
286   bool ret = connector()->CreateConnection(
287       /*use_accept_list=*/false,
288       kTestAddress,
289       hci_spec::defaults::kLEScanInterval,
290       hci_spec::defaults::kLEScanWindow,
291       kTestParams,
292       callback,
293       kPwConnectTimeout);
294   EXPECT_TRUE(ret);
295   EXPECT_TRUE(connector()->request_pending());
296 
297   ASSERT_FALSE(request_canceled);
298 
299   connector()->Cancel();
300   EXPECT_TRUE(connector()->request_pending());
301 
302   // The request timeout should be canceled regardless of whether it was posted
303   // before.
304   EXPECT_FALSE(connector()->timeout_posted());
305 
306   RunUntilIdle();
307 
308   EXPECT_FALSE(connector()->timeout_posted());
309   EXPECT_FALSE(connector()->request_pending());
310   EXPECT_TRUE(callback_called);
311   EXPECT_TRUE(request_canceled);
312   EXPECT_EQ(ToResult(HostError::kCanceled), status);
313   EXPECT_TRUE(in_connections().empty());
314   EXPECT_FALSE(conn);
315 }
316 
TEST_F(LowEnergyConnectorTest,IncomingConnect)317 TEST_F(LowEnergyConnectorTest, IncomingConnect) {
318   EXPECT_TRUE(in_connections().empty());
319   EXPECT_FALSE(connector()->request_pending());
320 
321   auto packet = hci::EmbossEventPacket::New<
322       pw::bluetooth::emboss::LEConnectionCompleteSubeventWriter>(
323       hci_spec::kLEMetaEventCode);
324   auto view = packet.view_t();
325 
326   view.le_meta_event().subevent_code().Write(
327       hci_spec::kLEConnectionCompleteSubeventCode);
328   view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
329   view.peer_address().CopyFrom(kTestAddress.value().view());
330   view.peer_address_type().Write(
331       pw::bluetooth::emboss::LEPeerAddressType::PUBLIC);
332   view.connection_interval().Write(
333       hci_spec::defaults::kLEConnectionIntervalMin);
334   view.connection_handle().Write(1);
335 
336   test_device()->SendCommandChannelPacket(packet.data());
337 
338   RunUntilIdle();
339 
340   ASSERT_EQ(1u, in_connections().size());
341 
342   auto conn = in_connections()[0].get();
343   EXPECT_EQ(1u, conn->handle());
344   EXPECT_EQ(kLocalAddress, conn->local_address());
345   EXPECT_EQ(kTestAddress, conn->peer_address());
346   conn->Disconnect(
347       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
348 }
349 
TEST_F(LowEnergyConnectorTest,IncomingConnectDuringConnectionRequest)350 TEST_F(LowEnergyConnectorTest, IncomingConnectDuringConnectionRequest) {
351   const DeviceAddress kIncomingAddress(DeviceAddress::Type::kLEPublic, {2});
352 
353   EXPECT_TRUE(in_connections().empty());
354   EXPECT_FALSE(connector()->request_pending());
355 
356   auto fake_peer =
357       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
358   test_device()->AddPeer(std::move(fake_peer));
359 
360   Result<> status = fit::ok();
361   std::unique_ptr<LowEnergyConnection> conn;
362   unsigned int callback_count = 0;
363 
364   auto callback = [&](auto cb_status, auto cb_conn) {
365     status = cb_status;
366     callback_count++;
367     conn = std::move(cb_conn);
368   };
369 
370   connector()->CreateConnection(
371       /*use_accept_list=*/false,
372       kTestAddress,
373       hci_spec::defaults::kLEScanInterval,
374       hci_spec::defaults::kLEScanWindow,
375       kTestParams,
376       callback,
377       kPwConnectTimeout);
378 
379   (void)heap_dispatcher().Post(
380       [kIncomingAddress, this](pw::async::Context /*ctx*/, pw::Status status) {
381         if (!status.ok()) {
382           return;
383         }
384 
385         auto packet = hci::EmbossEventPacket::New<
386             pw::bluetooth::emboss::LEConnectionCompleteSubeventWriter>(
387             hci_spec::kLEMetaEventCode);
388         auto view = packet.view_t();
389 
390         view.le_meta_event().subevent_code().Write(
391             hci_spec::kLEConnectionCompleteSubeventCode);
392         view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
393         view.peer_address().CopyFrom(kIncomingAddress.value().view());
394         view.peer_address_type().Write(
395             pw::bluetooth::emboss::LEPeerAddressType::PUBLIC);
396         view.connection_interval().Write(
397             hci_spec::defaults::kLEConnectionIntervalMin);
398         view.connection_handle().Write(2);
399 
400         test_device()->SendCommandChannelPacket(packet.data());
401       });
402 
403   RunUntilIdle();
404 
405   EXPECT_EQ(fit::ok(), status);
406   EXPECT_EQ(1u, callback_count);
407   ASSERT_EQ(1u, in_connections().size());
408 
409   const auto& in_conn = in_connections().front();
410 
411   EXPECT_EQ(1u, conn->handle());
412   EXPECT_EQ(2u, in_conn->handle());
413   EXPECT_EQ(kTestAddress, conn->peer_address());
414   EXPECT_EQ(kIncomingAddress, in_conn->peer_address());
415 
416   conn->Disconnect(
417       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
418   in_conn->Disconnect(
419       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
420 }
421 
TEST_F(LowEnergyConnectorTest,CreateConnectionTimeout)422 TEST_F(LowEnergyConnectorTest, CreateConnectionTimeout) {
423   // We do not set up any fake devices. This will cause the request to time out.
424   EXPECT_FALSE(connector()->request_pending());
425 
426   Result<> status = fit::ok();
427   std::unique_ptr<LowEnergyConnection> conn;
428   bool callback_called = false;
429 
430   auto callback = [&](auto cb_status, auto cb_conn) {
431     status = cb_status;
432     callback_called = true;
433     conn = std::move(cb_conn);
434   };
435 
436   connector()->CreateConnection(
437       /*use_accept_list=*/false,
438       kTestAddress,
439       hci_spec::defaults::kLEScanInterval,
440       hci_spec::defaults::kLEScanWindow,
441       kTestParams,
442       callback,
443       kPwConnectTimeout);
444   EXPECT_TRUE(connector()->request_pending());
445 
446   EXPECT_FALSE(request_canceled);
447 
448   // Make the connection attempt time out.
449   RunFor(kConnectTimeout);
450 
451   EXPECT_FALSE(connector()->request_pending());
452   EXPECT_TRUE(callback_called);
453   EXPECT_TRUE(request_canceled);
454   EXPECT_EQ(ToResult(HostError::kTimedOut), status);
455   EXPECT_TRUE(in_connections().empty());
456   EXPECT_FALSE(conn);
457 }
458 
TEST_F(LowEnergyConnectorTest,SendRequestAndDelete)459 TEST_F(LowEnergyConnectorTest, SendRequestAndDelete) {
460   auto fake_peer =
461       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
462 
463   // Make sure the pending connect remains pending.
464   fake_peer->set_force_pending_connect(true);
465   test_device()->AddPeer(std::move(fake_peer));
466 
467   bool ret = connector()->CreateConnection(
468       /*use_accept_list=*/
469       false,
470       kTestAddress,
471       hci_spec::defaults::kLEScanInterval,
472       hci_spec::defaults::kLEScanWindow,
473       kTestParams,
474       [](auto, auto) {},
475       kPwConnectTimeout);
476   EXPECT_TRUE(ret);
477   EXPECT_TRUE(connector()->request_pending());
478 
479   DeleteConnector();
480   RunUntilIdle();
481 
482   EXPECT_TRUE(request_canceled);
483   EXPECT_TRUE(in_connections().empty());
484 }
485 
TEST_F(LowEnergyConnectorTest,AllowsRandomAddressChange)486 TEST_F(LowEnergyConnectorTest, AllowsRandomAddressChange) {
487   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
488 
489   auto fake_device =
490       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
491   test_device()->AddPeer(std::move(fake_device));
492 
493   // Address change should not be allowed while the procedure is pending.
494   connector()->CreateConnection(
495       /*use_accept_list=*/
496       false,
497       kTestAddress,
498       hci_spec::defaults::kLEScanInterval,
499       hci_spec::defaults::kLEScanWindow,
500       kTestParams,
501       [](auto, auto) {},
502       kPwConnectTimeout);
503   EXPECT_TRUE(connector()->request_pending());
504   EXPECT_FALSE(connector()->AllowsRandomAddressChange());
505 
506   RunUntilIdle();
507   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
508 }
509 
TEST_F(LowEnergyConnectorTest,AllowsRandomAddressChangeWhileRequestingLocalAddress)510 TEST_F(LowEnergyConnectorTest,
511        AllowsRandomAddressChangeWhileRequestingLocalAddress) {
512   // Make the local address delegate report its result asynchronously.
513   fake_address_delegate()->set_async(true);
514 
515   // The connector should be in the "request pending" state without initiating
516   // controller procedures that would prevent a local address change.
517   connector()->CreateConnection(
518       /*use_accept_list=*/
519       false,
520       kTestAddress,
521       hci_spec::defaults::kLEScanInterval,
522       hci_spec::defaults::kLEScanWindow,
523       kTestParams,
524       [](auto, auto) {},
525       kPwConnectTimeout);
526   EXPECT_TRUE(connector()->request_pending());
527   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
528 
529   // Initiating a new connection should fail in this state.
530   bool result = connector()->CreateConnection(
531       /*use_accept_list=*/
532       false,
533       kTestAddress,
534       hci_spec::defaults::kLEScanInterval,
535       hci_spec::defaults::kLEScanWindow,
536       kTestParams,
537       [](auto, auto) {},
538       kPwConnectTimeout);
539   EXPECT_FALSE(result);
540 
541   // After the loop runs the request should remain pending (since we added no
542   // fake device, the request would eventually timeout) but address change
543   // should no longer be allowed.
544   RunUntilIdle();
545   EXPECT_TRUE(connector()->request_pending());
546   EXPECT_FALSE(connector()->AllowsRandomAddressChange());
547 }
548 
TEST_F(LowEnergyConnectorTest,ConnectUsingPublicAddress)549 TEST_F(LowEnergyConnectorTest, ConnectUsingPublicAddress) {
550   auto fake_device =
551       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
552   test_device()->AddPeer(std::move(fake_device));
553   connector()->CreateConnection(
554       /*use_accept_list=*/
555       false,
556       kTestAddress,
557       hci_spec::defaults::kLEScanInterval,
558       hci_spec::defaults::kLEScanWindow,
559       kTestParams,
560       [](auto, auto) {},
561       kPwConnectTimeout);
562   RunUntilIdle();
563   ASSERT_TRUE(test_device()->le_connect_params());
564   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
565             test_device()->le_connect_params()->own_address_type);
566 }
567 
TEST_F(LowEnergyConnectorTest,ConnectUsingRandomAddress)568 TEST_F(LowEnergyConnectorTest, ConnectUsingRandomAddress) {
569   fake_address_delegate()->set_local_address(kRandomAddress);
570 
571   auto fake_device =
572       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
573   test_device()->AddPeer(std::move(fake_device));
574   connector()->CreateConnection(
575       /*use_accept_list=*/
576       false,
577       kTestAddress,
578       hci_spec::defaults::kLEScanInterval,
579       hci_spec::defaults::kLEScanWindow,
580       kTestParams,
581       [](auto, auto) {},
582       kPwConnectTimeout);
583   RunUntilIdle();
584   ASSERT_TRUE(test_device()->le_connect_params());
585   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
586             test_device()->le_connect_params()->own_address_type);
587 }
588 
TEST_F(LowEnergyConnectorTest,CancelConnectWhileWaitingForLocalAddress)589 TEST_F(LowEnergyConnectorTest, CancelConnectWhileWaitingForLocalAddress) {
590   Result<> status = fit::ok();
591   std::unique_ptr<LowEnergyConnection> conn;
592   auto callback = [&](auto s, auto c) {
593     status = s;
594     conn = std::move(c);
595   };
596   fake_address_delegate()->set_async(true);
597   connector()->CreateConnection(
598       /*use_accept_list=*/false,
599       kTestAddress,
600       hci_spec::defaults::kLEScanInterval,
601       hci_spec::defaults::kLEScanWindow,
602       kTestParams,
603       std::move(callback),
604       kPwConnectTimeout);
605 
606   // Should be waiting for the address.
607   EXPECT_TRUE(connector()->request_pending());
608   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
609 
610   connector()->Cancel();
611   RunUntilIdle();
612   EXPECT_FALSE(connector()->request_pending());
613   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
614 
615   // The controller should have received no command from us.
616   EXPECT_FALSE(test_device()->le_connect_params());
617   EXPECT_FALSE(request_canceled);
618 
619   // Our request should have resulted in an error.
620   EXPECT_EQ(ToResult(HostError::kCanceled), status);
621   EXPECT_FALSE(conn);
622 }
623 
TEST_F(LowEnergyConnectorTest,UseLocalIdentityAddress)624 TEST_F(LowEnergyConnectorTest, UseLocalIdentityAddress) {
625   // Public identity address and a random current local address.
626   fake_address_delegate()->set_identity_address(kLocalAddress);
627   fake_address_delegate()->set_local_address(kRandomAddress);
628 
629   connector()->UseLocalIdentityAddress();
630 
631   auto fake_device =
632       std::make_unique<FakePeer>(kTestAddress, dispatcher(), true, true);
633   test_device()->AddPeer(std::move(fake_device));
634   connector()->CreateConnection(
635       /*use_accept_list=*/
636       false,
637       kTestAddress,
638       hci_spec::defaults::kLEScanInterval,
639       hci_spec::defaults::kLEScanWindow,
640       kTestParams,
641       [](auto, auto) {},
642       kPwConnectTimeout);
643   RunUntilIdle();
644   ASSERT_TRUE(test_device()->le_connect_params());
645 
646   // The public address should have been used.
647   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
648             test_device()->le_connect_params()->own_address_type);
649 }
650 
651 }  // namespace
652 }  // namespace bt::hci
653