xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/hci/low_energy_connector_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 kPwConnectTimeout =
40     std::chrono::seconds(10);
41 
42 class LowEnergyConnectorTest : public TestingBase,
43                                public ::testing::WithParamInterface<bool> {
44  public:
45   LowEnergyConnectorTest() = default;
46   ~LowEnergyConnectorTest() override = default;
47 
48  protected:
SetUp()49   void SetUp() override {
50     TestingBase::SetUp();
51     InitializeACLDataChannel();
52 
53     FakeController::Settings settings;
54     settings.ApplyLegacyLEConfig();
55     test_device()->set_settings(settings);
56 
57     fake_address_delegate_.set_local_address(kLocalAddress);
58 
59     bool use_extended_operations = GetParam();
60     connector_ = std::make_unique<LowEnergyConnector>(
61         transport()->GetWeakPtr(),
62         &fake_address_delegate_,
63         dispatcher(),
64         fit::bind_member<&LowEnergyConnectorTest::OnIncomingConnectionCreated>(
65             this),
66         use_extended_operations);
67 
68     test_device()->set_connection_state_callback(
69         fit::bind_member<&LowEnergyConnectorTest::OnConnectionStateChanged>(
70             this));
71   }
72 
TearDown()73   void TearDown() override {
74     connector_ = nullptr;
75     in_connections_.clear();
76     test_device()->Stop();
77     TestingBase::TearDown();
78   }
79 
CreateConnectionCompleteSubevent(hci_spec::ConnectionHandle conn_handle,const DeviceAddress & peer_address) const80   EventPacket CreateConnectionCompleteSubevent(
81       hci_spec::ConnectionHandle conn_handle,
82       const DeviceAddress& peer_address) const {
83     auto packet = hci::EventPacket::New<
84         pw::bluetooth::emboss::LEEnhancedConnectionCompleteSubeventV1Writer>(
85         hci_spec::kLEMetaEventCode);
86     auto params = packet.view_t();
87 
88     params.le_meta_event().subevent_code().Write(
89         hci_spec::kLEEnhancedConnectionCompleteSubeventCode);
90     params.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
91     params.connection_handle().Write(conn_handle);
92     params.role().Write(pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
93     params.peer_address_type().Write(
94         pw::bluetooth::emboss::LEAddressType::PUBLIC);
95     params.peer_address().CopyFrom(peer_address.value().view());
96     params.connection_interval().Write(
97         hci_spec::defaults::kLEConnectionIntervalMin);
98     params.peripheral_latency().Write(0);
99     params.supervision_timeout().Write(10);
100     params.central_clock_accuracy().Write(
101         pw::bluetooth::emboss::LEClockAccuracy::PPM_20);
102 
103     // there are also local_resolvable_private_address and
104     // peer_resolvable_private_address fields available within
105     // LEEnhancedConnectionCompleteSubeventV1. However, these fields are only
106     // valid when we use either the identity addresses in
107     // HCI_LE_Enhanced_Create_Connection for either the local device or peer
108     // device. Our tests mainly use public or random addresses, as if they
109     // have already resolved the addresses. We ignore setting these fields
110     // here to prevent confusion.
111 
112     return packet;
113   }
114 
heap_dispatcher()115   pw::async::HeapDispatcher& heap_dispatcher() { return heap_dispatcher_; }
DeleteConnector()116   void DeleteConnector() { connector_ = nullptr; }
request_canceled() const117   bool request_canceled() const { return request_canceled_; }
connector() const118   LowEnergyConnector* connector() const { return connector_.get(); }
119 
in_connections() const120   const std::vector<std::unique_ptr<LowEnergyConnection>>& in_connections()
121       const {
122     return in_connections_;
123   }
124 
fake_address_delegate()125   FakeLocalAddressDelegate* fake_address_delegate() {
126     return &fake_address_delegate_;
127   }
128 
129  private:
OnIncomingConnectionCreated(hci_spec::ConnectionHandle handle,pw::bluetooth::emboss::ConnectionRole role,const DeviceAddress & peer_address,const hci_spec::LEConnectionParameters &)130   void OnIncomingConnectionCreated(hci_spec::ConnectionHandle handle,
131                                    pw::bluetooth::emboss::ConnectionRole role,
132                                    const DeviceAddress& peer_address,
133                                    const hci_spec::LEConnectionParameters&) {
134     in_connections_.push_back(
135         std::make_unique<testing::FakeLowEnergyConnection>(
136             handle,
137             kLocalAddress,
138             peer_address,
139             role,
140             transport()->GetWeakPtr()));
141   }
142 
OnConnectionStateChanged(const DeviceAddress &,hci_spec::ConnectionHandle,bool,bool canceled)143   void OnConnectionStateChanged(const DeviceAddress&,
144                                 hci_spec::ConnectionHandle,
145                                 bool,
146                                 bool canceled) {
147     request_canceled_ = canceled;
148   }
149 
150   bool request_canceled_ = false;
151   FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
152   std::unique_ptr<LowEnergyConnector> connector_;
153   std::vector<std::unique_ptr<LowEnergyConnection>> in_connections_;
154   pw::async::HeapDispatcher heap_dispatcher_{dispatcher()};
155 
156   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyConnectorTest);
157 };
158 
159 INSTANTIATE_TEST_SUITE_P(LowEnergyConnectorTest,
160                          LowEnergyConnectorTest,
161                          ::testing::Bool());
162 
TEST_P(LowEnergyConnectorTest,CreateConnection)163 TEST_P(LowEnergyConnectorTest, CreateConnection) {
164   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
165   test_device()->AddPeer(std::move(fake_peer));
166   // Public address would be used if privacy was disabled
167   fake_address_delegate()->EnablePrivacy(true);
168 
169   EXPECT_FALSE(connector()->request_pending());
170   EXPECT_FALSE(connector()->pending_peer_address());
171 
172   Result<> status = fit::ok();
173   std::unique_ptr<LowEnergyConnection> conn;
174   bool callback_called = false;
175 
176   auto callback = [&](auto cb_status, auto cb_conn) {
177     status = cb_status;
178     conn = std::move(cb_conn);
179     callback_called = true;
180   };
181 
182   bool ret = connector()->CreateConnection(
183       /*use_accept_list=*/false,
184       kTestAddress,
185       hci_spec::defaults::kLEScanInterval,
186       hci_spec::defaults::kLEScanWindow,
187       kTestParams,
188       callback,
189       kPwConnectTimeout);
190   EXPECT_TRUE(ret);
191   EXPECT_TRUE(connector()->request_pending());
192   EXPECT_EQ(connector()->pending_peer_address().value(), kTestAddress);
193 
194   ret = connector()->CreateConnection(
195       /*use_accept_list=*/false,
196       kTestAddress,
197       hci_spec::defaults::kLEScanInterval,
198       hci_spec::defaults::kLEScanWindow,
199       kTestParams,
200       callback,
201       kPwConnectTimeout);
202   EXPECT_FALSE(ret);
203 
204   RunUntilIdle();
205 
206   EXPECT_FALSE(connector()->request_pending());
207   EXPECT_FALSE(connector()->pending_peer_address());
208   EXPECT_TRUE(callback_called);
209   EXPECT_EQ(fit::ok(), status);
210   EXPECT_TRUE(in_connections().empty());
211 
212   ASSERT_TRUE(conn);
213   EXPECT_EQ(1u, conn->handle());
214   EXPECT_EQ(kLocalAddress, conn->local_address());
215   EXPECT_EQ(kTestAddress, conn->peer_address());
216   conn->Disconnect(
217       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
218 }
219 
220 // Controller reports error from HCI Command Status event.
TEST_P(LowEnergyConnectorTest,CreateConnectionStatusError)221 TEST_P(LowEnergyConnectorTest, CreateConnectionStatusError) {
222   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
223   fake_peer->set_connect_status(
224       pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED);
225   test_device()->AddPeer(std::move(fake_peer));
226 
227   EXPECT_FALSE(connector()->request_pending());
228 
229   Result<> status = fit::ok();
230   std::unique_ptr<LowEnergyConnection> conn;
231   bool callback_called = false;
232 
233   auto callback = [&](auto cb_status, auto cb_conn) {
234     status = cb_status;
235     conn = std::move(cb_conn);
236     callback_called = true;
237   };
238 
239   bool ret = connector()->CreateConnection(
240       /*use_accept_list=*/false,
241       kTestAddress,
242       hci_spec::defaults::kLEScanInterval,
243       hci_spec::defaults::kLEScanWindow,
244       kTestParams,
245       callback,
246       kPwConnectTimeout);
247   EXPECT_TRUE(ret);
248   EXPECT_TRUE(connector()->request_pending());
249 
250   RunUntilIdle();
251 
252   EXPECT_FALSE(connector()->request_pending());
253   EXPECT_TRUE(callback_called);
254   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED),
255             status);
256   EXPECT_FALSE(conn);
257   EXPECT_TRUE(in_connections().empty());
258 }
259 
260 // Controller reports error from HCI LE Connection Complete event
TEST_P(LowEnergyConnectorTest,CreateConnectionEventError)261 TEST_P(LowEnergyConnectorTest, CreateConnectionEventError) {
262   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
263   fake_peer->set_connect_response(
264       pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_SECURITY);
265   test_device()->AddPeer(std::move(fake_peer));
266 
267   EXPECT_FALSE(connector()->request_pending());
268 
269   Result<> status = fit::ok();
270   std::unique_ptr<LowEnergyConnection> conn;
271   bool callback_called = false;
272 
273   auto callback = [&](auto cb_status, auto cb_conn) {
274     status = cb_status;
275     callback_called = true;
276     conn = std::move(cb_conn);
277   };
278 
279   bool ret = connector()->CreateConnection(
280       /*use_accept_list=*/false,
281       kTestAddress,
282       hci_spec::defaults::kLEScanInterval,
283       hci_spec::defaults::kLEScanWindow,
284       kTestParams,
285       callback,
286       kPwConnectTimeout);
287   EXPECT_TRUE(ret);
288   EXPECT_TRUE(connector()->request_pending());
289 
290   RunUntilIdle();
291 
292   EXPECT_FALSE(connector()->request_pending());
293   EXPECT_TRUE(callback_called);
294   EXPECT_EQ(
295       ToResult(pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_SECURITY),
296       status);
297   EXPECT_TRUE(in_connections().empty());
298   EXPECT_FALSE(conn);
299 }
300 
301 // Controller reports error from HCI LE Connection Complete event
TEST_P(LowEnergyConnectorTest,Cancel)302 TEST_P(LowEnergyConnectorTest, Cancel) {
303   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
304 
305   // Make sure the pending connect remains pending.
306   fake_peer->set_force_pending_connect(true);
307   test_device()->AddPeer(std::move(fake_peer));
308 
309   hci::Result<> status = fit::ok();
310   std::unique_ptr<LowEnergyConnection> conn;
311   bool callback_called = false;
312 
313   auto callback = [&](auto cb_status, auto cb_conn) {
314     status = cb_status;
315     callback_called = true;
316     conn = std::move(cb_conn);
317   };
318 
319   bool ret = connector()->CreateConnection(
320       /*use_accept_list=*/false,
321       kTestAddress,
322       hci_spec::defaults::kLEScanInterval,
323       hci_spec::defaults::kLEScanWindow,
324       kTestParams,
325       callback,
326       kPwConnectTimeout);
327   EXPECT_TRUE(ret);
328   EXPECT_TRUE(connector()->request_pending());
329 
330   ASSERT_FALSE(request_canceled());
331 
332   connector()->Cancel();
333   EXPECT_TRUE(connector()->request_pending());
334 
335   // The request timeout should be canceled regardless of whether it was posted
336   // before.
337   EXPECT_FALSE(connector()->timeout_posted());
338 
339   RunUntilIdle();
340 
341   EXPECT_FALSE(connector()->timeout_posted());
342   EXPECT_FALSE(connector()->request_pending());
343   EXPECT_TRUE(callback_called);
344   EXPECT_TRUE(request_canceled());
345   EXPECT_EQ(ToResult(HostError::kCanceled), status);
346   EXPECT_TRUE(in_connections().empty());
347   EXPECT_FALSE(conn);
348 }
349 
TEST_P(LowEnergyConnectorTest,IncomingConnect)350 TEST_P(LowEnergyConnectorTest, IncomingConnect) {
351   EXPECT_TRUE(in_connections().empty());
352   EXPECT_FALSE(connector()->request_pending());
353 
354   EventPacket packet = CreateConnectionCompleteSubevent(1, kTestAddress);
355   test_device()->SendCommandChannelPacket(packet.data());
356 
357   RunUntilIdle();
358   ASSERT_EQ(1u, in_connections().size());
359 
360   auto conn = in_connections()[0].get();
361   EXPECT_EQ(1u, conn->handle());
362   EXPECT_EQ(kLocalAddress, conn->local_address());
363   EXPECT_EQ(kTestAddress, conn->peer_address());
364   conn->Disconnect(
365       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
366 }
367 
TEST_P(LowEnergyConnectorTest,IncomingConnectDuringConnectionRequest)368 TEST_P(LowEnergyConnectorTest, IncomingConnectDuringConnectionRequest) {
369   const DeviceAddress kIncomingAddress(DeviceAddress::Type::kLEPublic, {2});
370 
371   EXPECT_TRUE(in_connections().empty());
372   EXPECT_FALSE(connector()->request_pending());
373 
374   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
375   test_device()->AddPeer(std::move(fake_peer));
376 
377   Result<> status = fit::ok();
378   std::unique_ptr<LowEnergyConnection> conn;
379   unsigned int callback_count = 0;
380 
381   auto callback = [&](auto cb_status, auto cb_conn) {
382     status = cb_status;
383     callback_count++;
384     conn = std::move(cb_conn);
385   };
386 
387   connector()->CreateConnection(
388       /*use_accept_list=*/false,
389       kTestAddress,
390       hci_spec::defaults::kLEScanInterval,
391       hci_spec::defaults::kLEScanWindow,
392       kTestParams,
393       callback,
394       kPwConnectTimeout);
395 
396   (void)heap_dispatcher().Post(
397       [kIncomingAddress, this](pw::async::Context /*ctx*/, pw::Status status) {
398         if (!status.ok()) {
399           return;
400         }
401 
402         EventPacket packet =
403             CreateConnectionCompleteSubevent(2, kIncomingAddress);
404         test_device()->SendCommandChannelPacket(packet.data());
405       });
406 
407   RunUntilIdle();
408 
409   EXPECT_EQ(fit::ok(), status);
410   EXPECT_EQ(1u, callback_count);
411   ASSERT_EQ(1u, in_connections().size());
412 
413   const auto& in_conn = in_connections().front();
414 
415   EXPECT_EQ(1u, conn->handle());
416   EXPECT_EQ(2u, in_conn->handle());
417   EXPECT_EQ(kTestAddress, conn->peer_address());
418   EXPECT_EQ(kIncomingAddress, in_conn->peer_address());
419 
420   conn->Disconnect(
421       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
422   in_conn->Disconnect(
423       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
424 }
425 
TEST_P(LowEnergyConnectorTest,CreateConnectionTimeout)426 TEST_P(LowEnergyConnectorTest, CreateConnectionTimeout) {
427   // We do not set up any fake devices. This will cause the request to time out.
428   EXPECT_FALSE(connector()->request_pending());
429 
430   Result<> status = fit::ok();
431   std::unique_ptr<LowEnergyConnection> conn;
432   bool callback_called = false;
433 
434   auto callback = [&](auto cb_status, auto cb_conn) {
435     status = cb_status;
436     callback_called = true;
437     conn = std::move(cb_conn);
438   };
439 
440   connector()->CreateConnection(
441       /*use_accept_list=*/false,
442       kTestAddress,
443       hci_spec::defaults::kLEScanInterval,
444       hci_spec::defaults::kLEScanWindow,
445       kTestParams,
446       callback,
447       kPwConnectTimeout);
448   EXPECT_TRUE(connector()->request_pending());
449 
450   EXPECT_FALSE(request_canceled());
451 
452   // Make the connection attempt time out.
453   RunFor(kPwConnectTimeout);
454 
455   EXPECT_FALSE(connector()->request_pending());
456   EXPECT_TRUE(callback_called);
457   EXPECT_TRUE(request_canceled());
458   EXPECT_EQ(ToResult(HostError::kTimedOut), status);
459   EXPECT_TRUE(in_connections().empty());
460   EXPECT_FALSE(conn);
461 }
462 
TEST_P(LowEnergyConnectorTest,SendRequestAndDelete)463 TEST_P(LowEnergyConnectorTest, SendRequestAndDelete) {
464   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
465 
466   // Make sure the pending connect remains pending.
467   fake_peer->set_force_pending_connect(true);
468   test_device()->AddPeer(std::move(fake_peer));
469 
470   bool ret = connector()->CreateConnection(
471       /*use_accept_list=*/
472       false,
473       kTestAddress,
474       hci_spec::defaults::kLEScanInterval,
475       hci_spec::defaults::kLEScanWindow,
476       kTestParams,
477       [](auto, auto) {},
478       kPwConnectTimeout);
479   EXPECT_TRUE(ret);
480   EXPECT_TRUE(connector()->request_pending());
481 
482   DeleteConnector();
483   RunUntilIdle();
484 
485   EXPECT_TRUE(request_canceled());
486   EXPECT_TRUE(in_connections().empty());
487 }
488 
TEST_P(LowEnergyConnectorTest,AllowsRandomAddressChange)489 TEST_P(LowEnergyConnectorTest, AllowsRandomAddressChange) {
490   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
491 
492   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
493   test_device()->AddPeer(std::move(fake_peer));
494 
495   // Address change should not be allowed while the procedure is pending.
496   connector()->CreateConnection(
497       /*use_accept_list=*/
498       false,
499       kTestAddress,
500       hci_spec::defaults::kLEScanInterval,
501       hci_spec::defaults::kLEScanWindow,
502       kTestParams,
503       [](auto, auto) {},
504       kPwConnectTimeout);
505   EXPECT_TRUE(connector()->request_pending());
506   EXPECT_FALSE(connector()->AllowsRandomAddressChange());
507 
508   RunUntilIdle();
509   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
510 }
511 
TEST_P(LowEnergyConnectorTest,AllowsRandomAddressChangeWhileRequestingLocalAddress)512 TEST_P(LowEnergyConnectorTest,
513        AllowsRandomAddressChangeWhileRequestingLocalAddress) {
514   // Make the local address delegate report its result asynchronously.
515   fake_address_delegate()->set_async(true);
516 
517   // The connector should be in the "request pending" state without initiating
518   // controller procedures that would prevent a local address change.
519   connector()->CreateConnection(
520       /*use_accept_list=*/
521       false,
522       kTestAddress,
523       hci_spec::defaults::kLEScanInterval,
524       hci_spec::defaults::kLEScanWindow,
525       kTestParams,
526       [](auto, auto) {},
527       kPwConnectTimeout);
528   EXPECT_TRUE(connector()->request_pending());
529   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
530 
531   // Initiating a new connection should fail in this state.
532   bool result = connector()->CreateConnection(
533       /*use_accept_list=*/
534       false,
535       kTestAddress,
536       hci_spec::defaults::kLEScanInterval,
537       hci_spec::defaults::kLEScanWindow,
538       kTestParams,
539       [](auto, auto) {},
540       kPwConnectTimeout);
541   EXPECT_FALSE(result);
542 
543   // After the loop runs the request should remain pending (since we added no
544   // fake device, the request would eventually timeout) but address change
545   // should no longer be allowed.
546   RunUntilIdle();
547   EXPECT_TRUE(connector()->request_pending());
548   EXPECT_FALSE(connector()->AllowsRandomAddressChange());
549 }
550 
TEST_P(LowEnergyConnectorTest,ConnectUsingAcceptList)551 TEST_P(LowEnergyConnectorTest, ConnectUsingAcceptList) {
552   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
553   test_device()->AddPeer(std::move(fake_peer));
554   connector()->CreateConnection(
555       /*use_accept_list=*/
556       true,
557       kTestAddress,
558       hci_spec::defaults::kLEScanInterval,
559       hci_spec::defaults::kLEScanWindow,
560       kTestParams,
561       [](auto, auto) {},
562       kPwConnectTimeout);
563   RunUntilIdle();
564   ASSERT_TRUE(test_device()->le_connect_params());
565   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
566             test_device()->le_connect_params()->own_address_type);
567 }
568 
TEST_P(LowEnergyConnectorTest,ConnectUsingPublicAddress)569 TEST_P(LowEnergyConnectorTest, ConnectUsingPublicAddress) {
570   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
571   test_device()->AddPeer(std::move(fake_peer));
572   connector()->CreateConnection(
573       /*use_accept_list=*/
574       false,
575       kTestAddress,
576       hci_spec::defaults::kLEScanInterval,
577       hci_spec::defaults::kLEScanWindow,
578       kTestParams,
579       [](auto, auto) {},
580       kPwConnectTimeout);
581   RunUntilIdle();
582   ASSERT_TRUE(test_device()->le_connect_params());
583   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
584             test_device()->le_connect_params()->own_address_type);
585 }
586 
TEST_P(LowEnergyConnectorTest,ConnectUsingRandomAddress)587 TEST_P(LowEnergyConnectorTest, ConnectUsingRandomAddress) {
588   fake_address_delegate()->set_local_address(kRandomAddress);
589   fake_address_delegate()->EnablePrivacy(true);
590 
591   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
592   test_device()->AddPeer(std::move(fake_peer));
593   connector()->CreateConnection(
594       /*use_accept_list=*/
595       false,
596       kTestAddress,
597       hci_spec::defaults::kLEScanInterval,
598       hci_spec::defaults::kLEScanWindow,
599       kTestParams,
600       [](auto, auto) {},
601       kPwConnectTimeout);
602   RunUntilIdle();
603   ASSERT_TRUE(test_device()->le_connect_params());
604   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
605             test_device()->le_connect_params()->own_address_type);
606 }
607 
TEST_P(LowEnergyConnectorTest,ConnectUsingRandomPeerAddress)608 TEST_P(LowEnergyConnectorTest, ConnectUsingRandomPeerAddress) {
609   auto fake_peer = std::make_unique<FakePeer>(kRandomAddress, dispatcher());
610   test_device()->AddPeer(std::move(fake_peer));
611   connector()->CreateConnection(
612       /*use_accept_list=*/
613       false,
614       kRandomAddress,
615       hci_spec::defaults::kLEScanInterval,
616       hci_spec::defaults::kLEScanWindow,
617       kTestParams,
618       [](auto, auto) {},
619       kPwConnectTimeout);
620   RunUntilIdle();
621   ASSERT_TRUE(test_device()->le_connect_params());
622   EXPECT_EQ(DeviceAddress::Type::kLERandom,
623             test_device()->le_connect_params()->peer_address.type());
624 }
625 
TEST_P(LowEnergyConnectorTest,CancelConnectWhileWaitingForLocalAddress)626 TEST_P(LowEnergyConnectorTest, CancelConnectWhileWaitingForLocalAddress) {
627   Result<> status = fit::ok();
628   std::unique_ptr<LowEnergyConnection> conn;
629   auto callback = [&](auto s, auto c) {
630     status = s;
631     conn = std::move(c);
632   };
633   fake_address_delegate()->set_async(true);
634   connector()->CreateConnection(
635       /*use_accept_list=*/false,
636       kTestAddress,
637       hci_spec::defaults::kLEScanInterval,
638       hci_spec::defaults::kLEScanWindow,
639       kTestParams,
640       std::move(callback),
641       kPwConnectTimeout);
642 
643   // Should be waiting for the address.
644   EXPECT_TRUE(connector()->request_pending());
645   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
646 
647   connector()->Cancel();
648   RunUntilIdle();
649   EXPECT_FALSE(connector()->request_pending());
650   EXPECT_TRUE(connector()->AllowsRandomAddressChange());
651 
652   // The controller should have received no command from us.
653   EXPECT_FALSE(test_device()->le_connect_params());
654   EXPECT_FALSE(request_canceled());
655 
656   // Our request should have resulted in an error.
657   EXPECT_EQ(ToResult(HostError::kCanceled), status);
658   EXPECT_FALSE(conn);
659 }
660 
TEST_P(LowEnergyConnectorTest,UseLocalIdentityAddress)661 TEST_P(LowEnergyConnectorTest, UseLocalIdentityAddress) {
662   // Public identity address and a random current local address.
663   fake_address_delegate()->set_identity_address(kLocalAddress);
664   fake_address_delegate()->set_local_address(kRandomAddress);
665 
666   connector()->UseLocalIdentityAddress();
667 
668   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
669   test_device()->AddPeer(std::move(fake_peer));
670   connector()->CreateConnection(
671       /*use_accept_list=*/
672       false,
673       kTestAddress,
674       hci_spec::defaults::kLEScanInterval,
675       hci_spec::defaults::kLEScanWindow,
676       kTestParams,
677       [](auto, auto) {},
678       kPwConnectTimeout);
679   RunUntilIdle();
680   ASSERT_TRUE(test_device()->le_connect_params());
681 
682   // The public address should have been used.
683   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
684             test_device()->le_connect_params()->own_address_type);
685 }
686 
TEST_P(LowEnergyConnectorTest,ExtendedCreateConnectionUsesSameParameters)687 TEST_P(LowEnergyConnectorTest, ExtendedCreateConnectionUsesSameParameters) {
688   bool use_extended_operations = GetParam();
689   if (!use_extended_operations) {
690     // For this specific test, we want to test only the LE Extended Create
691     // Connection functionality. Since this is only a single test, skipping the
692     // LE Create Connection option seemed simpler. If tests for LE Extended
693     // Create Connection grow in number, we should create a separate file, test
694     // suite, etc.
695     return;
696   }
697 
698   using LEConnectParams = FakeController::LEConnectParams;
699   using InitiatingPHYs = LEConnectParams::InitiatingPHYs;
700 
701   auto fake_peer = std::make_unique<FakePeer>(kTestAddress, dispatcher());
702   test_device()->AddPeer(std::move(fake_peer));
703 
704   connector()->CreateConnection(
705       /*use_accept_list=*/
706       true,
707       kTestAddress,
708       hci_spec::defaults::kLEScanInterval,
709       hci_spec::defaults::kLEScanWindow,
710       kTestParams,
711       [](auto, auto) {},
712       kPwConnectTimeout);
713   RunUntilIdle();
714 
715   const std::optional<LEConnectParams>& params =
716       test_device()->le_connect_params();
717   ASSERT_EQ(3u, params->phy_conn_params.size());
718   const auto& le_1m =
719       params->phy_conn_params.find(InitiatingPHYs::kLE_1M)->second;
720   const auto& le_2m =
721       params->phy_conn_params.find(InitiatingPHYs::kLE_2M)->second;
722   const auto& le_coded =
723       params->phy_conn_params.find(InitiatingPHYs::kLE_Coded)->second;
724 
725   ASSERT_EQ(le_1m.scan_interval, le_2m.scan_interval);
726   ASSERT_EQ(le_1m.scan_window, le_2m.scan_window);
727   ASSERT_EQ(le_1m.connection_interval_min, le_2m.connection_interval_min);
728   ASSERT_EQ(le_1m.connection_interval_max, le_2m.connection_interval_max);
729   ASSERT_EQ(le_1m.max_latency, le_2m.max_latency);
730   ASSERT_EQ(le_1m.supervision_timeout, le_2m.supervision_timeout);
731   ASSERT_EQ(le_1m.min_ce_length, le_2m.min_ce_length);
732   ASSERT_EQ(le_1m.max_ce_length, le_2m.max_ce_length);
733 
734   ASSERT_EQ(le_2m.scan_interval, le_coded.scan_interval);
735   ASSERT_EQ(le_2m.scan_window, le_coded.scan_window);
736   ASSERT_EQ(le_2m.connection_interval_min, le_coded.connection_interval_min);
737   ASSERT_EQ(le_2m.connection_interval_max, le_coded.connection_interval_max);
738   ASSERT_EQ(le_2m.max_latency, le_coded.max_latency);
739   ASSERT_EQ(le_2m.supervision_timeout, le_coded.supervision_timeout);
740   ASSERT_EQ(le_2m.min_ce_length, le_coded.min_ce_length);
741   ASSERT_EQ(le_2m.max_ce_length, le_coded.max_ce_length);
742 }
743 
744 }  // namespace
745 }  // namespace bt::hci
746