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_connection_manager.h"
16
17 #include <gmock/gmock.h>
18 #include <lib/fit/function.h>
19 #include <pw_assert/check.h>
20
21 #include <cstddef>
22 #include <limits>
23 #include <memory>
24 #include <vector>
25
26 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
27 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
28 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
29 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
30 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
31 #include "pw_bluetooth_sapphire/internal/host/gap/low_energy_address_manager.h"
32 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h"
33 #include "pw_bluetooth_sapphire/internal/host/gap/peer_cache.h"
34 #include "pw_bluetooth_sapphire/internal/host/gatt/fake_layer.h"
35 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
36 #include "pw_bluetooth_sapphire/internal/host/hci-spec/defaults.h"
37 #include "pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
38 #include "pw_bluetooth_sapphire/internal/host/hci/fake_local_address_delegate.h"
39 #include "pw_bluetooth_sapphire/internal/host/hci/legacy_low_energy_scanner.h"
40 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connection.h"
41 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connector.h"
42 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel.h"
43 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_l2cap.h"
44 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
45 #include "pw_bluetooth_sapphire/internal/host/l2cap/types.h"
46 #include "pw_bluetooth_sapphire/internal/host/sm/test_security_manager.h"
47 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
48 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
49 #include "pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
50 #include "pw_bluetooth_sapphire/internal/host/testing/fake_peer.h"
51 #include "pw_bluetooth_sapphire/internal/host/testing/inspect.h"
52 #include "pw_bluetooth_sapphire/internal/host/transport/fake_acl_connection.h"
53
54 namespace bt::gap {
55 namespace {
56
57 using namespace inspect::testing;
58
59 using bt::sm::BondableMode;
60 using bt::testing::FakeController;
61 using bt::testing::FakePeer;
62
63 using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
64 using TestSm = sm::testing::TestSecurityManager;
65 using TestSmFactory = sm::testing::TestSecurityManagerFactory;
66 using ConnectionResult = LowEnergyConnectionManager::ConnectionResult;
67
68 const bt::sm::LTK kLTK;
69
70 const DeviceAddress kAddress0(DeviceAddress::Type::kLEPublic, {1});
71 const DeviceAddress kAddrAlias0(DeviceAddress::Type::kBREDR, kAddress0.value());
72 const DeviceAddress kAddress1(DeviceAddress::Type::kLERandom, {2});
73 const DeviceAddress kAddress2(DeviceAddress::Type::kBREDR, {3});
74 const DeviceAddress kAddress3(DeviceAddress::Type::kLEPublic, {4});
75 const DeviceAddress kAdapterAddress(DeviceAddress::Type::kLEPublic, {9});
76
77 const size_t kLEMaxNumPackets = 10;
78 const hci::DataBufferInfo kLEDataBufferInfo(hci_spec::kMaxACLPayloadSize,
79 kLEMaxNumPackets);
80
81 constexpr std::array kConnectDelays = {
82 std::chrono::seconds(0), std::chrono::seconds(2), std::chrono::seconds(4)};
83
84 const LowEnergyConnectionOptions kConnectionOptions{};
85
86 class LowEnergyConnectionManagerTest : public TestingBase {
87 public:
88 LowEnergyConnectionManagerTest() = default;
89 ~LowEnergyConnectionManagerTest() override = default;
90
91 protected:
SetUp()92 void SetUp() override {
93 TestingBase::SetUp();
94
95 // Initialize with LE buffers only.
96 TestingBase::InitializeACLDataChannel(hci::DataBufferInfo(),
97 kLEDataBufferInfo);
98
99 FakeController::Settings settings;
100 settings.ApplyLegacyLEConfig();
101 test_device()->set_settings(settings);
102
103 peer_cache_ = std::make_unique<PeerCache>(dispatcher());
104 l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());
105
106 const hci::CommandChannel::WeakPtr cmd_weak = cmd_channel()->AsWeakPtr();
107
108 connector_ = std::make_unique<hci::LowEnergyConnector>(
109 transport()->GetWeakPtr(),
110 &addr_delegate_,
111 dispatcher(),
112 fit::bind_member<&LowEnergyConnectionManagerTest::OnIncomingConnection>(
113 this));
114
115 gatt_ = std::make_unique<gatt::testing::FakeLayer>(dispatcher());
116 sm_factory_ = std::make_unique<TestSmFactory>();
117
118 hci::LowEnergyScanner::PacketFilterConfig packet_filter_config(false, 0);
119
120 address_manager_ = std::make_unique<LowEnergyAddressManager>(
121 kAdapterAddress,
122 /*delegate=*/[] { return false; },
123 cmd_weak,
124 dispatcher());
125 scanner_ =
126 std::make_unique<hci::LegacyLowEnergyScanner>(address_manager_.get(),
127 packet_filter_config,
128 transport()->GetWeakPtr(),
129 dispatcher());
130 discovery_manager_ = std::make_unique<LowEnergyDiscoveryManager>(
131 scanner_.get(), peer_cache_.get(), packet_filter_config, dispatcher());
132 conn_mgr_ = std::make_unique<LowEnergyConnectionManager>(
133 transport()->GetWeakPtr(),
134 &addr_delegate_,
135 connector_.get(),
136 peer_cache_.get(),
137 l2cap_.get(),
138 gatt_->GetWeakPtr(),
139 discovery_manager_->GetWeakPtr(),
140 fit::bind_member<&TestSmFactory::CreateSm>(sm_factory_.get()),
141 adapter_state_,
142 dispatcher());
143
144 test_device()->set_connection_state_callback(
145 fit::bind_member<
146 &LowEnergyConnectionManagerTest::OnConnectionStateChanged>(this));
147 }
148
TearDown()149 void TearDown() override {
150 if (conn_mgr_) {
151 conn_mgr_ = nullptr;
152 }
153 discovery_manager_ = nullptr;
154 scanner_ = nullptr;
155 address_manager_ = nullptr;
156 gatt_ = nullptr;
157 connector_ = nullptr;
158 peer_cache_ = nullptr;
159
160 l2cap_ = nullptr;
161
162 TestingBase::TearDown();
163 }
164
165 // Deletes |conn_mgr_|.
DeleteConnMgr()166 void DeleteConnMgr() { conn_mgr_ = nullptr; }
167
peer_cache() const168 PeerCache* peer_cache() const { return peer_cache_.get(); }
conn_mgr() const169 LowEnergyConnectionManager* conn_mgr() const { return conn_mgr_.get(); }
fake_l2cap() const170 l2cap::testing::FakeL2cap* fake_l2cap() const { return l2cap_.get(); }
fake_gatt()171 gatt::testing::FakeLayer* fake_gatt() { return gatt_.get(); }
discovery_mgr()172 LowEnergyDiscoveryManager* discovery_mgr() {
173 return discovery_manager_.get();
174 }
175
176 // Addresses of currently connected fake peers.
177 using PeerList = std::unordered_set<DeviceAddress>;
connected_peers() const178 const PeerList& connected_peers() const { return connected_peers_; }
179
180 // Addresses of peers with a canceled connection attempt.
canceled_peers() const181 const PeerList& canceled_peers() const { return canceled_peers_; }
182
MoveLastRemoteInitiated()183 std::unique_ptr<hci::LowEnergyConnection> MoveLastRemoteInitiated() {
184 return std::move(last_remote_initiated_);
185 }
186
TestSmByHandle(hci_spec::ConnectionHandle handle)187 TestSm::WeakPtr TestSmByHandle(hci_spec::ConnectionHandle handle) {
188 return sm_factory_->GetTestSm(handle);
189 }
190
191 private:
192 // Called by |connector_| when a new remote initiated connection is received.
OnIncomingConnection(hci_spec::ConnectionHandle handle,pw::bluetooth::emboss::ConnectionRole role,const DeviceAddress & peer_address,const hci_spec::LEConnectionParameters & conn_params)193 void OnIncomingConnection(
194 hci_spec::ConnectionHandle handle,
195 pw::bluetooth::emboss::ConnectionRole role,
196 const DeviceAddress& peer_address,
197 const hci_spec::LEConnectionParameters& conn_params) {
198 DeviceAddress local_address(DeviceAddress::Type::kLEPublic,
199 {3, 2, 1, 1, 2, 3});
200
201 // Create a production connection object that can interact with the fake
202 // controller.
203 last_remote_initiated_ =
204 std::make_unique<hci::LowEnergyConnection>(handle,
205 local_address,
206 peer_address,
207 conn_params,
208 role,
209 transport()->GetWeakPtr());
210 }
211
212 // Called by FakeController on connection events.
OnConnectionStateChanged(const DeviceAddress & address,hci_spec::ConnectionHandle handle,bool connected,bool canceled)213 void OnConnectionStateChanged(const DeviceAddress& address,
214 hci_spec::ConnectionHandle handle,
215 bool connected,
216 bool canceled) {
217 bt_log(DEBUG,
218 "gap-test",
219 "OnConnectionStateChanged: %s (handle: %#.4x) (connected: %s) "
220 "(canceled: %s):\n",
221 address.ToString().c_str(),
222 handle,
223 (connected ? "true" : "false"),
224 (canceled ? "true" : "false"));
225 if (canceled) {
226 canceled_peers_.insert(address);
227 } else if (connected) {
228 PW_DCHECK(connected_peers_.find(address) == connected_peers_.end());
229 connected_peers_.insert(address);
230 } else {
231 PW_DCHECK(connected_peers_.find(address) != connected_peers_.end());
232 connected_peers_.erase(address);
233 }
234 }
235
236 std::unique_ptr<l2cap::testing::FakeL2cap> l2cap_;
237 hci::FakeLocalAddressDelegate addr_delegate_{dispatcher()};
238 std::unique_ptr<PeerCache> peer_cache_;
239 std::unique_ptr<hci::LowEnergyConnector> connector_;
240 std::unique_ptr<gatt::testing::FakeLayer> gatt_;
241 std::unique_ptr<TestSmFactory> sm_factory_;
242 std::unique_ptr<hci::LegacyLowEnergyScanner> scanner_;
243 std::unique_ptr<LowEnergyAddressManager> address_manager_;
244 std::unique_ptr<LowEnergyDiscoveryManager> discovery_manager_;
245 std::unique_ptr<LowEnergyConnectionManager> conn_mgr_;
246
247 AdapterState adapter_state_ = {};
248
249 // The most recent remote-initiated connection reported by |connector_|.
250 std::unique_ptr<hci::LowEnergyConnection> last_remote_initiated_;
251
252 PeerList connected_peers_;
253 PeerList canceled_peers_;
254
255 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyConnectionManagerTest);
256 };
257
258 using GAP_LowEnergyConnectionManagerTest = LowEnergyConnectionManagerTest;
259
TEST_F(LowEnergyConnectionManagerTest,ConnectUnknownPeer)260 TEST_F(LowEnergyConnectionManagerTest, ConnectUnknownPeer) {
261 constexpr PeerId kUnknownId(1);
262 ConnectionResult result = fit::ok(nullptr);
263 conn_mgr()->Connect(
264 kUnknownId,
265 [&result](auto res) { result = std::move(res); },
266 kConnectionOptions);
267 ASSERT_TRUE(result.is_error());
268 EXPECT_EQ(HostError::kNotFound, result.error_value());
269 }
270
TEST_F(LowEnergyConnectionManagerTest,ConnectClassicPeer)271 TEST_F(LowEnergyConnectionManagerTest, ConnectClassicPeer) {
272 auto* peer = peer_cache()->NewPeer(kAddress2, /*connectable=*/true);
273 ConnectionResult result = fit::ok(nullptr);
274 conn_mgr()->Connect(
275 peer->identifier(),
276 [&result](auto res) { result = std::move(res); },
277 kConnectionOptions);
278 ASSERT_TRUE(result.is_error());
279 EXPECT_EQ(HostError::kNotFound, result.error_value());
280 }
281
TEST_F(LowEnergyConnectionManagerTest,ConnectNonConnectablePeer)282 TEST_F(LowEnergyConnectionManagerTest, ConnectNonConnectablePeer) {
283 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/false);
284 ConnectionResult result = fit::ok(nullptr);
285 conn_mgr()->Connect(
286 peer->identifier(),
287 [&result](auto res) { result = std::move(res); },
288 kConnectionOptions);
289 ASSERT_TRUE(result.is_error());
290 EXPECT_EQ(HostError::kNotFound, result.error_value());
291 }
292
293 // An error is received via the HCI Command cb_status event
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeerErrorStatus)294 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerErrorStatus) {
295 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
296 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
297 fake_peer->set_connect_status(
298 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
299 test_device()->AddPeer(std::move(fake_peer));
300
301 ASSERT_TRUE(peer->le());
302 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
303 peer->le()->connection_state());
304
305 ConnectionResult result = fit::ok(nullptr);
306 auto callback = [&result](auto res) { result = std::move(res); };
307
308 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
309 EXPECT_EQ(Peer::ConnectionState::kInitializing,
310 peer->le()->connection_state());
311
312 RunUntilIdle();
313
314 ASSERT_TRUE(result.is_error());
315 EXPECT_EQ(HostError::kFailed, result.error_value());
316 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
317 peer->le()->connection_state());
318 }
319
320 // LE Connection Complete event reports error
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeerFailure)321 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerFailure) {
322 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
323 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
324 fake_peer->set_connect_response(
325 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
326 test_device()->AddPeer(std::move(fake_peer));
327
328 ConnectionResult result = fit::ok(nullptr);
329 auto callback = [&result](auto res) { result = std::move(res); };
330
331 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
332 ASSERT_TRUE(peer->le());
333 EXPECT_EQ(Peer::ConnectionState::kInitializing,
334 peer->le()->connection_state());
335
336 RunUntilIdle();
337
338 ASSERT_TRUE(result.is_error());
339 EXPECT_EQ(HostError::kFailed, result.error_value());
340 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
341 peer->le()->connection_state());
342 }
343
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeerScanTimeout)344 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerScanTimeout) {
345 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
346
347 // We add no fake peers to cause the scan to time out.
348
349 ConnectionResult result = fit::ok(nullptr);
350 auto callback = [&result](auto res) { result = std::move(res); };
351
352 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
353 ASSERT_TRUE(peer->le());
354 EXPECT_EQ(Peer::ConnectionState::kInitializing,
355 peer->le()->connection_state());
356
357 RunFor(kLEGeneralCepScanTimeout);
358
359 ASSERT_TRUE(result.is_error());
360 EXPECT_EQ(HostError::kTimedOut, result.error_value());
361 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
362 peer->le()->connection_state());
363 }
364
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeerAlreadyInScanCache)365 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerAlreadyInScanCache) {
366 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
367 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
368 test_device()->AddPeer(std::move(fake_peer));
369
370 // Ensure peer is in scan cache by doing active discovery.
371 LowEnergyDiscoverySessionPtr session;
372 discovery_mgr()->StartDiscovery(
373 /*active=*/true, {}, [&session](auto cb_session) {
374 session = std::move(cb_session);
375 });
376 RunUntilIdle();
377
378 ConnectionResult result = fit::ok(nullptr);
379 auto callback = [&result](auto res) { result = std::move(res); };
380
381 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
382 RunUntilIdle();
383 ASSERT_EQ(fit::ok(), result);
384 }
385
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeerRequestTimeout)386 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeerRequestTimeout) {
387 constexpr pw::chrono::SystemClock::duration kTestRequestTimeout =
388 std::chrono::seconds(20);
389
390 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
391
392 // Add a fake peer so that scan succeeds but connect stalls.
393 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
394 fake_peer->set_force_pending_connect(true);
395 test_device()->AddPeer(std::move(fake_peer));
396
397 ConnectionResult result = fit::ok(nullptr);
398 auto callback = [&result](auto res) { result = std::move(res); };
399
400 conn_mgr()->set_request_timeout_for_testing(kTestRequestTimeout);
401 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
402 ASSERT_TRUE(peer->le());
403 EXPECT_EQ(Peer::ConnectionState::kInitializing,
404 peer->le()->connection_state());
405
406 RunFor(kTestRequestTimeout);
407 RunUntilIdle();
408
409 ASSERT_TRUE(result.is_error());
410 EXPECT_EQ(HostError::kTimedOut, result.error_value());
411 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
412 peer->le()->connection_state());
413 }
414
415 // Tests that an entry in the cache does not expire while a connection attempt
416 // is pending.
TEST_F(LowEnergyConnectionManagerTest,PeerDoesNotExpireDuringTimeout)417 TEST_F(LowEnergyConnectionManagerTest, PeerDoesNotExpireDuringTimeout) {
418 // Set a connection timeout that is longer than the PeerCache expiry
419 // timeout.
420 // TODO(fxbug.dev/42087236): Consider configuring the cache timeout explicitly
421 // rather than relying on the kCacheTimeout constant.
422 constexpr pw::chrono::SystemClock::duration kTestRequestTimeout =
423 kCacheTimeout + std::chrono::seconds(1);
424 conn_mgr()->set_request_timeout_for_testing(kTestRequestTimeout);
425
426 // Note: Use a random address so that the peer becomes temporary upon failure.
427 auto* peer = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
428 EXPECT_TRUE(peer->temporary());
429
430 ConnectionResult result = fit::ok(nullptr);
431 auto callback = [&result](auto res) { result = std::move(res); };
432
433 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
434 ASSERT_TRUE(peer->le());
435 EXPECT_EQ(Peer::ConnectionState::kInitializing,
436 peer->le()->connection_state());
437 EXPECT_FALSE(peer->temporary());
438
439 RunFor(kTestRequestTimeout);
440 ASSERT_TRUE(result.is_error());
441 EXPECT_EQ(HostError::kTimedOut, result.error_value());
442 EXPECT_EQ(peer, peer_cache()->FindByAddress(kAddress1));
443 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
444 peer->le()->connection_state());
445 EXPECT_TRUE(peer->temporary());
446 }
447
TEST_F(LowEnergyConnectionManagerTest,PeerDoesNotExpireDuringDelayedConnect)448 TEST_F(LowEnergyConnectionManagerTest, PeerDoesNotExpireDuringDelayedConnect) {
449 // Make the connection resolve after a delay that is longer than the cache
450 // timeout.
451 constexpr pw::chrono::SystemClock::duration kConnectionDelay =
452 kCacheTimeout + std::chrono::seconds(1);
453 FakeController::Settings settings;
454 settings.ApplyLegacyLEConfig();
455 settings.le_connection_delay = kConnectionDelay;
456 test_device()->set_settings(settings);
457
458 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
459 auto id = peer->identifier();
460 EXPECT_TRUE(peer->temporary());
461
462 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
463 test_device()->AddPeer(std::move(fake_peer));
464
465 // Make sure the connection request doesn't time out while waiting for a
466 // response.
467 conn_mgr()->set_request_timeout_for_testing(kConnectionDelay +
468 std::chrono::seconds(1));
469
470 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
471 auto callback = [&conn_handle](auto result) {
472 ASSERT_EQ(fit::ok(), result);
473 conn_handle = std::move(result).value();
474 ASSERT_TRUE(conn_handle);
475 EXPECT_TRUE(conn_handle->active());
476 };
477 conn_mgr()->Connect(id, callback, kConnectionOptions);
478 ASSERT_TRUE(peer->le());
479 EXPECT_EQ(Peer::ConnectionState::kInitializing,
480 peer->le()->connection_state());
481
482 RunFor(kConnectionDelay);
483 ASSERT_TRUE(conn_handle);
484
485 // The peer should not have expired during this time.
486 peer = peer_cache()->FindByAddress(kAddress0);
487 ASSERT_TRUE(peer);
488 EXPECT_EQ(id, peer->identifier());
489 EXPECT_TRUE(peer->connected());
490 EXPECT_FALSE(peer->temporary());
491 }
492
493 // Successful connection to single peer
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeer)494 TEST_F(LowEnergyConnectionManagerTest, ConnectSinglePeer) {
495 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
496 EXPECT_TRUE(peer->temporary());
497
498 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
499 test_device()->AddPeer(std::move(fake_peer));
500
501 // Use a StaticPacket so that the packet is copied.
502 std::optional<
503 StaticPacket<pw::bluetooth::emboss::LECreateConnectionCommandWriter>>
504 connect_params;
505 test_device()->set_le_create_connection_command_callback(
506 [&](pw::bluetooth::emboss::LECreateConnectionCommandView params) {
507 connect_params.emplace(params);
508 });
509
510 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
511 auto callback = [&conn_handle](auto result) {
512 ASSERT_EQ(fit::ok(), result);
513 conn_handle = std::move(result).value();
514 EXPECT_TRUE(conn_handle->active());
515 };
516
517 EXPECT_TRUE(connected_peers().empty());
518 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
519 ASSERT_TRUE(peer->le());
520 EXPECT_EQ(Peer::ConnectionState::kInitializing,
521 peer->le()->connection_state());
522
523 RunUntilIdle();
524
525 EXPECT_EQ(1u, connected_peers().size());
526 EXPECT_EQ(1u, connected_peers().count(kAddress0));
527
528 ASSERT_TRUE(conn_handle);
529 EXPECT_TRUE(conn_handle->active());
530 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
531 EXPECT_FALSE(peer->temporary());
532 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
533 ASSERT_TRUE(connect_params);
534 EXPECT_EQ(connect_params->view().le_scan_interval().Read(),
535 kLEScanFastInterval);
536 EXPECT_EQ(connect_params->view().le_scan_window().Read(), kLEScanFastWindow);
537 }
538
539 struct TestObject final {
TestObjectbt::gap::__anon5ab8b6cc0111::TestObject540 explicit TestObject(bool* d) : deleted(d) {
541 PW_DCHECK(deleted);
542 *deleted = false;
543 }
544
~TestObjectbt::gap::__anon5ab8b6cc0111::TestObject545 ~TestObject() { *deleted = true; }
546
547 bool* deleted;
548 };
549
TEST_F(LowEnergyConnectionManagerTest,DeleteRefInClosedCallback)550 TEST_F(LowEnergyConnectionManagerTest, DeleteRefInClosedCallback) {
551 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
552 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
553
554 bool deleted = false;
555 auto obj = std::make_shared<TestObject>(&deleted);
556 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
557 int closed_count = 0;
558 auto closed_cb = [&, obj = std::move(obj)] {
559 closed_count++;
560 conn_handle = nullptr;
561
562 // The object should remain alive for the duration of this callback.
563 EXPECT_FALSE(deleted);
564 };
565
566 auto success_cb = [&conn_handle, &closed_cb](auto result) {
567 ASSERT_EQ(fit::ok(), result);
568 conn_handle = std::move(result).value();
569 conn_handle->set_closed_callback(std::move(closed_cb));
570 };
571
572 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
573 RunUntilIdle();
574
575 ASSERT_TRUE(conn_handle);
576 ASSERT_TRUE(conn_handle->active());
577
578 // This will trigger the closed callback.
579 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
580 RunUntilIdle();
581
582 EXPECT_EQ(1, closed_count);
583 EXPECT_TRUE(connected_peers().empty());
584 EXPECT_FALSE(conn_handle);
585
586 // The object should be deleted.
587 EXPECT_TRUE(deleted);
588 }
589
TEST_F(LowEnergyConnectionManagerTest,ReleaseRef)590 TEST_F(LowEnergyConnectionManagerTest, ReleaseRef) {
591 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
592 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
593 test_device()->AddPeer(std::move(fake_peer));
594
595 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
596 auto callback = [&conn_handle](auto result) {
597 ASSERT_EQ(fit::ok(), result);
598 conn_handle = std::move(result).value();
599 EXPECT_TRUE(conn_handle->active());
600 };
601
602 EXPECT_TRUE(connected_peers().empty());
603 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
604
605 RunUntilIdle();
606
607 EXPECT_EQ(1u, connected_peers().size());
608 ASSERT_TRUE(peer->le());
609 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
610
611 ASSERT_TRUE(conn_handle);
612 conn_handle = nullptr;
613
614 RunUntilIdle();
615
616 EXPECT_TRUE(connected_peers().empty());
617 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
618 peer->le()->connection_state());
619 }
620
TEST_F(LowEnergyConnectionManagerTest,OnePeerTwoPendingRequestsBothFail)621 TEST_F(LowEnergyConnectionManagerTest, OnePeerTwoPendingRequestsBothFail) {
622 constexpr size_t kRequestCount = 2;
623
624 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
625 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
626 fake_peer->set_connect_response(
627 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
628 test_device()->AddPeer(std::move(fake_peer));
629
630 std::vector<ConnectionResult> results;
631
632 auto callback = [&results](auto result) {
633 results.push_back(std::move(result));
634 };
635
636 for (size_t i = 0; i < kRequestCount; ++i) {
637 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
638 }
639
640 RunUntilIdle();
641
642 EXPECT_EQ(kRequestCount, results.size());
643 for (size_t i = 0; i < results.size(); ++i) {
644 ASSERT_TRUE(results.at(i).is_error());
645 EXPECT_EQ(HostError::kFailed, results.at(i).error_value())
646 << "request count: " << i + 1;
647 }
648 }
649
TEST_F(LowEnergyConnectionManagerTest,OnePeerManyPendingRequests)650 TEST_F(LowEnergyConnectionManagerTest, OnePeerManyPendingRequests) {
651 constexpr size_t kRequestCount = 50;
652
653 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
654 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
655 test_device()->AddPeer(std::move(fake_peer));
656
657 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
658 auto callback = [&conn_handles](auto result) {
659 ASSERT_EQ(fit::ok(), result);
660 conn_handles.emplace_back(std::move(result).value());
661 };
662
663 for (size_t i = 0; i < kRequestCount; ++i) {
664 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
665 }
666
667 RunUntilIdle();
668
669 EXPECT_EQ(1u, connected_peers().size());
670 EXPECT_EQ(1u, connected_peers().count(kAddress0));
671
672 EXPECT_EQ(kRequestCount, conn_handles.size());
673 for (size_t i = 0; i < kRequestCount; ++i) {
674 ASSERT_TRUE(conn_handles[i]);
675 EXPECT_TRUE(conn_handles[i]->active());
676 EXPECT_EQ(peer->identifier(), conn_handles[i]->peer_identifier());
677 }
678
679 // Release one reference. The rest should be active.
680 conn_handles[0] = nullptr;
681 for (size_t i = 1; i < kRequestCount; ++i)
682 EXPECT_TRUE(conn_handles[i]->active());
683
684 // Release all but one reference.
685 for (size_t i = 1; i < kRequestCount - 1; ++i)
686 conn_handles[i] = nullptr;
687 EXPECT_TRUE(conn_handles[kRequestCount - 1]->active());
688
689 // Drop the last reference.
690 conn_handles[kRequestCount - 1] = nullptr;
691
692 RunUntilIdle();
693
694 EXPECT_TRUE(connected_peers().empty());
695 }
696
TEST_F(LowEnergyConnectionManagerTest,AddRefAfterConnection)697 TEST_F(LowEnergyConnectionManagerTest, AddRefAfterConnection) {
698 constexpr size_t kRefCount = 50;
699
700 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
701 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
702 test_device()->AddPeer(std::move(fake_peer));
703
704 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
705 auto callback = [&conn_handles](auto result) {
706 ASSERT_EQ(fit::ok(), result);
707 conn_handles.emplace_back(std::move(result).value());
708 };
709
710 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
711
712 RunUntilIdle();
713
714 EXPECT_EQ(1u, connected_peers().size());
715 EXPECT_EQ(1u, connected_peers().count(kAddress0));
716 EXPECT_EQ(1u, conn_handles.size());
717
718 // Add new references.
719 for (size_t i = 1; i < kRefCount; ++i) {
720 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
721 RunUntilIdle();
722 }
723
724 EXPECT_EQ(1u, connected_peers().size());
725 EXPECT_EQ(1u, connected_peers().count(kAddress0));
726 EXPECT_EQ(kRefCount, conn_handles.size());
727
728 // Disconnect.
729 conn_handles.clear();
730
731 RunUntilIdle();
732
733 EXPECT_TRUE(connected_peers().empty());
734 }
735
TEST_F(LowEnergyConnectionManagerTest,PendingRequestsOnTwoPeers)736 TEST_F(LowEnergyConnectionManagerTest, PendingRequestsOnTwoPeers) {
737 auto* peer0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
738 auto* peer1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
739
740 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
741 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
742
743 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
744 auto callback = [&conn_handles](auto result) {
745 ASSERT_EQ(fit::ok(), result);
746 conn_handles.emplace_back(std::move(result).value());
747 };
748
749 conn_mgr()->Connect(peer0->identifier(), callback, kConnectionOptions);
750 conn_mgr()->Connect(peer1->identifier(), callback, kConnectionOptions);
751
752 RunUntilIdle();
753
754 EXPECT_EQ(2u, connected_peers().size());
755 EXPECT_EQ(1u, connected_peers().count(kAddress0));
756 EXPECT_EQ(1u, connected_peers().count(kAddress1));
757
758 ASSERT_EQ(2u, conn_handles.size());
759 ASSERT_TRUE(conn_handles[0]);
760 ASSERT_TRUE(conn_handles[1]);
761 EXPECT_EQ(peer0->identifier(), conn_handles[0]->peer_identifier());
762 EXPECT_EQ(peer1->identifier(), conn_handles[1]->peer_identifier());
763
764 // |peer1| should disconnect first.
765 conn_handles[1] = nullptr;
766
767 RunUntilIdle();
768
769 EXPECT_EQ(1u, connected_peers().size());
770 EXPECT_EQ(1u, connected_peers().count(kAddress0));
771
772 conn_handles.clear();
773
774 RunUntilIdle();
775 EXPECT_TRUE(connected_peers().empty());
776 }
777
TEST_F(LowEnergyConnectionManagerTest,PendingRequestsOnTwoPeersOneFails)778 TEST_F(LowEnergyConnectionManagerTest, PendingRequestsOnTwoPeersOneFails) {
779 auto* peer0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
780 auto* peer1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
781
782 auto fake_peer0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
783 fake_peer0->set_connect_response(
784 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
785 test_device()->AddPeer(std::move(fake_peer0));
786 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
787
788 std::vector<ConnectionResult> conn_results;
789 auto callback = [&conn_results](auto result) {
790 conn_results.emplace_back(std::move(result));
791 };
792
793 conn_mgr()->Connect(peer0->identifier(), callback, kConnectionOptions);
794 conn_mgr()->Connect(peer1->identifier(), callback, kConnectionOptions);
795
796 RunUntilIdle();
797
798 EXPECT_EQ(1u, connected_peers().size());
799 EXPECT_EQ(1u, connected_peers().count(kAddress1));
800
801 ASSERT_EQ(2u, conn_results.size());
802 EXPECT_TRUE(conn_results[0].is_error());
803 ASSERT_EQ(fit::ok(), conn_results[1]);
804 EXPECT_EQ(peer1->identifier(), conn_results[1].value()->peer_identifier());
805
806 // Both connections should disconnect.
807 conn_results.clear();
808
809 RunUntilIdle();
810 EXPECT_TRUE(connected_peers().empty());
811 }
812
TEST_F(LowEnergyConnectionManagerTest,Destructor)813 TEST_F(LowEnergyConnectionManagerTest, Destructor) {
814 auto* peer0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
815 auto* peer1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
816
817 // Connecting to this peer will succeed.
818 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
819
820 // Connecting to this peer will remain pending.
821 auto pending_peer = std::make_unique<FakePeer>(kAddress1, dispatcher());
822 pending_peer->set_force_pending_connect(true);
823 test_device()->AddPeer(std::move(pending_peer));
824
825 // Below we create one connection and one pending request to have at the time
826 // of destruction.
827
828 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
829 auto success_cb = [&conn_handle](auto result) {
830 ASSERT_EQ(fit::ok(), result);
831 conn_handle = std::move(result).value();
832 };
833
834 conn_mgr()->Connect(peer0->identifier(), success_cb, kConnectionOptions);
835 RunUntilIdle();
836
837 ASSERT_TRUE(conn_handle);
838 bool conn_closed = false;
839 conn_handle->set_closed_callback([&conn_closed] { conn_closed = true; });
840
841 bool error_cb_called = false;
842 auto error_cb = [&error_cb_called](auto result) {
843 ASSERT_TRUE(result.is_error());
844 EXPECT_EQ(HostError::kCanceled, result.error_value());
845 error_cb_called = true;
846 };
847
848 // This will send an HCI command to the fake controller. We delete the
849 // connection manager before a connection event gets received which should
850 // cancel the connection.
851 conn_mgr()->Connect(peer1->identifier(), error_cb, kConnectionOptions);
852 RunUntilIdle();
853 EXPECT_FALSE(error_cb_called);
854
855 DeleteConnMgr();
856
857 RunUntilIdle();
858
859 EXPECT_TRUE(error_cb_called);
860 EXPECT_TRUE(conn_closed);
861 EXPECT_EQ(1u, canceled_peers().size());
862 EXPECT_EQ(1u, canceled_peers().count(kAddress1));
863 }
864
TEST_F(LowEnergyConnectionManagerTest,DisconnectPendingConnectionWhileAwaitingScanStart)865 TEST_F(LowEnergyConnectionManagerTest,
866 DisconnectPendingConnectionWhileAwaitingScanStart) {
867 auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
868 auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
869 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
870
871 int conn_cb_0_count = 0;
872 auto conn_cb_0 = [&](auto result) {
873 ASSERT_TRUE(result.is_error());
874 EXPECT_EQ(HostError::kCanceled, result.error_value());
875 EXPECT_EQ(peer_0->le()->connection_state(),
876 Peer::ConnectionState::kNotConnected);
877 conn_cb_0_count++;
878 };
879
880 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
881 auto conn_cb_1 = [&](auto result) {
882 ASSERT_EQ(fit::ok(), result);
883 conn_handle = std::move(result).value();
884 };
885
886 conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
887 conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
888 EXPECT_EQ(Peer::ConnectionState::kInitializing,
889 peer_0->le()->connection_state());
890 EXPECT_EQ(Peer::ConnectionState::kInitializing,
891 peer_1->le()->connection_state());
892
893 // Do NOT wait for scanning to start asynchronously before calling Disconnect
894 // synchronously. After peer_0's connection request is cancelled, peer_1's
895 // connection request should succeed.
896 EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
897 RunUntilIdle();
898 EXPECT_EQ(conn_cb_0_count, 1);
899 ASSERT_TRUE(conn_handle);
900 EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
901 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
902 peer_0->le()->connection_state());
903 EXPECT_EQ(Peer::ConnectionState::kConnected,
904 peer_1->le()->connection_state());
905 }
906
TEST_F(LowEnergyConnectionManagerTest,DisconnectPendingConnectionDuringScan)907 TEST_F(LowEnergyConnectionManagerTest, DisconnectPendingConnectionDuringScan) {
908 // Don't add FakePeer for peer_0 in order to stall during scanning.
909 auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
910 auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
911 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
912
913 int conn_cb_0_count = 0;
914 auto conn_cb_0 = [&](auto result) {
915 ASSERT_TRUE(result.is_error());
916 EXPECT_EQ(HostError::kCanceled, result.error_value());
917 EXPECT_EQ(peer_0->le()->connection_state(),
918 Peer::ConnectionState::kNotConnected);
919 conn_cb_0_count++;
920 };
921
922 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
923 auto conn_cb_1 = [&](auto result) {
924 ASSERT_EQ(fit::ok(), result);
925 conn_handle = std::move(result).value();
926 };
927
928 conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
929 conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
930
931 // Wait for scanning to start & OnScanStart callback to be called.
932 RunUntilIdle();
933 EXPECT_EQ(Peer::ConnectionState::kInitializing,
934 peer_0->le()->connection_state());
935 EXPECT_EQ(Peer::ConnectionState::kInitializing,
936 peer_1->le()->connection_state());
937
938 // After peer_0's connection request is cancelled, peer_1's connection request
939 // should succeed.
940 EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
941 RunUntilIdle();
942 EXPECT_EQ(conn_cb_0_count, 1);
943 ASSERT_TRUE(conn_handle);
944 EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
945 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
946 peer_0->le()->connection_state());
947 EXPECT_EQ(Peer::ConnectionState::kConnected,
948 peer_1->le()->connection_state());
949 }
950
TEST_F(LowEnergyConnectionManagerTest,LocalDisconnectWhileConnectorPending)951 TEST_F(LowEnergyConnectionManagerTest, LocalDisconnectWhileConnectorPending) {
952 auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
953 auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
954 fake_peer_0->set_force_pending_connect(true);
955 test_device()->AddPeer(std::move(fake_peer_0));
956
957 auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
958 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
959
960 int conn_cb_0_count = 0;
961 auto conn_cb_0 = [&](auto result) {
962 EXPECT_TRUE(result.is_error());
963 EXPECT_EQ(HostError::kCanceled, result.error_value());
964 conn_cb_0_count++;
965 };
966
967 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
968 auto conn_cb_1 = [&](auto result) {
969 ASSERT_EQ(fit::ok(), result);
970 conn_handle = std::move(result).value();
971 };
972
973 conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
974 conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
975 EXPECT_EQ(Peer::ConnectionState::kInitializing,
976 peer_0->le()->connection_state());
977 EXPECT_EQ(Peer::ConnectionState::kInitializing,
978 peer_1->le()->connection_state());
979
980 // Wait for peer_0 scanning to complete and kLECreateConnection command to be
981 // sent.
982 RunUntilIdle();
983
984 // After peer_0's connection request is cancelled, peer_1's connection request
985 // should succeed.
986 EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
987 RunUntilIdle();
988 EXPECT_EQ(conn_cb_0_count, 1);
989 ASSERT_TRUE(conn_handle);
990 EXPECT_EQ(conn_handle->peer_identifier(), peer_1->identifier());
991 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
992 peer_0->le()->connection_state());
993 EXPECT_EQ(Peer::ConnectionState::kConnected,
994 peer_1->le()->connection_state());
995 }
996
TEST_F(LowEnergyConnectionManagerTest,DisconnectQueuedPendingConnectionAndThenPendingConnectionWithPendingConnector)997 TEST_F(
998 LowEnergyConnectionManagerTest,
999 DisconnectQueuedPendingConnectionAndThenPendingConnectionWithPendingConnector) {
1000 auto peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1001 auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
1002 fake_peer_0->set_force_pending_connect(true);
1003 test_device()->AddPeer(std::move(fake_peer_0));
1004
1005 auto peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
1006 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
1007
1008 int conn_cb_0_count = 0;
1009 auto conn_cb_0 = [&](auto result) {
1010 ASSERT_TRUE(result.is_error());
1011 EXPECT_EQ(HostError::kCanceled, result.error_value());
1012 EXPECT_EQ(peer_0->le()->connection_state(),
1013 Peer::ConnectionState::kNotConnected);
1014 conn_cb_0_count++;
1015 };
1016
1017 int conn_cb_1_count = 0;
1018 auto conn_cb_1 = [&](auto result) {
1019 ASSERT_TRUE(result.is_error());
1020 EXPECT_EQ(HostError::kCanceled, result.error_value());
1021 EXPECT_EQ(peer_1->le()->connection_state(),
1022 Peer::ConnectionState::kNotConnected);
1023 conn_cb_1_count++;
1024 };
1025
1026 conn_mgr()->Connect(peer_0->identifier(), conn_cb_0, kConnectionOptions);
1027 conn_mgr()->Connect(peer_1->identifier(), conn_cb_1, kConnectionOptions);
1028 EXPECT_EQ(Peer::ConnectionState::kInitializing,
1029 peer_0->le()->connection_state());
1030 EXPECT_EQ(Peer::ConnectionState::kInitializing,
1031 peer_1->le()->connection_state());
1032
1033 EXPECT_TRUE(conn_mgr()->Disconnect(peer_1->identifier()));
1034 RunUntilIdle();
1035 EXPECT_EQ(conn_cb_0_count, 0);
1036 EXPECT_EQ(conn_cb_1_count, 1);
1037 EXPECT_EQ(Peer::ConnectionState::kInitializing,
1038 peer_0->le()->connection_state());
1039 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
1040 peer_1->le()->connection_state());
1041
1042 EXPECT_TRUE(conn_mgr()->Disconnect(peer_0->identifier()));
1043 RunUntilIdle();
1044 EXPECT_EQ(conn_cb_0_count, 1);
1045 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
1046 peer_0->le()->connection_state());
1047 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
1048 peer_1->le()->connection_state());
1049 }
1050
TEST_F(LowEnergyConnectionManagerTest,DisconnectUnknownPeer)1051 TEST_F(LowEnergyConnectionManagerTest, DisconnectUnknownPeer) {
1052 // Unknown peers are inherently "not connected."
1053 EXPECT_TRUE(conn_mgr()->Disconnect(PeerId(999)));
1054 }
1055
TEST_F(LowEnergyConnectionManagerTest,DisconnectUnconnectedPeer)1056 TEST_F(LowEnergyConnectionManagerTest, DisconnectUnconnectedPeer) {
1057 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1058 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1059
1060 // This returns true so long the peer is not connected.
1061 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1062 }
1063
TEST_F(LowEnergyConnectionManagerTest,Disconnect)1064 TEST_F(LowEnergyConnectionManagerTest, Disconnect) {
1065 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1066 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1067
1068 int closed_count = 0;
1069 auto closed_cb = [&closed_count] { closed_count++; };
1070
1071 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
1072 auto success_cb = [&conn_handles, &closed_cb](auto result) {
1073 ASSERT_EQ(fit::ok(), result);
1074 auto conn_handle = std::move(result).value();
1075 conn_handle->set_closed_callback(closed_cb);
1076 conn_handles.push_back(std::move(conn_handle));
1077 };
1078
1079 // Issue two connection refs.
1080 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1081 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1082
1083 RunUntilIdle();
1084
1085 ASSERT_EQ(2u, conn_handles.size());
1086
1087 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1088
1089 bool peer_removed = peer_cache()->RemoveDisconnectedPeer(peer->identifier());
1090 EXPECT_TRUE(peer_removed);
1091
1092 RunUntilIdle();
1093
1094 EXPECT_EQ(2, closed_count);
1095 EXPECT_TRUE(connected_peers().empty());
1096 EXPECT_TRUE(canceled_peers().empty());
1097
1098 // The central pause timeout handler should not run.
1099 RunFor(kLEConnectionPauseCentral);
1100 }
1101
TEST_F(LowEnergyConnectionManagerTest,IntentionalDisconnectDisablesAutoConnectBehavior)1102 TEST_F(LowEnergyConnectionManagerTest,
1103 IntentionalDisconnectDisablesAutoConnectBehavior) {
1104 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1105 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1106
1107 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
1108 auto success_cb = [&conn_handles](auto result) {
1109 ASSERT_EQ(fit::ok(), result);
1110 conn_handles.push_back(std::move(result).value());
1111 };
1112
1113 sm::PairingData data;
1114 data.peer_ltk = sm::LTK();
1115 data.local_ltk = sm::LTK();
1116 EXPECT_TRUE(peer_cache()->StoreLowEnergyBond(peer->identifier(), data));
1117
1118 // Issue connection ref.
1119 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1120 RunUntilIdle();
1121
1122 // Bonded peer should have auto-connection enabled.
1123 EXPECT_TRUE(peer->le()->should_auto_connect());
1124
1125 // Explicit disconnect should disable the auto-connection property.
1126 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1127 RunUntilIdle();
1128 EXPECT_FALSE(peer->le()->should_auto_connect());
1129
1130 // Intentional re-connection should re-enable the auto-connection property.
1131 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1132 RunUntilIdle();
1133 EXPECT_TRUE(peer->le()->should_auto_connect());
1134 }
1135
TEST_F(LowEnergyConnectionManagerTest,IncidentalDisconnectDoesNotAffectAutoConnectBehavior)1136 TEST_F(LowEnergyConnectionManagerTest,
1137 IncidentalDisconnectDoesNotAffectAutoConnectBehavior) {
1138 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1139 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1140
1141 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
1142 auto success_cb = [&conn_handles](auto result) {
1143 ASSERT_EQ(fit::ok(), result);
1144 conn_handles.push_back(std::move(result).value());
1145 };
1146
1147 sm::PairingData data;
1148 data.peer_ltk = sm::LTK();
1149 data.local_ltk = sm::LTK();
1150 EXPECT_TRUE(peer_cache()->StoreLowEnergyBond(peer->identifier(), data));
1151
1152 // Issue connection ref.
1153 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1154 RunUntilIdle();
1155
1156 // Bonded peer should have auto-connection enabled.
1157 EXPECT_TRUE(peer->le()->should_auto_connect());
1158
1159 // Incidental disconnect should NOT disable the auto-connection property.
1160 ASSERT_TRUE(conn_handles.size());
1161 conn_handles[0] = nullptr;
1162 RunUntilIdle();
1163 EXPECT_TRUE(peer->le()->should_auto_connect());
1164 }
1165
TEST_F(LowEnergyConnectionManagerTest,DisconnectThrice)1166 TEST_F(LowEnergyConnectionManagerTest, DisconnectThrice) {
1167 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1168 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1169
1170 int closed_count = 0;
1171 auto closed_cb = [&closed_count] { closed_count++; };
1172
1173 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1174 auto success_cb = [&closed_cb, &conn_handle](auto result) {
1175 ASSERT_EQ(fit::ok(), result);
1176 conn_handle = std::move(result).value();
1177 ASSERT_TRUE(conn_handle);
1178 conn_handle->set_closed_callback(closed_cb);
1179 };
1180
1181 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1182
1183 RunUntilIdle();
1184
1185 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1186
1187 // Try to disconnect again while the first disconnection is in progress.
1188 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1189
1190 RunUntilIdle();
1191
1192 // The single ref should get only one "closed" call.
1193 EXPECT_EQ(1, closed_count);
1194 EXPECT_TRUE(connected_peers().empty());
1195 EXPECT_TRUE(canceled_peers().empty());
1196
1197 // Try to disconnect once more, now that the link is gone.
1198 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1199 }
1200
1201 // Tests when a link is lost without explicitly disconnecting
TEST_F(LowEnergyConnectionManagerTest,DisconnectEvent)1202 TEST_F(LowEnergyConnectionManagerTest, DisconnectEvent) {
1203 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1204
1205 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1206
1207 int closed_count = 0;
1208 auto closed_cb = [&closed_count] { closed_count++; };
1209
1210 std::vector<std::unique_ptr<LowEnergyConnectionHandle>> conn_handles;
1211 auto success_cb = [&conn_handles, &closed_cb](auto result) {
1212 ASSERT_EQ(fit::ok(), result);
1213 auto conn_handle = std::move(result).value();
1214 conn_handle->set_closed_callback(closed_cb);
1215 conn_handles.push_back(std::move(conn_handle));
1216 };
1217
1218 // Issue two connection refs.
1219 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1220 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1221
1222 RunUntilIdle();
1223
1224 ASSERT_EQ(2u, conn_handles.size());
1225
1226 // This makes FakeController send us HCI Disconnection Complete events.
1227 test_device()->Disconnect(kAddress0);
1228
1229 RunUntilIdle();
1230
1231 EXPECT_EQ(2, closed_count);
1232 }
1233
TEST_F(LowEnergyConnectionManagerTest,DisconnectAfterRefsReleased)1234 TEST_F(LowEnergyConnectionManagerTest, DisconnectAfterRefsReleased) {
1235 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1236 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1237
1238 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1239 auto success_cb = [&conn_handle](auto result) {
1240 ASSERT_EQ(fit::ok(), result);
1241 conn_handle = std::move(result).value();
1242 };
1243
1244 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1245
1246 RunUntilIdle();
1247
1248 ASSERT_TRUE(conn_handle);
1249 conn_handle.reset();
1250
1251 // Try to disconnect while the zero-refs connection is being disconnected.
1252 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1253
1254 RunUntilIdle();
1255
1256 EXPECT_TRUE(connected_peers().empty());
1257 EXPECT_TRUE(canceled_peers().empty());
1258 }
1259
TEST_F(LowEnergyConnectionManagerTest,DisconnectAfterSecondConnectionRequestInvalidatesRefs)1260 TEST_F(LowEnergyConnectionManagerTest,
1261 DisconnectAfterSecondConnectionRequestInvalidatesRefs) {
1262 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1263 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1264
1265 std::unique_ptr<LowEnergyConnectionHandle> conn_handle_0;
1266 auto success_cb = [&conn_handle_0](auto result) {
1267 ASSERT_EQ(fit::ok(), result);
1268 conn_handle_0 = std::move(result).value();
1269 ASSERT_TRUE(conn_handle_0);
1270 EXPECT_TRUE(conn_handle_0->active());
1271 };
1272
1273 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1274 RunUntilIdle();
1275 ASSERT_TRUE(conn_handle_0);
1276 EXPECT_TRUE(conn_handle_0->active());
1277
1278 std::unique_ptr<LowEnergyConnectionHandle> conn_handle_1;
1279 auto ref_cb = [&conn_handle_1](auto result) {
1280 ASSERT_EQ(fit::ok(), result);
1281 conn_handle_1 = std::move(result).value();
1282 };
1283
1284 // Callback should be run synchronously with success status because connection
1285 // already exists.
1286 conn_mgr()->Connect(peer->identifier(), ref_cb, kConnectionOptions);
1287 EXPECT_TRUE(conn_handle_1);
1288 EXPECT_TRUE(conn_handle_1->active());
1289
1290 // This should invalidate the refs.
1291 EXPECT_TRUE(conn_mgr()->Disconnect(peer->identifier()));
1292 EXPECT_FALSE(conn_handle_1->active());
1293 EXPECT_FALSE(conn_handle_0->active());
1294
1295 RunUntilIdle();
1296 }
1297
1298 // This tests that a connection reference callback succeeds if a HCI
1299 // Disconnection Complete event is received for the corresponding ACL link
1300 // immediately after the callback gets run.
TEST_F(LowEnergyConnectionManagerTest,DisconnectCompleteEventAfterConnect)1301 TEST_F(LowEnergyConnectionManagerTest, DisconnectCompleteEventAfterConnect) {
1302 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1303 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1304
1305 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1306 auto success_cb = [&conn_handle](auto result) {
1307 ASSERT_EQ(fit::ok(), result);
1308 conn_handle = std::move(result).value();
1309 EXPECT_TRUE(conn_handle->active());
1310 };
1311
1312 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1313 RunUntilIdle();
1314 ASSERT_TRUE(conn_handle);
1315
1316 // Request a new reference. Disconnect the link before the reference is
1317 // received.
1318 size_t ref_cb_count = 0;
1319 auto ref_cb = [&ref_cb_count](auto result) {
1320 ref_cb_count++;
1321 EXPECT_EQ(fit::ok(), result);
1322 };
1323
1324 size_t disconn_cb_count = 0;
1325 auto disconn_cb =
1326 [this, ref_cb, peer, &disconn_cb_count, &ref_cb_count](auto) {
1327 disconn_cb_count++;
1328 // The link is gone but conn_mgr() hasn't updated the connection state
1329 // yet. The request to connect will attempt to add a new reference which
1330 // will succeed because ref_cb is called synchronously.
1331 EXPECT_EQ(0u, ref_cb_count);
1332 conn_mgr()->Connect(peer->identifier(), ref_cb, kConnectionOptions);
1333 EXPECT_EQ(1u, ref_cb_count);
1334 };
1335 conn_mgr()->SetDisconnectCallbackForTesting(disconn_cb);
1336
1337 test_device()->SendDisconnectionCompleteEvent(conn_handle->handle());
1338
1339 RunUntilIdle();
1340
1341 EXPECT_EQ(1u, ref_cb_count);
1342 EXPECT_EQ(1u, disconn_cb_count);
1343 }
1344
TEST_F(LowEnergyConnectionManagerTest,RemovePeerFromPeerCacheDuringDisconnection)1345 TEST_F(LowEnergyConnectionManagerTest,
1346 RemovePeerFromPeerCacheDuringDisconnection) {
1347 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1348 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1349
1350 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1351 auto success_cb = [&conn_handle](auto result) {
1352 ASSERT_EQ(fit::ok(), result);
1353 conn_handle = std::move(result).value();
1354 EXPECT_TRUE(conn_handle->active());
1355 };
1356
1357 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
1358 RunUntilIdle();
1359 ASSERT_TRUE(conn_handle);
1360
1361 // This should invalidate the ref that was bound to |ref_cb|.
1362 const PeerId id = peer->identifier();
1363 EXPECT_TRUE(conn_mgr()->Disconnect(id));
1364 ASSERT_FALSE(peer->le()->connected());
1365 EXPECT_FALSE(conn_handle->active());
1366
1367 EXPECT_TRUE(peer_cache()->RemoveDisconnectedPeer(id));
1368
1369 RunUntilIdle();
1370
1371 EXPECT_FALSE(peer_cache()->FindById(id));
1372 EXPECT_FALSE(peer_cache()->FindByAddress(kAddress0));
1373 }
1374
1375 // Listener receives remote initiated connection ref.
TEST_F(LowEnergyConnectionManagerTest,RegisterRemoteInitiatedLink)1376 TEST_F(LowEnergyConnectionManagerTest, RegisterRemoteInitiatedLink) {
1377 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1378
1379 // First create a fake incoming connection.
1380 test_device()->ConnectLowEnergy(kAddress0);
1381
1382 RunUntilIdle();
1383
1384 auto link = MoveLastRemoteInitiated();
1385 ASSERT_TRUE(link);
1386
1387 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1388 conn_mgr()->RegisterRemoteInitiatedLink(
1389 std::move(link), BondableMode::Bondable, [&](auto result) {
1390 ASSERT_EQ(fit::ok(), result);
1391 conn_handle = std::move(result).value();
1392 });
1393 // A Peer should now exist in the cache.
1394 auto* peer = peer_cache()->FindByAddress(kAddress0);
1395 EXPECT_EQ(peer->le()->connection_state(),
1396 Peer::ConnectionState::kInitializing);
1397
1398 RunUntilIdle();
1399
1400 ASSERT_TRUE(conn_handle);
1401 EXPECT_TRUE(conn_handle->active());
1402 ASSERT_TRUE(peer);
1403 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
1404 EXPECT_TRUE(peer->connected());
1405 EXPECT_TRUE(peer->le()->connected());
1406 EXPECT_TRUE(peer->version().has_value());
1407 EXPECT_TRUE(peer->le()->features().has_value());
1408
1409 conn_handle = nullptr;
1410
1411 RunUntilIdle();
1412 EXPECT_TRUE(connected_peers().empty());
1413 }
1414
TEST_F(LowEnergyConnectionManagerTest,RegisterRemoteInitiatedLinkDuringLocalInitiatedLinkConnecting)1415 TEST_F(LowEnergyConnectionManagerTest,
1416 RegisterRemoteInitiatedLinkDuringLocalInitiatedLinkConnecting) {
1417 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1418 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
1419 fake_peer->set_force_pending_connect(true);
1420 test_device()->AddPeer(std::move(fake_peer));
1421
1422 // Create a fake incoming connection.
1423 test_device()->ConnectLowEnergy(kAddress0);
1424 RunUntilIdle();
1425 auto link = MoveLastRemoteInitiated();
1426 ASSERT_TRUE(link);
1427
1428 // Create a pending outgoing connection.
1429 ConnectionResult result = fit::ok(nullptr);
1430 auto callback = [&result](auto res) { result = std::move(res); };
1431 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
1432
1433 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1434 conn_mgr()->RegisterRemoteInitiatedLink(
1435 std::move(link), BondableMode::Bondable, [&](auto result) {
1436 ASSERT_EQ(fit::ok(), result);
1437 conn_handle = std::move(result).value();
1438 });
1439 RunUntilIdle();
1440 ASSERT_TRUE(conn_handle);
1441
1442 // Local connector result handler should not crash when it finds that
1443 // connection to peer already exists.
1444 RunFor(kLECreateConnectionTimeout);
1445 // An error should be returned if the connection complete was incorrectly not
1446 // matched to the pending connection request (see fxbug.dev/42148050). In the
1447 // future it may make sense to return success because a link to the peer
1448 // already exists.
1449 ASSERT_TRUE(result.is_error());
1450 EXPECT_TRUE(peer->le()->connected());
1451 }
1452
TEST_F(LowEnergyConnectionManagerTest,RegisterRemoteInitiatedLinkDuringLocalInitiatedConnectionScanning)1453 TEST_F(LowEnergyConnectionManagerTest,
1454 RegisterRemoteInitiatedLinkDuringLocalInitiatedConnectionScanning) {
1455 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1456 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
1457 fake_peer->set_advertising_enabled(false);
1458 test_device()->AddPeer(std::move(fake_peer));
1459
1460 // Create a fake incoming connection.
1461 test_device()->ConnectLowEnergy(kAddress0);
1462 RunUntilIdle();
1463 auto link = MoveLastRemoteInitiated();
1464 ASSERT_TRUE(link);
1465
1466 // Create a pending outgoing connection.
1467 ConnectionResult result = fit::ok(nullptr);
1468 auto callback = [&result](auto res) { result = std::move(res); };
1469 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
1470
1471 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1472 conn_mgr()->RegisterRemoteInitiatedLink(
1473 std::move(link), BondableMode::Bondable, [&](auto result) {
1474 ASSERT_EQ(fit::ok(), result);
1475 conn_handle = std::move(result).value();
1476 });
1477 RunUntilIdle();
1478 ASSERT_TRUE(conn_handle);
1479
1480 // Local connector result handler should not crash when it finds that
1481 // connection to peer already exists.
1482 RunFor(kLEGeneralCepScanTimeout);
1483 ASSERT_TRUE(result.is_error());
1484 EXPECT_TRUE(peer->le()->connected());
1485 }
1486
1487 // Listener receives remote initiated connection ref for a known peer with the
1488 // same BR/EDR address.
TEST_F(LowEnergyConnectionManagerTest,IncomingConnectionUpgradesKnownBrEdrPeerToDualMode)1489 TEST_F(LowEnergyConnectionManagerTest,
1490 IncomingConnectionUpgradesKnownBrEdrPeerToDualMode) {
1491 Peer* peer = peer_cache()->NewPeer(kAddrAlias0, /*connectable=*/true);
1492 ASSERT_TRUE(peer);
1493 ASSERT_EQ(peer, peer_cache()->FindByAddress(kAddress0));
1494 ASSERT_EQ(TechnologyType::kClassic, peer->technology());
1495
1496 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1497
1498 // First create a fake incoming connection.
1499 test_device()->ConnectLowEnergy(kAddress0);
1500
1501 RunUntilIdle();
1502
1503 auto link = MoveLastRemoteInitiated();
1504 ASSERT_TRUE(link);
1505
1506 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1507 conn_mgr()->RegisterRemoteInitiatedLink(
1508 std::move(link), BondableMode::Bondable, [&conn_handle](auto result) {
1509 ASSERT_EQ(fit::ok(), result);
1510 conn_handle = std::move(result).value();
1511 });
1512 RunUntilIdle();
1513 ASSERT_TRUE(conn_handle);
1514
1515 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
1516 EXPECT_EQ(TechnologyType::kDualMode, peer->technology());
1517 }
1518
1519 // Successful connection to a peer whose address type is kBREDR.
1520 // TODO(fxbug.dev/42102158): This test will likely become obsolete when LE
1521 // connections are based on the presence of LowEnergyData in a Peer and no
1522 // address type enum exists.
TEST_F(LowEnergyConnectionManagerTest,ConnectAndDisconnectDualModeDeviceWithBrEdrAddress)1523 TEST_F(LowEnergyConnectionManagerTest,
1524 ConnectAndDisconnectDualModeDeviceWithBrEdrAddress) {
1525 Peer* peer = peer_cache()->NewPeer(kAddrAlias0, /*connectable=*/true);
1526 ASSERT_TRUE(peer);
1527 ASSERT_TRUE(peer->bredr());
1528
1529 peer->MutLe();
1530 ASSERT_EQ(TechnologyType::kDualMode, peer->technology());
1531 ASSERT_EQ(peer, peer_cache()->FindByAddress(kAddress0));
1532 ASSERT_EQ(DeviceAddress::Type::kBREDR, peer->address().type());
1533
1534 // Only the LE transport connects in this test, so only add an LE FakePeer to
1535 // FakeController.
1536 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1537
1538 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1539 auto callback = [&conn_handle](auto result) {
1540 ASSERT_EQ(fit::ok(), result);
1541 conn_handle = std::move(result).value();
1542 };
1543
1544 EXPECT_TRUE(connected_peers().empty());
1545 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
1546 EXPECT_EQ(Peer::ConnectionState::kInitializing,
1547 peer->le()->connection_state());
1548
1549 RunUntilIdle();
1550
1551 EXPECT_EQ(1u, connected_peers().size());
1552 EXPECT_EQ(1u, connected_peers().count(kAddress0));
1553
1554 ASSERT_TRUE(conn_handle);
1555 EXPECT_TRUE(conn_handle->active());
1556 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
1557 EXPECT_FALSE(peer->temporary());
1558 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
1559
1560 conn_handle = nullptr;
1561 RunUntilIdle();
1562 EXPECT_EQ(0u, connected_peers().size());
1563 }
1564
1565 // Tests that the central accepts the connection parameters that are sent from
1566 // a fake peripheral and eventually applies them to the link.
TEST_F(LowEnergyConnectionManagerTest,CentralAppliesL2capConnectionParameterUpdateRequestParams)1567 TEST_F(LowEnergyConnectionManagerTest,
1568 CentralAppliesL2capConnectionParameterUpdateRequestParams) {
1569 // Set up a fake peer and a connection over which to process the L2CAP
1570 // request.
1571 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1572 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1573 ASSERT_TRUE(peer);
1574
1575 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1576 auto conn_cb = [&conn_handle](auto result) {
1577 ASSERT_EQ(fit::ok(), result);
1578 conn_handle = std::move(result).value();
1579 };
1580 conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
1581
1582 RunUntilIdle();
1583 ASSERT_TRUE(conn_handle);
1584
1585 hci_spec::LEPreferredConnectionParameters preferred(
1586 hci_spec::kLEConnectionIntervalMin,
1587 hci_spec::kLEConnectionIntervalMax,
1588 hci_spec::kLEConnectionLatencyMax,
1589 hci_spec::kLEConnectionSupervisionTimeoutMax);
1590
1591 std::optional<hci_spec::LEConnectionParameters> actual;
1592
1593 auto conn_params_updated_cb = [&](const auto&, const auto& params) {
1594 actual = params;
1595 };
1596 test_device()->set_le_connection_parameters_callback(conn_params_updated_cb);
1597
1598 fake_l2cap()->TriggerLEConnectionParameterUpdate(conn_handle->handle(),
1599 preferred);
1600
1601 // These connection update events for the wrong handle should be ignored.
1602 // Send twice: once before the parameter request is processed, and once after
1603 // the request has been processed.
1604 hci_spec::LEConnectionParameters wrong_handle_conn_params(0, 1, 2);
1605 test_device()->SendLEConnectionUpdateCompleteSubevent(
1606 conn_handle->handle() + 1, wrong_handle_conn_params);
1607 RunUntilIdle();
1608
1609 test_device()->SendLEConnectionUpdateCompleteSubevent(
1610 conn_handle->handle() + 1, wrong_handle_conn_params);
1611
1612 RunUntilIdle();
1613
1614 ASSERT_TRUE(actual.has_value());
1615 ASSERT_TRUE(peer->le());
1616 EXPECT_EQ(preferred, *peer->le()->preferred_connection_parameters());
1617 EXPECT_EQ(actual.value(), *peer->le()->connection_parameters());
1618 }
1619
TEST_F(LowEnergyConnectionManagerTest,L2CAPSignalLinkError)1620 TEST_F(LowEnergyConnectionManagerTest, L2CAPSignalLinkError) {
1621 // Set up a fake peer and a connection over which to process the L2CAP
1622 // request.
1623 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1624 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1625 ASSERT_TRUE(peer);
1626
1627 l2cap::testing::FakeChannel::WeakPtr smp_chan;
1628 auto l2cap_chan_cb = [&smp_chan](auto chan) { smp_chan = chan; };
1629 fake_l2cap()->set_channel_callback(l2cap_chan_cb);
1630
1631 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1632 auto conn_cb = [&conn_handle](auto result) {
1633 ASSERT_EQ(fit::ok(), result);
1634 conn_handle = std::move(result).value();
1635 };
1636 conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
1637
1638 RunUntilIdle();
1639 ASSERT_TRUE(conn_handle);
1640 ASSERT_TRUE(smp_chan.is_alive());
1641 ASSERT_EQ(1u, connected_peers().size());
1642
1643 // Signaling a link error through the channel should disconnect the link.
1644 smp_chan->SignalLinkError();
1645
1646 RunUntilIdle();
1647 EXPECT_TRUE(connected_peers().empty());
1648 }
1649
TEST_F(LowEnergyConnectionManagerTest,AttBearerSignalsLinkError)1650 TEST_F(LowEnergyConnectionManagerTest, AttBearerSignalsLinkError) {
1651 // Set up a fake peer and a connection over which to process the L2CAP
1652 // request.
1653 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1654 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1655 ASSERT_TRUE(peer);
1656
1657 l2cap::testing::FakeChannel::WeakPtr att_chan;
1658 auto l2cap_chan_cb = [&att_chan](l2cap::testing::FakeChannel::WeakPtr chan) {
1659 if (chan->id() == l2cap::kATTChannelId) {
1660 att_chan = std::move(chan);
1661 }
1662 };
1663 fake_l2cap()->set_channel_callback(l2cap_chan_cb);
1664
1665 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1666 auto conn_cb = [&conn_handle](auto result) {
1667 ASSERT_EQ(fit::ok(), result);
1668 conn_handle = std::move(result).value();
1669 };
1670 conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
1671
1672 RunUntilIdle();
1673 ASSERT_TRUE(conn_handle);
1674 ASSERT_TRUE(att_chan.is_alive());
1675 ASSERT_EQ(1u, connected_peers().size());
1676
1677 // Receiving an invalid SDU should cause att::Bearer to signal a link error.
1678 DynamicByteBuffer too_large_att_sdu(att::kLEMaxMTU + 1);
1679 too_large_att_sdu.Fill(0x00);
1680 att_chan->Receive(too_large_att_sdu);
1681
1682 RunUntilIdle();
1683 ASSERT_FALSE(att_chan.is_alive());
1684 EXPECT_TRUE(connected_peers().empty());
1685 }
1686
TEST_F(LowEnergyConnectionManagerTest,OutboundConnectATTChannelActivateFails)1687 TEST_F(LowEnergyConnectionManagerTest, OutboundConnectATTChannelActivateFails) {
1688 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1689 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1690 ASSERT_TRUE(peer);
1691
1692 std::optional<l2cap::testing::FakeChannel::WeakPtr> att_chan;
1693 auto l2cap_chan_cb = [&att_chan](l2cap::testing::FakeChannel::WeakPtr chan) {
1694 if (chan->id() == l2cap::kATTChannelId) {
1695 // Cause att::Bearer construction/activation to fail.
1696 chan->set_activate_fails(true);
1697 att_chan = std::move(chan);
1698 }
1699 };
1700 fake_l2cap()->set_channel_callback(l2cap_chan_cb);
1701
1702 std::optional<LowEnergyConnectionManager::ConnectionResult> result;
1703 auto conn_cb = [&](LowEnergyConnectionManager::ConnectionResult cb_result) {
1704 result = std::move(cb_result);
1705 };
1706 conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
1707
1708 RunUntilIdle();
1709 ASSERT_TRUE(att_chan.has_value());
1710 // The link should have been closed due to the error, invalidating the
1711 // channel.
1712 EXPECT_FALSE(att_chan.value().is_alive());
1713 ASSERT_TRUE(result.has_value());
1714 EXPECT_EQ(HostError::kFailed, result->error_value());
1715 EXPECT_TRUE(connected_peers().empty());
1716 }
1717
TEST_F(LowEnergyConnectionManagerTest,InboundConnectionATTChannelActivateFails)1718 TEST_F(LowEnergyConnectionManagerTest,
1719 InboundConnectionATTChannelActivateFails) {
1720 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1721 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1722 ASSERT_TRUE(peer);
1723
1724 std::optional<l2cap::testing::FakeChannel::WeakPtr> att_chan;
1725 auto l2cap_chan_cb = [&att_chan](l2cap::testing::FakeChannel::WeakPtr chan) {
1726 if (chan->id() == l2cap::kATTChannelId) {
1727 // Cause att::Bearer construction/activation to fail.
1728 chan->set_activate_fails(true);
1729 att_chan = std::move(chan);
1730 }
1731 };
1732 fake_l2cap()->set_channel_callback(l2cap_chan_cb);
1733
1734 std::optional<LowEnergyConnectionManager::ConnectionResult> result;
1735 auto conn_cb = [&](LowEnergyConnectionManager::ConnectionResult cb_result) {
1736 result = std::move(cb_result);
1737 };
1738 test_device()->ConnectLowEnergy(kAddress0);
1739 RunUntilIdle();
1740 auto link = MoveLastRemoteInitiated();
1741 ASSERT_TRUE(link);
1742 conn_mgr()->RegisterRemoteInitiatedLink(
1743 std::move(link), BondableMode::Bondable, std::move(conn_cb));
1744
1745 RunUntilIdle();
1746 ASSERT_TRUE(att_chan.has_value());
1747 // The link should have been closed due to the error, invalidating the
1748 // channel.
1749 EXPECT_FALSE(att_chan.value().is_alive());
1750 ASSERT_TRUE(result.has_value());
1751 EXPECT_EQ(HostError::kFailed, result->error_value());
1752 EXPECT_TRUE(connected_peers().empty());
1753 }
1754
TEST_F(LowEnergyConnectionManagerTest,LinkErrorDuringInterrogation)1755 TEST_F(LowEnergyConnectionManagerTest, LinkErrorDuringInterrogation) {
1756 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
1757 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1758 ASSERT_TRUE(peer);
1759
1760 // Get an arbitrary channel in order to signal a link error.
1761 l2cap::testing::FakeChannel::WeakPtr chan;
1762 auto l2cap_chan_cb = [&chan](l2cap::testing::FakeChannel::WeakPtr cb_chan) {
1763 chan = std::move(cb_chan);
1764 };
1765 fake_l2cap()->set_channel_callback(l2cap_chan_cb);
1766
1767 // Cause interrogation to stall so that we can simulate a link error.
1768 fit::closure send_read_remote_features_rsp;
1769 test_device()->pause_responses_for_opcode(
1770 hci_spec::kLEReadRemoteFeatures, [&](fit::closure unpause) {
1771 send_read_remote_features_rsp = std::move(unpause);
1772 });
1773
1774 std::optional<LowEnergyConnectionManager::ConnectionResult> result;
1775 auto conn_cb = [&](LowEnergyConnectionManager::ConnectionResult cb_result) {
1776 result = std::move(cb_result);
1777 };
1778 conn_mgr()->Connect(peer->identifier(), conn_cb, kConnectionOptions);
1779
1780 RunUntilIdle();
1781 ASSERT_TRUE(chan.is_alive());
1782 fake_l2cap()->TriggerLinkError(chan->link_handle());
1783
1784 send_read_remote_features_rsp();
1785
1786 RunUntilIdle();
1787 ASSERT_TRUE(result.has_value());
1788 ASSERT_TRUE(result->is_error());
1789 EXPECT_EQ(HostError::kFailed, result->error_value());
1790 EXPECT_TRUE(connected_peers().empty());
1791 }
1792
TEST_F(LowEnergyConnectionManagerTest,PairUnconnectedPeer)1793 TEST_F(LowEnergyConnectionManagerTest, PairUnconnectedPeer) {
1794 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1795 EXPECT_TRUE(peer->temporary());
1796 ASSERT_EQ(peer_cache()->count(), 1u);
1797 uint count_cb_called = 0;
1798 auto cb = [&count_cb_called](sm::Result<> status) {
1799 EXPECT_EQ(ToResult(bt::HostError::kNotFound), status);
1800 count_cb_called++;
1801 };
1802 conn_mgr()->Pair(peer->identifier(),
1803 sm::SecurityLevel::kEncrypted,
1804 sm::BondableMode::Bondable,
1805 cb);
1806 ASSERT_EQ(count_cb_called, 1u);
1807 }
1808
TEST_F(LowEnergyConnectionManagerTest,PairWithBondableModes)1809 TEST_F(LowEnergyConnectionManagerTest, PairWithBondableModes) {
1810 // clang-format on
1811 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1812 EXPECT_TRUE(peer->temporary());
1813
1814 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
1815 test_device()->AddPeer(std::move(fake_peer));
1816
1817 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1818 auto callback = [&conn_handle](auto result) {
1819 ASSERT_EQ(fit::ok(), result);
1820 conn_handle = std::move(result).value();
1821 EXPECT_TRUE(conn_handle);
1822 EXPECT_TRUE(conn_handle->active());
1823 };
1824
1825 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
1826 ASSERT_TRUE(peer->le());
1827
1828 RunUntilIdle();
1829 TestSm::WeakPtr mock_sm = TestSmByHandle(conn_handle->handle());
1830 ASSERT_TRUE(mock_sm.is_alive());
1831
1832 ASSERT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
1833
1834 EXPECT_FALSE(mock_sm->last_requested_upgrade().has_value());
1835 conn_mgr()->Pair(peer->identifier(),
1836 sm::SecurityLevel::kEncrypted,
1837 sm::BondableMode::Bondable,
1838 [](sm::Result<>) {});
1839 RunUntilIdle();
1840
1841 EXPECT_EQ(BondableMode::Bondable, mock_sm->bondable_mode());
1842 EXPECT_EQ(sm::SecurityLevel::kEncrypted, mock_sm->last_requested_upgrade());
1843
1844 conn_mgr()->Pair(peer->identifier(),
1845 sm::SecurityLevel::kAuthenticated,
1846 sm::BondableMode::NonBondable,
1847 [](sm::Result<>) {});
1848 RunUntilIdle();
1849
1850 EXPECT_EQ(BondableMode::NonBondable, mock_sm->bondable_mode());
1851 EXPECT_EQ(sm::SecurityLevel::kAuthenticated,
1852 mock_sm->last_requested_upgrade());
1853 }
1854
TEST_F(LowEnergyConnectionManagerTest,ConnectAndDiscoverByServiceWithoutUUID)1855 TEST_F(LowEnergyConnectionManagerTest, ConnectAndDiscoverByServiceWithoutUUID) {
1856 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1857
1858 bool cb_called = false;
1859 auto expect_uuids = [&cb_called](PeerId, auto uuids) {
1860 ASSERT_TRUE(uuids.empty());
1861 cb_called = true;
1862 };
1863 fake_gatt()->SetInitializeClientCallback(expect_uuids);
1864
1865 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
1866 test_device()->AddPeer(std::move(fake_peer));
1867
1868 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1869 auto callback = [&conn_handle](auto result) {
1870 ASSERT_EQ(fit::ok(), result);
1871 conn_handle = std::move(result).value();
1872 EXPECT_TRUE(conn_handle);
1873 EXPECT_TRUE(conn_handle->active());
1874 };
1875
1876 LowEnergyConnectionOptions connection_options{.service_uuid = std::nullopt};
1877 conn_mgr()->Connect(peer->identifier(), callback, connection_options);
1878
1879 RunUntilIdle();
1880
1881 ASSERT_TRUE(cb_called);
1882 }
1883
TEST_F(LowEnergyConnectionManagerTest,ConnectAndDiscoverByServiceUuid)1884 TEST_F(LowEnergyConnectionManagerTest, ConnectAndDiscoverByServiceUuid) {
1885 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
1886
1887 UUID kConnectUuid({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15});
1888 std::array<UUID, 2> expected_uuids = {kConnectUuid, kGenericAccessService};
1889
1890 bool cb_called = false;
1891 auto expect_uuid = [&cb_called, expected_uuids](PeerId, auto uuids) {
1892 EXPECT_THAT(uuids, ::testing::UnorderedElementsAreArray(expected_uuids));
1893 cb_called = true;
1894 };
1895 fake_gatt()->SetInitializeClientCallback(expect_uuid);
1896
1897 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
1898 test_device()->AddPeer(std::move(fake_peer));
1899
1900 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
1901 auto callback = [&conn_handle](auto result) {
1902 ASSERT_EQ(fit::ok(), result);
1903 conn_handle = std::move(result).value();
1904 ASSERT_TRUE(conn_handle);
1905 EXPECT_TRUE(conn_handle->active());
1906 };
1907
1908 LowEnergyConnectionOptions connection_options{
1909 .service_uuid = std::optional(kConnectUuid)};
1910 conn_mgr()->Connect(peer->identifier(), callback, connection_options);
1911
1912 RunUntilIdle();
1913
1914 ASSERT_TRUE(cb_called);
1915 }
1916
1917 class ReadDeviceNameParameterizedFixture
1918 : public LowEnergyConnectionManagerTest,
1919 public ::testing::WithParamInterface<DynamicByteBuffer> {};
1920
TEST_P(ReadDeviceNameParameterizedFixture,ReadDeviceNameParameterized)1921 TEST_P(ReadDeviceNameParameterizedFixture, ReadDeviceNameParameterized) {
1922 Peer* peer = peer_cache()->NewPeer(kAddress0, true);
1923 std::unique_ptr<FakePeer> fake_peer =
1924 std::make_unique<FakePeer>(kAddress0, dispatcher());
1925 test_device()->AddPeer(std::move(fake_peer));
1926
1927 // Set up GAP service
1928 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
1929 /*start=*/0x0001,
1930 /*end=*/0x0009,
1931 kGenericAccessService);
1932 auto [remote_svc, service_client] =
1933 fake_gatt()->AddPeerService(peer->identifier(), service_data);
1934
1935 // Set up preferred connection parameters characteristic.
1936 att::Handle char_handle = 0x0002;
1937 att::Handle char_value_handle = 0x0003;
1938 gatt::CharacteristicData char_data(gatt::kRead,
1939 /*ext_props=*/std::nullopt,
1940 char_handle,
1941 char_value_handle,
1942 kDeviceNameCharacteristic);
1943 service_client->set_characteristics({char_data});
1944
1945 DynamicByteBuffer char_value = GetParam();
1946 service_client->set_read_request_callback(
1947 [char_value_handle, char_value](att::Handle handle, auto read_cb) {
1948 if (handle == char_value_handle) {
1949 read_cb(fit::ok(), char_value, /*maybe_truncated=*/false);
1950 }
1951 });
1952
1953 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
1954 auto callback =
1955 [&conn_ref](
1956 fit::result<HostError, std::unique_ptr<LowEnergyConnectionHandle>>
1957 result) {
1958 ASSERT_EQ(fit::ok(), result);
1959 conn_ref = std::move(result).value();
1960 };
1961
1962 conn_mgr()->Connect(
1963 peer->identifier(), callback, LowEnergyConnectionOptions());
1964
1965 RunUntilIdle();
1966 EXPECT_TRUE(conn_ref);
1967 ASSERT_TRUE(peer->name());
1968 EXPECT_EQ(peer->name_source(), Peer::NameSource::kGenericAccessService);
1969 std::string device_name = peer->name().value();
1970 EXPECT_EQ(device_name, "abc");
1971 }
1972
1973 StaticByteBuffer<3> b1{'a', 'b', 'c'};
1974 StaticByteBuffer<5> b2{'a', 'b', 'c', '\0', 'x'};
1975 INSTANTIATE_TEST_SUITE_P(ReadDeviceNameTest,
1976 ReadDeviceNameParameterizedFixture,
1977 ::testing::Values(DynamicByteBuffer(b1),
1978 DynamicByteBuffer(b2)));
1979
TEST_F(LowEnergyConnectionManagerTest,ReadDeviceNameLong)1980 TEST_F(LowEnergyConnectionManagerTest, ReadDeviceNameLong) {
1981 Peer* peer = peer_cache()->NewPeer(kAddress0, true);
1982 std::unique_ptr<FakePeer> fake_peer =
1983 std::make_unique<FakePeer>(kAddress0, dispatcher());
1984 test_device()->AddPeer(std::move(fake_peer));
1985
1986 // Set up GAP service
1987 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
1988 /*start=*/0x0001,
1989 /*end=*/0x0009,
1990 kGenericAccessService);
1991 auto [remote_svc, service_client] =
1992 fake_gatt()->AddPeerService(peer->identifier(), service_data);
1993
1994 // Set up preferred connection parameters characteristic.
1995 att::Handle char_handle = 0x0002;
1996 att::Handle char_value_handle = 0x0003;
1997 gatt::CharacteristicData char_data(gatt::kRead,
1998 /*ext_props=*/std::nullopt,
1999 char_handle,
2000 char_value_handle,
2001 kDeviceNameCharacteristic);
2002 service_client->set_characteristics({char_data});
2003
2004 // Max length read
2005 StaticByteBuffer<att::kMaxAttributeValueLength> char_value;
2006 char_value.Fill('a');
2007 service_client->set_read_request_callback(
2008 [char_value_handle, char_value](att::Handle handle, auto read_cb) {
2009 if (handle == char_value_handle) {
2010 read_cb(fit::ok(), char_value, /*maybe_truncated=*/false);
2011 }
2012 });
2013
2014 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2015 auto callback =
2016 [&conn_ref](
2017 fit::result<HostError, std::unique_ptr<LowEnergyConnectionHandle>>
2018 result) {
2019 ASSERT_EQ(fit::ok(), result);
2020 conn_ref = std::move(result).value();
2021 };
2022
2023 conn_mgr()->Connect(
2024 peer->identifier(), callback, LowEnergyConnectionOptions());
2025
2026 RunUntilIdle();
2027 EXPECT_TRUE(conn_ref);
2028 ASSERT_TRUE(peer->name());
2029 EXPECT_EQ(peer->name_source(), Peer::NameSource::kGenericAccessService);
2030 std::string device_name = peer->name().value();
2031 EXPECT_EQ(device_name, std::string(att::kMaxAttributeValueLength, 'a'));
2032 }
2033
TEST_F(LowEnergyConnectionManagerTest,ReadAppearance)2034 TEST_F(LowEnergyConnectionManagerTest, ReadAppearance) {
2035 Peer* peer = peer_cache()->NewPeer(kAddress0, true);
2036 std::unique_ptr<FakePeer> fake_peer =
2037 std::make_unique<FakePeer>(kAddress0, dispatcher());
2038 test_device()->AddPeer(std::move(fake_peer));
2039
2040 // Set up GAP service
2041 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
2042 /*start=*/0x0001,
2043 /*end=*/0x0009,
2044 kGenericAccessService);
2045 auto [remote_svc, service_client] =
2046 fake_gatt()->AddPeerService(peer->identifier(), service_data);
2047
2048 // Set up preferred connection parameters characteristic.
2049 att::Handle char_handle = 0x0002;
2050 att::Handle char_value_handle = 0x0003;
2051 gatt::CharacteristicData char_data(gatt::kRead,
2052 /*ext_props=*/std::nullopt,
2053 char_handle,
2054 char_value_handle,
2055 kAppearanceCharacteristic);
2056 service_client->set_characteristics({char_data});
2057 StaticByteBuffer char_value(0x01, 0x00);
2058 service_client->set_read_request_callback(
2059 [char_value_handle, char_value](att::Handle handle, auto read_cb) {
2060 if (handle == char_value_handle) {
2061 read_cb(fit::ok(), char_value, /*maybe_truncated=*/false);
2062 }
2063 });
2064
2065 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2066 auto callback =
2067 [&conn_ref](
2068 fit::result<HostError, std::unique_ptr<LowEnergyConnectionHandle>>
2069 result) {
2070 ASSERT_EQ(fit::ok(), result);
2071 conn_ref = std::move(result).value();
2072 };
2073
2074 conn_mgr()->Connect(
2075 peer->identifier(), callback, LowEnergyConnectionOptions());
2076
2077 RunUntilIdle();
2078 EXPECT_TRUE(conn_ref);
2079 ASSERT_TRUE(peer->appearance());
2080 uint16_t device_appearance = peer->appearance().value();
2081 EXPECT_EQ(device_appearance, 1u);
2082 }
2083
TEST_F(LowEnergyConnectionManagerTest,ReadAppearanceInvalidSize)2084 TEST_F(LowEnergyConnectionManagerTest, ReadAppearanceInvalidSize) {
2085 Peer* peer = peer_cache()->NewPeer(kAddress0, true);
2086 std::unique_ptr<FakePeer> fake_peer =
2087 std::make_unique<FakePeer>(kAddress0, dispatcher());
2088 test_device()->AddPeer(std::move(fake_peer));
2089
2090 // Set up GAP service
2091 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
2092 /*start=*/0x0001,
2093 /*end=*/0x0009,
2094 kGenericAccessService);
2095 auto [remote_svc, service_client] =
2096 fake_gatt()->AddPeerService(peer->identifier(), service_data);
2097
2098 // Set up preferred connection parameters characteristic.
2099 att::Handle char_handle = 0x0002;
2100 att::Handle char_value_handle = 0x0003;
2101 gatt::CharacteristicData char_data(gatt::kRead,
2102 /*ext_props=*/std::nullopt,
2103 char_handle,
2104 char_value_handle,
2105 kAppearanceCharacteristic);
2106 service_client->set_characteristics({char_data});
2107 StaticByteBuffer invalid_char_value(0x01); // too small
2108 service_client->set_read_request_callback(
2109 [char_value_handle, invalid_char_value](att::Handle handle,
2110 auto read_cb) {
2111 if (handle == char_value_handle) {
2112 read_cb(fit::ok(), invalid_char_value, /*maybe_truncated=*/false);
2113 }
2114 });
2115
2116 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2117 auto callback =
2118 [&conn_ref](
2119 fit::result<HostError, std::unique_ptr<LowEnergyConnectionHandle>>
2120 result) {
2121 ASSERT_EQ(fit::ok(), result);
2122 conn_ref = std::move(result).value();
2123 };
2124
2125 conn_mgr()->Connect(
2126 peer->identifier(), callback, LowEnergyConnectionOptions());
2127
2128 RunUntilIdle();
2129 EXPECT_TRUE(conn_ref);
2130 EXPECT_FALSE(peer->appearance());
2131 }
2132
TEST_F(LowEnergyConnectionManagerTest,ReadPeripheralPreferredConnectionParametersCharacteristicAndUpdateConnectionParameters)2133 TEST_F(
2134 LowEnergyConnectionManagerTest,
2135 ReadPeripheralPreferredConnectionParametersCharacteristicAndUpdateConnectionParameters) {
2136 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2137 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2138 test_device()->AddPeer(std::move(fake_peer));
2139
2140 // Set up GAP service
2141 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
2142 /*start=*/0x0001,
2143 /*end=*/0x0009,
2144 kGenericAccessService);
2145 auto [remote_svc, service_client] =
2146 fake_gatt()->AddPeerService(peer->identifier(), service_data);
2147
2148 // Set up preferred connection parameters characteristic.
2149 att::Handle char_handle = 0x0002;
2150 att::Handle char_value_handle = 0x0003;
2151 gatt::CharacteristicData char_data(
2152 gatt::kRead,
2153 /*ext_props=*/std::nullopt,
2154 char_handle,
2155 char_value_handle,
2156 kPeripheralPreferredConnectionParametersCharacteristic);
2157 service_client->set_characteristics({char_data});
2158
2159 // TODO(fxbug.dev/42074287): These parameters are invalid, but this test
2160 // passes because we fail to validate them before sending them to the
2161 // controller.
2162 StaticByteBuffer char_value(0x01,
2163 0x00, // min interval
2164 0x02,
2165 0x00, // max interval
2166 0x03,
2167 0x00, // max latency
2168 0x04,
2169 0x00); // supervision timeout
2170 service_client->set_read_request_callback(
2171 [char_value_handle, char_value](att::Handle handle, auto read_cb) {
2172 if (handle == char_value_handle) {
2173 read_cb(fit::ok(), char_value, /*maybe_truncated=*/false);
2174 }
2175 });
2176
2177 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2178 auto callback = [&conn_ref](auto result) {
2179 ASSERT_EQ(fit::ok(), result);
2180 conn_ref = std::move(result).value();
2181 };
2182
2183 conn_mgr()->Connect(
2184 peer->identifier(), callback, LowEnergyConnectionOptions());
2185
2186 RunUntilIdle();
2187 EXPECT_TRUE(conn_ref);
2188 ASSERT_TRUE(peer->le()->preferred_connection_parameters());
2189 auto params = peer->le()->preferred_connection_parameters().value();
2190 EXPECT_EQ(params.min_interval(), 1u);
2191 EXPECT_EQ(params.max_interval(), 2u);
2192 EXPECT_EQ(params.max_latency(), 3u);
2193 EXPECT_EQ(params.supervision_timeout(), 4u);
2194
2195 std::optional<hci_spec::LEConnectionParameters> conn_params;
2196 test_device()->set_le_connection_parameters_callback(
2197 [&](auto, auto parameters) { conn_params = parameters; });
2198
2199 RunFor(kLEConnectionPauseCentral);
2200 ASSERT_TRUE(conn_params.has_value());
2201 EXPECT_EQ(conn_params->interval(),
2202 1u); // FakeController will use min interval
2203 EXPECT_EQ(conn_params->latency(), 3u);
2204 EXPECT_EQ(conn_params->supervision_timeout(), 4u);
2205 }
2206
TEST_F(LowEnergyConnectionManagerTest,ReadPeripheralPreferredConnectionParametersCharacteristicInvalidValueSize)2207 TEST_F(
2208 LowEnergyConnectionManagerTest,
2209 ReadPeripheralPreferredConnectionParametersCharacteristicInvalidValueSize) {
2210 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2211 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2212 test_device()->AddPeer(std::move(fake_peer));
2213
2214 // Set up GAP service
2215 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
2216 /*start=*/0x0001,
2217 /*end=*/0x0003,
2218 kGenericAccessService);
2219 auto [remote_svc, service_client] =
2220 fake_gatt()->AddPeerService(peer->identifier(), service_data);
2221
2222 // Set up preferred connection parameters characteristic.
2223 att::Handle char_handle = 0x0002;
2224 att::Handle char_value_handle = 0x0003;
2225 gatt::CharacteristicData char_data(
2226 gatt::kRead,
2227 /*ext_props=*/std::nullopt,
2228 char_handle,
2229 char_value_handle,
2230 kPeripheralPreferredConnectionParametersCharacteristic);
2231 service_client->set_characteristics({char_data});
2232 StaticByteBuffer invalid_char_value(0x01); // too small
2233 service_client->set_read_request_callback(
2234 [char_value_handle, invalid_char_value](auto handle, auto read_cb) {
2235 if (handle == char_value_handle) {
2236 read_cb(fit::ok(), invalid_char_value, /*maybe_truncated=*/false);
2237 }
2238 });
2239
2240 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2241 auto callback = [&conn_ref](auto result) {
2242 ASSERT_EQ(fit::ok(), result);
2243 conn_ref = std::move(result).value();
2244 };
2245
2246 conn_mgr()->Connect(
2247 peer->identifier(), callback, LowEnergyConnectionOptions());
2248
2249 RunUntilIdle();
2250 EXPECT_TRUE(conn_ref);
2251 EXPECT_FALSE(peer->le()->preferred_connection_parameters());
2252 }
2253
TEST_F(LowEnergyConnectionManagerTest,GapServiceCharacteristicDiscoveryError)2254 TEST_F(LowEnergyConnectionManagerTest, GapServiceCharacteristicDiscoveryError) {
2255 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2256 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2257 test_device()->AddPeer(std::move(fake_peer));
2258
2259 // Set up GAP service
2260 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
2261 /*start=*/0x0001,
2262 /*end=*/0x0003,
2263 kGenericAccessService);
2264 auto [remote_svc, service_client] =
2265 fake_gatt()->AddPeerService(peer->identifier(), service_data);
2266
2267 // Set up preferred connection parameters characteristic.
2268 att::Handle char_handle = 0x0002;
2269 att::Handle char_value_handle = 0x0003;
2270 gatt::CharacteristicData char_data(
2271 gatt::kRead,
2272 /*ext_props=*/std::nullopt,
2273 char_handle,
2274 char_value_handle,
2275 kPeripheralPreferredConnectionParametersCharacteristic);
2276 service_client->set_characteristic_discovery_status(
2277 ToResult(att::ErrorCode::kReadNotPermitted));
2278
2279 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2280 auto callback = [&conn_ref](auto result) {
2281 ASSERT_EQ(fit::ok(), result);
2282 conn_ref = std::move(result).value();
2283 };
2284
2285 conn_mgr()->Connect(
2286 peer->identifier(), callback, LowEnergyConnectionOptions());
2287
2288 RunUntilIdle();
2289 EXPECT_TRUE(conn_ref);
2290 EXPECT_FALSE(peer->le()->preferred_connection_parameters());
2291 }
2292
TEST_F(LowEnergyConnectionManagerTest,GapServiceListServicesError)2293 TEST_F(LowEnergyConnectionManagerTest, GapServiceListServicesError) {
2294 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2295 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2296 test_device()->AddPeer(std::move(fake_peer));
2297
2298 fake_gatt()->set_list_services_status(ToResult(HostError::kFailed));
2299
2300 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2301 auto callback = [&conn_ref](auto result) {
2302 ASSERT_EQ(fit::ok(), result);
2303 conn_ref = std::move(result).value();
2304 };
2305
2306 conn_mgr()->Connect(
2307 peer->identifier(), callback, LowEnergyConnectionOptions());
2308
2309 RunUntilIdle();
2310 EXPECT_TRUE(conn_ref);
2311 EXPECT_FALSE(peer->le()->preferred_connection_parameters());
2312 }
2313
TEST_F(LowEnergyConnectionManagerTest,PeerGapServiceMissingConnectionParameterCharacteristic)2314 TEST_F(LowEnergyConnectionManagerTest,
2315 PeerGapServiceMissingConnectionParameterCharacteristic) {
2316 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2317 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2318 test_device()->AddPeer(std::move(fake_peer));
2319
2320 // Set up GAP service
2321 gatt::ServiceData service_data(gatt::ServiceKind::PRIMARY,
2322 /*start=*/0x0001,
2323 /*end=*/0x0003,
2324 kGenericAccessService);
2325 auto [remote_svc, service_client] =
2326 fake_gatt()->AddPeerService(peer->identifier(), service_data);
2327
2328 std::unique_ptr<LowEnergyConnectionHandle> conn_ref;
2329 auto callback = [&conn_ref](auto result) {
2330 ASSERT_EQ(fit::ok(), result);
2331 conn_ref = std::move(result).value();
2332 };
2333
2334 conn_mgr()->Connect(
2335 peer->identifier(), callback, LowEnergyConnectionOptions());
2336
2337 RunUntilIdle();
2338 EXPECT_TRUE(conn_ref);
2339 EXPECT_FALSE(peer->le()->preferred_connection_parameters());
2340 }
2341
2342 // Listener receives remote initiated connection ref.
TEST_F(LowEnergyConnectionManagerTest,PassBondableThroughRemoteInitiatedLink)2343 TEST_F(LowEnergyConnectionManagerTest, PassBondableThroughRemoteInitiatedLink) {
2344 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
2345
2346 // First create a fake incoming connection.
2347 test_device()->ConnectLowEnergy(kAddress0);
2348
2349 RunUntilIdle();
2350
2351 auto link = MoveLastRemoteInitiated();
2352 ASSERT_TRUE(link);
2353
2354 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2355 conn_mgr()->RegisterRemoteInitiatedLink(
2356 std::move(link), BondableMode::Bondable, [&conn_handle](auto result) {
2357 ASSERT_EQ(fit::ok(), result);
2358 conn_handle = std::move(result).value();
2359 });
2360 RunUntilIdle();
2361
2362 ASSERT_TRUE(conn_handle);
2363 EXPECT_TRUE(conn_handle->active());
2364 EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::Bondable);
2365 }
2366
TEST_F(LowEnergyConnectionManagerTest,PassNonBondableThroughRemoteInitiatedLink)2367 TEST_F(LowEnergyConnectionManagerTest,
2368 PassNonBondableThroughRemoteInitiatedLink) {
2369 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
2370
2371 // First create a fake incoming connection.
2372 test_device()->ConnectLowEnergy(kAddress0);
2373
2374 RunUntilIdle();
2375
2376 auto link = MoveLastRemoteInitiated();
2377 ASSERT_TRUE(link);
2378
2379 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2380 conn_mgr()->RegisterRemoteInitiatedLink(
2381 std::move(link), BondableMode::NonBondable, [&conn_handle](auto result) {
2382 ASSERT_EQ(fit::ok(), result);
2383 conn_handle = std::move(result).value();
2384 });
2385 RunUntilIdle();
2386
2387 ASSERT_TRUE(conn_handle);
2388 EXPECT_TRUE(conn_handle->active());
2389 EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::NonBondable);
2390 }
2391
2392 // Successful connection to single peer
TEST_F(LowEnergyConnectionManagerTest,PassBondableThroughConnect)2393 TEST_F(LowEnergyConnectionManagerTest, PassBondableThroughConnect) {
2394 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2395 EXPECT_TRUE(peer->temporary());
2396
2397 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2398 test_device()->AddPeer(std::move(fake_peer));
2399
2400 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2401 auto callback = [&conn_handle](auto result) {
2402 ASSERT_EQ(fit::ok(), result);
2403 conn_handle = std::move(result).value();
2404 ASSERT_TRUE(conn_handle);
2405 EXPECT_TRUE(conn_handle->active());
2406 };
2407
2408 EXPECT_TRUE(connected_peers().empty());
2409 conn_mgr()->Connect(
2410 peer->identifier(), callback, {.bondable_mode = BondableMode::Bondable});
2411
2412 RunUntilIdle();
2413
2414 ASSERT_TRUE(conn_handle);
2415 EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::Bondable);
2416 }
2417
2418 // Successful connection to single peer
TEST_F(LowEnergyConnectionManagerTest,PassNonBondableThroughConnect)2419 TEST_F(LowEnergyConnectionManagerTest, PassNonBondableThroughConnect) {
2420 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2421 EXPECT_TRUE(peer->temporary());
2422
2423 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2424 test_device()->AddPeer(std::move(fake_peer));
2425
2426 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2427 auto callback = [&conn_handle](auto result) {
2428 ASSERT_EQ(fit::ok(), result);
2429 conn_handle = std::move(result).value();
2430 ASSERT_TRUE(conn_handle);
2431 EXPECT_TRUE(conn_handle->active());
2432 };
2433
2434 EXPECT_TRUE(connected_peers().empty());
2435 conn_mgr()->Connect(peer->identifier(),
2436 callback,
2437 {.bondable_mode = BondableMode::NonBondable});
2438
2439 RunUntilIdle();
2440
2441 ASSERT_TRUE(conn_handle);
2442 EXPECT_EQ(conn_handle->bondable_mode(), BondableMode::NonBondable);
2443 }
2444
2445 // Tests that the connection manager cleans up its connection map correctly
2446 // following a disconnection due to encryption failure.
TEST_F(LowEnergyConnectionManagerTest,ConnectionCleanUpFollowingEncryptionFailure)2447 TEST_F(LowEnergyConnectionManagerTest,
2448 ConnectionCleanUpFollowingEncryptionFailure) {
2449 // Set up a connection.
2450 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2451 EXPECT_TRUE(peer->temporary());
2452
2453 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2454 test_device()->AddPeer(std::move(fake_peer));
2455
2456 std::unique_ptr<LowEnergyConnectionHandle> conn;
2457 conn_mgr()->Connect(
2458 peer->identifier(),
2459 [&](auto result) {
2460 ASSERT_EQ(fit::ok(), result);
2461 conn = std::move(result).value();
2462 },
2463 kConnectionOptions);
2464 RunUntilIdle();
2465 ASSERT_TRUE(conn);
2466
2467 hci_spec::ConnectionHandle handle = conn->handle();
2468 bool ref_cleaned_up = false;
2469 bool disconnected = false;
2470 conn->set_closed_callback([&] { ref_cleaned_up = true; });
2471 conn_mgr()->SetDisconnectCallbackForTesting(
2472 [&](hci_spec::ConnectionHandle cb_handle) {
2473 EXPECT_EQ(handle, cb_handle);
2474 disconnected = true;
2475 });
2476
2477 test_device()->SendEncryptionChangeEvent(
2478 handle,
2479 pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE,
2480 pw::bluetooth::emboss::EncryptionStatus::OFF);
2481 test_device()->SendDisconnectionCompleteEvent(handle);
2482 RunUntilIdle();
2483
2484 EXPECT_TRUE(ref_cleaned_up);
2485 EXPECT_TRUE(disconnected);
2486 }
2487
TEST_F(LowEnergyConnectionManagerTest,SuccessfulInterrogationSetsPeerVersionAndFeatures)2488 TEST_F(LowEnergyConnectionManagerTest,
2489 SuccessfulInterrogationSetsPeerVersionAndFeatures) {
2490 constexpr hci_spec::LESupportedFeatures kLEFeatures{static_cast<uint64_t>(
2491 hci_spec::LESupportedFeature::kConnectionParametersRequestProcedure)};
2492
2493 // Set up a connection.
2494 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2495 ASSERT_TRUE(peer->le());
2496
2497 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2498 fake_peer->set_le_features(kLEFeatures);
2499 test_device()->AddPeer(std::move(fake_peer));
2500
2501 std::unique_ptr<LowEnergyConnectionHandle> conn;
2502 conn_mgr()->Connect(
2503 peer->identifier(),
2504 [&](auto result) {
2505 ASSERT_EQ(fit::ok(), result);
2506 conn = std::move(result).value();
2507 },
2508 kConnectionOptions);
2509
2510 EXPECT_FALSE(peer->version().has_value());
2511 EXPECT_FALSE(peer->le()->features().has_value());
2512 RunUntilIdle();
2513 EXPECT_TRUE(conn);
2514 EXPECT_TRUE(peer->version().has_value());
2515 EXPECT_TRUE(peer->le()->features().has_value());
2516 EXPECT_EQ(kLEFeatures, peer->le()->features());
2517 EXPECT_FALSE(peer->temporary());
2518 }
2519
TEST_F(LowEnergyConnectionManagerTest,ConnectInterrogationFailure)2520 TEST_F(LowEnergyConnectionManagerTest, ConnectInterrogationFailure) {
2521 // Set up a connection.
2522 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2523 ASSERT_TRUE(peer->le());
2524
2525 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2526 test_device()->AddPeer(std::move(fake_peer));
2527
2528 std::optional<HostError> error;
2529 conn_mgr()->Connect(
2530 peer->identifier(),
2531 [&](auto result) {
2532 ASSERT_TRUE(result.is_error());
2533 error = result.error_value();
2534 },
2535 kConnectionOptions);
2536 ASSERT_FALSE(peer->le()->features().has_value());
2537
2538 // Remove fake peer so LE Read Remote Features command fails during
2539 // interrogation.
2540 test_device()->set_le_read_remote_features_callback(
2541 [this]() { test_device()->RemovePeer(kAddress0); });
2542
2543 RunUntilIdle();
2544 ASSERT_TRUE(error.has_value());
2545 EXPECT_FALSE(peer->connected());
2546 EXPECT_FALSE(peer->le()->connected());
2547 EXPECT_FALSE(peer->temporary());
2548 }
2549
TEST_F(LowEnergyConnectionManagerTest,RemoteInitiatedLinkInterrogationFailure)2550 TEST_F(LowEnergyConnectionManagerTest,
2551 RemoteInitiatedLinkInterrogationFailure) {
2552 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
2553
2554 // First create a fake incoming connection.
2555 test_device()->ConnectLowEnergy(kAddress0);
2556
2557 RunUntilIdle();
2558
2559 auto link = MoveLastRemoteInitiated();
2560 ASSERT_TRUE(link);
2561
2562 std::optional<HostError> error;
2563 conn_mgr()->RegisterRemoteInitiatedLink(
2564 std::move(link), BondableMode::Bondable, [&](auto result) {
2565 ASSERT_TRUE(result.is_error());
2566 error = result.error_value();
2567 });
2568
2569 // Remove fake peer so LE Read Remote Features command fails during
2570 // interrogation.
2571 test_device()->set_le_read_remote_features_callback(
2572 [this]() { test_device()->RemovePeer(kAddress0); });
2573
2574 RunUntilIdle();
2575 ASSERT_TRUE(error.has_value());
2576
2577 // A Peer should now exist in the cache.
2578 auto* peer = peer_cache()->FindByAddress(kAddress0);
2579 ASSERT_TRUE(peer);
2580 EXPECT_FALSE(peer->connected());
2581 EXPECT_FALSE(peer->le()->connected());
2582 EXPECT_FALSE(peer->temporary());
2583 }
2584
TEST_F(LowEnergyConnectionManagerTest,L2capRequestConnParamUpdateAfterInterrogation)2585 TEST_F(LowEnergyConnectionManagerTest,
2586 L2capRequestConnParamUpdateAfterInterrogation) {
2587 const hci_spec::LEPreferredConnectionParameters kConnParams(
2588 hci_spec::defaults::kLEConnectionIntervalMin,
2589 hci_spec::defaults::kLEConnectionIntervalMax,
2590 /*max_latency=*/0,
2591 hci_spec::defaults::kLESupervisionTimeout);
2592
2593 // Connection Parameter Update procedure NOT supported.
2594 constexpr hci_spec::LESupportedFeatures kLEFeatures{0};
2595 auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2596 peer->set_le_features(kLEFeatures);
2597 test_device()->AddPeer(std::move(peer));
2598
2599 // First create a fake incoming connection as peripheral.
2600 test_device()->ConnectLowEnergy(
2601 kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2602
2603 RunUntilIdle();
2604
2605 auto link = MoveLastRemoteInitiated();
2606 ASSERT_TRUE(link);
2607
2608 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2609 conn_mgr()->RegisterRemoteInitiatedLink(
2610 std::move(link), BondableMode::Bondable, [&](auto result) {
2611 ASSERT_EQ(fit::ok(), result);
2612 conn_handle = std::move(result).value();
2613 });
2614
2615 size_t l2cap_conn_param_update_count = 0;
2616 fake_l2cap()->set_connection_parameter_update_request_responder(
2617 [&](auto, auto params) {
2618 EXPECT_EQ(kConnParams, params);
2619 l2cap_conn_param_update_count++;
2620 return true;
2621 });
2622
2623 size_t hci_update_conn_param_count = 0;
2624 test_device()->set_le_connection_parameters_callback(
2625 [&](auto, auto) { hci_update_conn_param_count++; });
2626
2627 RunUntilIdle();
2628 ASSERT_TRUE(conn_handle);
2629 EXPECT_TRUE(conn_handle->active());
2630 EXPECT_EQ(0u, l2cap_conn_param_update_count);
2631 EXPECT_EQ(0u, hci_update_conn_param_count);
2632
2633 RunFor(kLEConnectionPausePeripheral);
2634 EXPECT_EQ(1u, l2cap_conn_param_update_count);
2635 EXPECT_EQ(0u, hci_update_conn_param_count);
2636 }
2637
2638 // Based on PTS L2CAP/LE/CPU/BV-01-C, in which the LE feature mask indicates
2639 // support for the Connection Parameter Request Procedure, but sending the
2640 // request results in a kUnsupportedRemoteFeature event status. PTS expects the
2641 // host to retry with a L2cap connection parameter request.
2642 //
2643 // Test that this behavior is followed for 2 concurrent connections in order to
2644 // ensure correct command/event handling.
TEST_F(LowEnergyConnectionManagerTest,PeripheralsRetryLLConnectionUpdateWithL2capRequest)2645 TEST_F(LowEnergyConnectionManagerTest,
2646 PeripheralsRetryLLConnectionUpdateWithL2capRequest) {
2647 auto peer0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
2648 auto peer1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
2649
2650 // Connection Parameter Update procedure supported by controller.
2651 constexpr hci_spec::LESupportedFeatures kLEFeatures{static_cast<uint64_t>(
2652 hci_spec::LESupportedFeature::kConnectionParametersRequestProcedure)};
2653
2654 peer0->set_le_features(kLEFeatures);
2655 peer1->set_le_features(kLEFeatures);
2656
2657 // Simulate host rejection by causing FakeController to set LE Connection
2658 // Update Complete status to kUnsupportedRemoteFeature, as PTS does.
2659 peer0->set_supports_ll_conn_update_procedure(false);
2660 peer1->set_supports_ll_conn_update_procedure(false);
2661
2662 test_device()->AddPeer(std::move(peer0));
2663 test_device()->AddPeer(std::move(peer1));
2664
2665 // First create fake incoming connections with local host as peripheral.
2666 test_device()->ConnectLowEnergy(
2667 kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2668 RunUntilIdle();
2669 auto link0 = MoveLastRemoteInitiated();
2670 ASSERT_TRUE(link0);
2671
2672 std::unique_ptr<LowEnergyConnectionHandle> conn_handle0;
2673 conn_mgr()->RegisterRemoteInitiatedLink(
2674 std::move(link0), BondableMode::Bondable, [&](auto result) {
2675 ASSERT_EQ(fit::ok(), result);
2676 conn_handle0 = std::move(result).value();
2677 });
2678
2679 test_device()->ConnectLowEnergy(
2680 kAddress1, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2681 RunUntilIdle();
2682 auto link1 = MoveLastRemoteInitiated();
2683 ASSERT_TRUE(link1);
2684
2685 std::unique_ptr<LowEnergyConnectionHandle> conn_handle1;
2686 conn_mgr()->RegisterRemoteInitiatedLink(
2687 std::move(link1), BondableMode::Bondable, [&](auto result) {
2688 ASSERT_EQ(fit::ok(), result);
2689 conn_handle1 = std::move(result).value();
2690 });
2691
2692 size_t l2cap_conn_param_update_count0 = 0;
2693 size_t l2cap_conn_param_update_count1 = 0;
2694 size_t hci_update_conn_param_count0 = 0;
2695 size_t hci_update_conn_param_count1 = 0;
2696
2697 fake_l2cap()->set_connection_parameter_update_request_responder(
2698 [&](auto handle, auto) {
2699 if (handle == conn_handle0->handle()) {
2700 l2cap_conn_param_update_count0++;
2701 // connection update commands should be sent before l2cap requests
2702 EXPECT_EQ(hci_update_conn_param_count0, 1u);
2703 } else if (handle == conn_handle1->handle()) {
2704 l2cap_conn_param_update_count1++;
2705 EXPECT_EQ(hci_update_conn_param_count1, 1u);
2706 } else {
2707 ADD_FAILURE();
2708 }
2709 return true;
2710 });
2711
2712 test_device()->set_le_connection_parameters_callback([&](auto address, auto) {
2713 if (address == kAddress0) {
2714 hci_update_conn_param_count0++;
2715 // l2cap requests should not be sent until after failed HCI connection
2716 // update commands
2717 EXPECT_EQ(l2cap_conn_param_update_count0, 0u);
2718 } else if (address == kAddress1) {
2719 hci_update_conn_param_count1++;
2720 EXPECT_EQ(l2cap_conn_param_update_count1, 0u);
2721 } else {
2722 ADD_FAILURE();
2723 }
2724 });
2725
2726 RunFor(kLEConnectionPausePeripheral);
2727 ASSERT_TRUE(conn_handle0);
2728 EXPECT_TRUE(conn_handle0->active());
2729 ASSERT_TRUE(conn_handle1);
2730 EXPECT_TRUE(conn_handle1->active());
2731
2732 EXPECT_EQ(conn_handle0->role(),
2733 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2734 EXPECT_EQ(conn_handle1->role(),
2735 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2736
2737 EXPECT_EQ(1u, hci_update_conn_param_count0);
2738 EXPECT_EQ(1u, l2cap_conn_param_update_count0);
2739 EXPECT_EQ(1u, hci_update_conn_param_count1);
2740 EXPECT_EQ(1u, l2cap_conn_param_update_count1);
2741
2742 // l2cap requests should not be sent on subsequent events
2743 test_device()->SendLEConnectionUpdateCompleteSubevent(
2744 conn_handle1->handle(),
2745 hci_spec::LEConnectionParameters(),
2746 pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
2747 RunUntilIdle();
2748 EXPECT_EQ(1u, l2cap_conn_param_update_count0);
2749 EXPECT_EQ(1u, l2cap_conn_param_update_count1);
2750 }
2751
2752 // Based on PTS L2CAP/LE/CPU/BV-01-C. When run twice, the controller caches the
2753 // LE Connection Update Complete kUnsupportedRemoteFeature status and returns it
2754 // directly in future LE Connection Update Command Status events. The host
2755 // should retry with the L2CAP Connection Parameter Update Request after
2756 // receiving this kUnsupportedRemoteFeature command status.
TEST_F(LowEnergyConnectionManagerTest,PeripheralSendsL2capConnParamReqAfterConnUpdateCommandStatusUnsupportedRemoteFeature)2757 TEST_F(
2758 LowEnergyConnectionManagerTest,
2759 PeripheralSendsL2capConnParamReqAfterConnUpdateCommandStatusUnsupportedRemoteFeature) {
2760 auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2761
2762 // Connection Parameter Update procedure supported by controller.
2763 constexpr hci_spec::LESupportedFeatures kLEFeatures{static_cast<uint64_t>(
2764 hci_spec::LESupportedFeature::kConnectionParametersRequestProcedure)};
2765 peer->set_le_features(kLEFeatures);
2766 test_device()->AddPeer(std::move(peer));
2767
2768 // First create a fake incoming connection with local host as peripheral.
2769 test_device()->ConnectLowEnergy(
2770 kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2771 RunUntilIdle();
2772
2773 auto link = MoveLastRemoteInitiated();
2774 ASSERT_TRUE(link);
2775
2776 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2777 conn_mgr()->RegisterRemoteInitiatedLink(
2778 std::move(link), BondableMode::Bondable, [&](auto result) {
2779 ASSERT_EQ(fit::ok(), result);
2780 conn_handle = std::move(result).value();
2781 });
2782
2783 size_t l2cap_conn_param_update_count = 0;
2784 size_t hci_update_conn_param_count = 0;
2785
2786 fake_l2cap()->set_connection_parameter_update_request_responder(
2787 [&](auto, auto) {
2788 l2cap_conn_param_update_count++;
2789 return true;
2790 });
2791
2792 test_device()->set_le_connection_parameters_callback(
2793 [&](auto, auto) { hci_update_conn_param_count++; });
2794
2795 test_device()->SetDefaultCommandStatus(
2796 hci_spec::kLEConnectionUpdate,
2797 pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
2798
2799 RunFor(kLEConnectionPausePeripheral);
2800 ASSERT_TRUE(conn_handle);
2801 EXPECT_TRUE(conn_handle->active());
2802 EXPECT_EQ(0u, hci_update_conn_param_count);
2803 EXPECT_EQ(1u, l2cap_conn_param_update_count);
2804
2805 test_device()->ClearDefaultCommandStatus(hci_spec::kLEConnectionUpdate);
2806
2807 // l2cap request should not be called on subsequent events
2808 test_device()->SendLEConnectionUpdateCompleteSubevent(
2809 conn_handle->handle(),
2810 hci_spec::LEConnectionParameters(),
2811 pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
2812
2813 RunUntilIdle();
2814 EXPECT_EQ(1u, l2cap_conn_param_update_count);
2815 }
2816
2817 // A peripheral should not attempt to handle the next LE Connection Update
2818 // Complete event if the status of the LE Connection Update command is not
2819 // success.
TEST_F(LowEnergyConnectionManagerTest,PeripheralDoesNotSendL2capConnParamReqAfterConnUpdateCommandStatusError)2820 TEST_F(
2821 LowEnergyConnectionManagerTest,
2822 PeripheralDoesNotSendL2capConnParamReqAfterConnUpdateCommandStatusError) {
2823 auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2824
2825 // Connection Parameter Update procedure supported by controller.
2826 constexpr hci_spec::LESupportedFeatures kLEFeatures{static_cast<uint64_t>(
2827 hci_spec::LESupportedFeature::kConnectionParametersRequestProcedure)};
2828 peer->set_le_features(kLEFeatures);
2829 test_device()->AddPeer(std::move(peer));
2830
2831 // First create a fake incoming connection with local host as peripheral.
2832 test_device()->ConnectLowEnergy(
2833 kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2834 RunUntilIdle();
2835
2836 auto link = MoveLastRemoteInitiated();
2837 ASSERT_TRUE(link);
2838
2839 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2840 conn_mgr()->RegisterRemoteInitiatedLink(
2841 std::move(link), BondableMode::Bondable, [&](auto result) {
2842 ASSERT_EQ(fit::ok(), result);
2843 conn_handle = std::move(result).value();
2844 });
2845
2846 size_t l2cap_conn_param_update_count = 0;
2847 size_t hci_update_conn_param_count = 0;
2848
2849 fake_l2cap()->set_connection_parameter_update_request_responder(
2850 [&](auto, auto) {
2851 l2cap_conn_param_update_count++;
2852 return true;
2853 });
2854
2855 test_device()->set_le_connection_parameters_callback(
2856 [&](auto, auto) { hci_update_conn_param_count++; });
2857
2858 test_device()->SetDefaultCommandStatus(
2859 hci_spec::kLEConnectionUpdate,
2860 pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR);
2861
2862 RunFor(kLEConnectionPausePeripheral);
2863 ASSERT_TRUE(conn_handle);
2864 EXPECT_TRUE(conn_handle->active());
2865 EXPECT_EQ(conn_handle->role(),
2866 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2867 EXPECT_EQ(0u, hci_update_conn_param_count);
2868 EXPECT_EQ(0u, l2cap_conn_param_update_count);
2869
2870 test_device()->ClearDefaultCommandStatus(hci_spec::kLEConnectionUpdate);
2871
2872 // l2cap request should not be called on subsequent events
2873 test_device()->SendLEConnectionUpdateCompleteSubevent(
2874 conn_handle->handle(),
2875 hci_spec::LEConnectionParameters(),
2876 pw::bluetooth::emboss::StatusCode::UNSUPPORTED_REMOTE_FEATURE);
2877
2878 RunUntilIdle();
2879 EXPECT_EQ(0u, l2cap_conn_param_update_count);
2880 }
2881
TEST_F(LowEnergyConnectionManagerTest,HciUpdateConnParamsAfterInterrogation)2882 TEST_F(LowEnergyConnectionManagerTest, HciUpdateConnParamsAfterInterrogation) {
2883 constexpr hci_spec::LESupportedFeatures kLEFeatures{static_cast<uint64_t>(
2884 hci_spec::LESupportedFeature::kConnectionParametersRequestProcedure)};
2885
2886 auto peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2887 peer->set_le_features(kLEFeatures);
2888 test_device()->AddPeer(std::move(peer));
2889
2890 // First create a fake incoming connection.
2891 test_device()->ConnectLowEnergy(
2892 kAddress0, pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2893
2894 RunUntilIdle();
2895
2896 auto link = MoveLastRemoteInitiated();
2897 ASSERT_TRUE(link);
2898
2899 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
2900 conn_mgr()->RegisterRemoteInitiatedLink(
2901 std::move(link), BondableMode::Bondable, [&](auto result) {
2902 ASSERT_EQ(fit::ok(), result);
2903 conn_handle = std::move(result).value();
2904 });
2905
2906 size_t l2cap_conn_param_update_count = 0;
2907 fake_l2cap()->set_connection_parameter_update_request_responder(
2908 [&](auto, const auto) {
2909 l2cap_conn_param_update_count++;
2910 return true;
2911 });
2912
2913 size_t hci_update_conn_param_count = 0;
2914 test_device()->set_le_connection_parameters_callback(
2915 [&](auto, const hci_spec::LEConnectionParameters& params) {
2916 // FakeController will pick an interval between min and max interval.
2917 EXPECT_TRUE(
2918 params.interval() >= hci_spec::defaults::kLEConnectionIntervalMin &&
2919 params.interval() <= hci_spec::defaults::kLEConnectionIntervalMax);
2920 EXPECT_EQ(0u, params.latency());
2921 EXPECT_EQ(hci_spec::defaults::kLESupervisionTimeout,
2922 params.supervision_timeout());
2923 hci_update_conn_param_count++;
2924 });
2925
2926 RunUntilIdle();
2927 ASSERT_TRUE(conn_handle);
2928 EXPECT_TRUE(conn_handle->active());
2929 EXPECT_EQ(conn_handle->role(),
2930 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
2931 EXPECT_EQ(0u, l2cap_conn_param_update_count);
2932 EXPECT_EQ(0u, hci_update_conn_param_count);
2933
2934 RunFor(kLEConnectionPausePeripheral);
2935 EXPECT_EQ(0u, l2cap_conn_param_update_count);
2936 EXPECT_EQ(1u, hci_update_conn_param_count);
2937 }
2938
TEST_F(LowEnergyConnectionManagerTest,CentralUpdatesConnectionParametersToDefaultsAfterInitialization)2939 TEST_F(LowEnergyConnectionManagerTest,
2940 CentralUpdatesConnectionParametersToDefaultsAfterInitialization) {
2941 // Set up a connection.
2942 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2943 ASSERT_TRUE(peer->le());
2944
2945 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
2946
2947 size_t hci_update_conn_param_count = 0;
2948 test_device()->set_le_connection_parameters_callback(
2949 [&](auto, const hci_spec::LEConnectionParameters& params) {
2950 // FakeController will pick an interval between min and max interval.
2951 EXPECT_TRUE(
2952 params.interval() >= hci_spec::defaults::kLEConnectionIntervalMin &&
2953 params.interval() <= hci_spec::defaults::kLEConnectionIntervalMax);
2954 EXPECT_EQ(0u, params.latency());
2955 EXPECT_EQ(hci_spec::defaults::kLESupervisionTimeout,
2956 params.supervision_timeout());
2957 hci_update_conn_param_count++;
2958 });
2959
2960 std::unique_ptr<LowEnergyConnectionHandle> conn;
2961 conn_mgr()->Connect(
2962 peer->identifier(),
2963 [&](auto result) {
2964 ASSERT_EQ(fit::ok(), result);
2965 conn = std::move(result).value();
2966 },
2967 kConnectionOptions);
2968
2969 RunUntilIdle();
2970 EXPECT_EQ(0u, hci_update_conn_param_count);
2971
2972 RunFor(kLEConnectionPauseCentral);
2973 EXPECT_EQ(1u, hci_update_conn_param_count);
2974 EXPECT_TRUE(conn);
2975 }
2976
TEST_F(LowEnergyConnectionManagerTest,ConnectCalledForPeerBeingInterrogated)2977 TEST_F(LowEnergyConnectionManagerTest, ConnectCalledForPeerBeingInterrogated) {
2978 // Set up a connection.
2979 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
2980 ASSERT_TRUE(peer->le());
2981
2982 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
2983 test_device()->AddPeer(std::move(fake_peer));
2984
2985 // Prevent remote features event from being received.
2986 test_device()->SetDefaultCommandStatus(
2987 hci_spec::kLEReadRemoteFeatures,
2988 pw::bluetooth::emboss::StatusCode::SUCCESS);
2989
2990 conn_mgr()->Connect(
2991 peer->identifier(),
2992 [&](auto result) { ASSERT_TRUE(result.is_error()); },
2993 kConnectionOptions);
2994
2995 RunUntilIdle();
2996 // Interrogation should not complete.
2997 EXPECT_FALSE(peer->le()->features().has_value());
2998
2999 // Connect to same peer again, before interrogation has completed.
3000 // No asserts should fail.
3001 conn_mgr()->Connect(
3002 peer->identifier(),
3003 [&](auto result) { ASSERT_TRUE(result.is_error()); },
3004 kConnectionOptions);
3005 RunUntilIdle();
3006 }
3007
3008 LowEnergyConnectionManager::ConnectionResultCallback
MakeConnectionResultCallback(std::unique_ptr<LowEnergyConnectionHandle> & conn_handle)3009 MakeConnectionResultCallback(
3010 std::unique_ptr<LowEnergyConnectionHandle>& conn_handle) {
3011 return [&conn_handle](auto result) {
3012 ASSERT_EQ(fit::ok(), result);
3013 conn_handle = std::move(result).value();
3014 EXPECT_TRUE(conn_handle);
3015 EXPECT_TRUE(conn_handle->active());
3016 };
3017 }
3018
3019 // Test that active connections not meeting the requirements for Secure
3020 // Connections Only mode are disconnected when the security mode is changed to
3021 // SC Only.
TEST_F(LowEnergyConnectionManagerTest,SecureConnectionsOnlyDisconnectsInsufficientSecurity)3022 TEST_F(LowEnergyConnectionManagerTest,
3023 SecureConnectionsOnlyDisconnectsInsufficientSecurity) {
3024 Peer* encrypted_peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3025 Peer* unencrypted_peer =
3026 peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
3027 Peer* secure_authenticated_peer =
3028 peer_cache()->NewPeer(kAddress3, /*connectable=*/true);
3029 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
3030 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
3031 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3, dispatcher()));
3032
3033 std::unique_ptr<LowEnergyConnectionHandle> unencrypted_conn_handle,
3034 encrypted_conn_handle, secure_authenticated_conn_handle;
3035 EXPECT_TRUE(connected_peers().empty());
3036 conn_mgr()->Connect(unencrypted_peer->identifier(),
3037 MakeConnectionResultCallback(unencrypted_conn_handle),
3038 kConnectionOptions);
3039 conn_mgr()->Connect(encrypted_peer->identifier(),
3040 MakeConnectionResultCallback(encrypted_conn_handle),
3041 kConnectionOptions);
3042 conn_mgr()->Connect(
3043 secure_authenticated_peer->identifier(),
3044 MakeConnectionResultCallback(secure_authenticated_conn_handle),
3045 kConnectionOptions);
3046 RunUntilIdle();
3047 std::function<void(sm::Result<>)> pair_cb = [](sm::Result<> s) {
3048 EXPECT_EQ(fit::ok(), s);
3049 };
3050 EXPECT_EQ(3u, connected_peers().size());
3051 ASSERT_TRUE(unencrypted_conn_handle);
3052 ASSERT_TRUE(encrypted_conn_handle);
3053 ASSERT_TRUE(secure_authenticated_conn_handle);
3054 EXPECT_TRUE(unencrypted_conn_handle->active());
3055 EXPECT_TRUE(secure_authenticated_conn_handle->active());
3056 EXPECT_TRUE(encrypted_conn_handle->active());
3057
3058 // "Pair" to the encrypted peers to get to the correct security level.
3059 conn_mgr()->Pair(encrypted_peer->identifier(),
3060 sm::SecurityLevel::kEncrypted,
3061 sm::BondableMode::Bondable,
3062 pair_cb);
3063 conn_mgr()->Pair(secure_authenticated_peer->identifier(),
3064 sm::SecurityLevel::kSecureAuthenticated,
3065 sm::BondableMode::Bondable,
3066 pair_cb);
3067 RunUntilIdle();
3068 EXPECT_EQ(sm::SecurityLevel::kNoSecurity,
3069 unencrypted_conn_handle->security().level());
3070 EXPECT_EQ(sm::SecurityLevel::kEncrypted,
3071 encrypted_conn_handle->security().level());
3072 EXPECT_EQ(sm::SecurityLevel::kSecureAuthenticated,
3073 secure_authenticated_conn_handle->security().level());
3074
3075 // Setting Secure Connections Only mode causes connections not allowed under
3076 // this mode to be disconnected (in this case, `encrypted_peer` is encrypted,
3077 // SC-generated, and with max encryption key size, but not authenticated).
3078 conn_mgr()->SetSecurityMode(LESecurityMode::SecureConnectionsOnly);
3079 RunUntilIdle();
3080 EXPECT_EQ(LESecurityMode::SecureConnectionsOnly, conn_mgr()->security_mode());
3081 EXPECT_EQ(2u, connected_peers().size());
3082 EXPECT_TRUE(unencrypted_conn_handle->active());
3083 EXPECT_TRUE(secure_authenticated_conn_handle->active());
3084 EXPECT_FALSE(encrypted_conn_handle->active());
3085 }
3086
3087 // Test that both existing and new peers pick up on a change to Secure
3088 // Connections Only mode.
TEST_F(LowEnergyConnectionManagerTest,SetSecureConnectionsOnlyModeWorks)3089 TEST_F(LowEnergyConnectionManagerTest, SetSecureConnectionsOnlyModeWorks) {
3090 // LE Connection Manager defaults to Mode 1.
3091 EXPECT_EQ(LESecurityMode::Mode1, conn_mgr()->security_mode());
3092
3093 // This peer will already be connected when we set LE Secure Connections Only
3094 // mode.
3095 Peer* existing_peer = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
3096 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress1, dispatcher()));
3097 std::unique_ptr<LowEnergyConnectionHandle> existing_conn_handle;
3098 RunUntilIdle();
3099
3100 conn_mgr()->Connect(existing_peer->identifier(),
3101 MakeConnectionResultCallback(existing_conn_handle),
3102 kConnectionOptions);
3103 RunUntilIdle();
3104 TestSm::WeakPtr existing_peer_sm =
3105 TestSmByHandle(existing_conn_handle->handle());
3106 ASSERT_TRUE(existing_peer_sm.is_alive());
3107 EXPECT_EQ(LESecurityMode::Mode1, existing_peer_sm->security_mode());
3108 EXPECT_EQ(1u, connected_peers().size());
3109
3110 conn_mgr()->SetSecurityMode(LESecurityMode::SecureConnectionsOnly);
3111 RunUntilIdle();
3112
3113 EXPECT_EQ(LESecurityMode::SecureConnectionsOnly,
3114 existing_peer_sm->security_mode());
3115
3116 // This peer is connected after setting LE Secure Connections Only mode.
3117 Peer* new_peer = peer_cache()->NewPeer(kAddress3, /*connectable=*/true);
3118 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress3, dispatcher()));
3119 std::unique_ptr<LowEnergyConnectionHandle> new_conn_handle;
3120
3121 conn_mgr()->Connect(new_peer->identifier(),
3122 MakeConnectionResultCallback(new_conn_handle),
3123 kConnectionOptions);
3124 RunUntilIdle();
3125 TestSm::WeakPtr new_peer_sm = TestSmByHandle(new_conn_handle->handle());
3126 ASSERT_TRUE(new_peer_sm.is_alive());
3127 EXPECT_EQ(2u, connected_peers().size());
3128
3129 EXPECT_EQ(LESecurityMode::SecureConnectionsOnly,
3130 new_peer_sm->security_mode());
3131 }
3132
TEST_F(LowEnergyConnectionManagerTest,ConnectAndInterrogateSecondPeerDuringInterrogationOfFirstPeer)3133 TEST_F(LowEnergyConnectionManagerTest,
3134 ConnectAndInterrogateSecondPeerDuringInterrogationOfFirstPeer) {
3135 auto* peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3136 ASSERT_TRUE(peer_0->le());
3137
3138 auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
3139 auto fake_peer_0_ptr = fake_peer_0.get();
3140 test_device()->AddPeer(std::move(fake_peer_0));
3141
3142 // Prevent remote features event from being received.
3143 test_device()->SetDefaultCommandStatus(
3144 hci_spec::kLEReadRemoteFeatures,
3145 pw::bluetooth::emboss::StatusCode::SUCCESS);
3146
3147 std::unique_ptr<LowEnergyConnectionHandle> conn_0;
3148 conn_mgr()->Connect(
3149 peer_0->identifier(),
3150 [&conn_0](auto result) {
3151 ASSERT_EQ(fit::ok(), result);
3152 conn_0 = std::move(result).value();
3153 ASSERT_TRUE(conn_0);
3154 },
3155 kConnectionOptions);
3156
3157 RunUntilIdle();
3158 // Interrogation should not complete.
3159 EXPECT_FALSE(peer_0->le()->connected());
3160 EXPECT_FALSE(conn_0);
3161
3162 auto* peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
3163 ASSERT_TRUE(peer_1->le());
3164
3165 auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
3166 auto fake_peer_1_ptr = fake_peer_1.get();
3167 test_device()->AddPeer(std::move(fake_peer_1));
3168
3169 // Connect to different peer, before interrogation has completed.
3170 std::unique_ptr<LowEnergyConnectionHandle> conn_1;
3171 conn_mgr()->Connect(
3172 peer_1->identifier(),
3173 [&conn_1](auto result) {
3174 ASSERT_EQ(fit::ok(), result);
3175 conn_1 = std::move(result).value();
3176 ASSERT_TRUE(conn_1);
3177 },
3178 kConnectionOptions);
3179 RunUntilIdle();
3180
3181 // Complete interrogation of peer_0
3182 ASSERT_FALSE(fake_peer_0_ptr->logical_links().empty());
3183 auto handle_0 = *fake_peer_0_ptr->logical_links().begin();
3184
3185 auto response = hci::EventPacket::New<
3186 pw::bluetooth::emboss::LEReadRemoteFeaturesCompleteSubeventWriter>(
3187 hci_spec::kLEMetaEventCode);
3188 auto view = response.view_t();
3189 view.le_meta_event().subevent_code().Write(
3190 hci_spec::kLEReadRemoteFeaturesCompleteSubeventCode);
3191 view.connection_handle().Write(handle_0);
3192 view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
3193 view.le_features().BackingStorage().WriteUInt(0u);
3194 test_device()->SendCommandChannelPacket(response.data());
3195 RunUntilIdle();
3196 EXPECT_TRUE(conn_0);
3197 EXPECT_TRUE(peer_0->le()->connected());
3198
3199 // Complete interrogation of peer_1
3200 ASSERT_FALSE(fake_peer_1_ptr->logical_links().empty());
3201 auto handle_1 = *fake_peer_0_ptr->logical_links().begin();
3202 view.connection_handle().Write(handle_1);
3203 test_device()->SendCommandChannelPacket(response.data());
3204 RunUntilIdle();
3205 EXPECT_TRUE(conn_1);
3206 EXPECT_TRUE(peer_1->le()->connected());
3207 }
3208
TEST_F(LowEnergyConnectionManagerTest,ConnectSecondPeerDuringInterrogationOfFirstPeer)3209 TEST_F(LowEnergyConnectionManagerTest,
3210 ConnectSecondPeerDuringInterrogationOfFirstPeer) {
3211 auto* peer_0 = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3212 ASSERT_TRUE(peer_0->le());
3213
3214 auto fake_peer_0 = std::make_unique<FakePeer>(kAddress0, dispatcher());
3215 auto fake_peer_0_ptr = fake_peer_0.get();
3216 test_device()->AddPeer(std::move(fake_peer_0));
3217
3218 // Prevent remote features event from being received.
3219 test_device()->SetDefaultCommandStatus(
3220 hci_spec::kLEReadRemoteFeatures,
3221 pw::bluetooth::emboss::StatusCode::SUCCESS);
3222
3223 std::unique_ptr<LowEnergyConnectionHandle> conn_0;
3224 conn_mgr()->Connect(
3225 peer_0->identifier(),
3226 [&](auto result) {
3227 ASSERT_EQ(fit::ok(), result);
3228 conn_0 = std::move(result).value();
3229 },
3230 kConnectionOptions);
3231
3232 RunUntilIdle();
3233 // Interrogation should not complete.
3234 EXPECT_FALSE(peer_0->le()->connected());
3235 EXPECT_FALSE(conn_0);
3236
3237 test_device()->ClearDefaultCommandStatus(hci_spec::kLEReadRemoteFeatures);
3238 // Stall connection complete for peer 1.
3239 test_device()->SetDefaultCommandStatus(
3240 hci_spec::kLECreateConnection,
3241 pw::bluetooth::emboss::StatusCode::SUCCESS);
3242
3243 auto* peer_1 = peer_cache()->NewPeer(kAddress1, /*connectable=*/true);
3244 ASSERT_TRUE(peer_1->le());
3245
3246 auto fake_peer_1 = std::make_unique<FakePeer>(kAddress1, dispatcher());
3247 test_device()->AddPeer(std::move(fake_peer_1));
3248
3249 // Connect to different peer, before interrogation has completed.
3250 conn_mgr()->Connect(
3251 peer_1->identifier(),
3252 [&](auto result) { EXPECT_TRUE(result.is_error()); },
3253 kConnectionOptions);
3254 RunUntilIdle();
3255
3256 // Complete interrogation of peer_0. No asserts should fail.
3257 ASSERT_FALSE(fake_peer_0_ptr->logical_links().empty());
3258 auto handle_0 = *fake_peer_0_ptr->logical_links().begin();
3259 auto response = hci::EventPacket::New<
3260 pw::bluetooth::emboss::LEReadRemoteFeaturesCompleteSubeventWriter>(
3261 hci_spec::kLEMetaEventCode);
3262 auto view = response.view_t();
3263 view.le_meta_event().subevent_code().Write(
3264 hci_spec::kLEReadRemoteFeaturesCompleteSubeventCode);
3265 view.connection_handle().Write(handle_0);
3266 view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
3267 view.le_features().BackingStorage().WriteUInt(0u);
3268 test_device()->SendCommandChannelPacket(response.data());
3269 RunUntilIdle();
3270 EXPECT_TRUE(conn_0);
3271 EXPECT_TRUE(peer_0->le()->connected());
3272 }
3273
TEST_F(LowEnergyConnectionManagerTest,SynchonousInterrogationAndNoCallbackRetainsConnectionRef)3274 TEST_F(LowEnergyConnectionManagerTest,
3275 SynchonousInterrogationAndNoCallbackRetainsConnectionRef) {
3276 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3277 ASSERT_TRUE(peer->le());
3278
3279 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3280 test_device()->AddPeer(std::move(fake_peer));
3281
3282 std::unique_ptr<LowEnergyConnectionHandle> conn;
3283 conn_mgr()->Connect(
3284 peer->identifier(),
3285 [&](auto result) {
3286 ASSERT_EQ(fit::ok(), result);
3287 conn = std::move(result).value();
3288 },
3289 kConnectionOptions);
3290
3291 RunUntilIdle();
3292 EXPECT_TRUE(peer->le()->connected());
3293 EXPECT_TRUE(conn);
3294
3295 // Disconnect
3296 conn = nullptr;
3297 RunUntilIdle();
3298
3299 // Second interrogation will complete synchronously because peer has already
3300 // been interrogated.
3301 bool conn_cb_called = false;
3302 conn_mgr()->Connect(
3303 peer->identifier(),
3304 [&](auto result) {
3305 conn_cb_called = true;
3306 EXPECT_EQ(fit::ok(), result);
3307 // Don't retain ref.
3308 },
3309 kConnectionOptions);
3310 // Wait for connect complete event.
3311 RunUntilIdle();
3312 EXPECT_TRUE(conn_cb_called);
3313 }
3314
TEST_F(LowEnergyConnectionManagerTest,AutoConnectSkipsScanning)3315 TEST_F(LowEnergyConnectionManagerTest, AutoConnectSkipsScanning) {
3316 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3317 EXPECT_TRUE(peer->temporary());
3318
3319 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3320 test_device()->AddPeer(std::move(fake_peer));
3321
3322 size_t scan_cb_count = 0;
3323 test_device()->set_scan_state_callback(
3324 [&scan_cb_count](bool) { scan_cb_count++; });
3325
3326 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
3327 auto callback = [&conn_handle](auto result) {
3328 ASSERT_EQ(fit::ok(), result);
3329 conn_handle = std::move(result).value();
3330 EXPECT_TRUE(conn_handle->active());
3331 };
3332
3333 EXPECT_TRUE(connected_peers().empty());
3334 LowEnergyConnectionOptions options{.auto_connect = true};
3335 conn_mgr()->Connect(peer->identifier(), callback, options);
3336 ASSERT_TRUE(peer->le());
3337 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3338 peer->le()->connection_state());
3339
3340 RunUntilIdle();
3341
3342 EXPECT_EQ(1u, connected_peers().size());
3343 EXPECT_EQ(1u, connected_peers().count(kAddress0));
3344
3345 ASSERT_TRUE(conn_handle);
3346 EXPECT_TRUE(conn_handle->active());
3347 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
3348 EXPECT_FALSE(peer->temporary());
3349 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
3350 EXPECT_EQ(scan_cb_count, 0u);
3351 }
3352
TEST_F(LowEnergyConnectionManagerTest,PeerDisconnectBeforeInterrogationCompletes)3353 TEST_F(LowEnergyConnectionManagerTest,
3354 PeerDisconnectBeforeInterrogationCompletes) {
3355 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3356 EXPECT_TRUE(peer->temporary());
3357
3358 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3359 auto fake_peer_ptr = fake_peer.get();
3360 test_device()->AddPeer(std::move(fake_peer));
3361
3362 // Cause interrogation to stall by not responding with a Read Remote Version
3363 // complete event.
3364 test_device()->SetDefaultCommandStatus(
3365 hci_spec::kReadRemoteVersionInfo,
3366 pw::bluetooth::emboss::StatusCode::SUCCESS);
3367
3368 int connect_count = 0;
3369 auto callback = [&connect_count](auto result) {
3370 ASSERT_TRUE(result.is_error());
3371 connect_count++;
3372 };
3373
3374 EXPECT_TRUE(connected_peers().empty());
3375 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3376 ASSERT_TRUE(peer->le());
3377 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3378 peer->le()->connection_state());
3379
3380 RunUntilIdle();
3381
3382 ASSERT_FALSE(fake_peer_ptr->logical_links().empty());
3383 auto handle = *fake_peer_ptr->logical_links().begin();
3384
3385 test_device()->Disconnect(peer->address());
3386
3387 RunUntilIdle();
3388
3389 // Complete interrogation so that callback gets called.
3390 auto response = hci::EventPacket::New<
3391 pw::bluetooth::emboss::ReadRemoteVersionInfoCompleteEventWriter>(
3392 hci_spec::kReadRemoteVersionInfoCompleteEventCode);
3393 auto view = response.view_t();
3394 view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
3395 view.connection_handle().Write(handle);
3396 test_device()->SendCommandChannelPacket(response.data());
3397
3398 RunUntilIdle();
3399 EXPECT_EQ(0u, connected_peers().size());
3400 EXPECT_EQ(1, connect_count);
3401 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3402 peer->le()->connection_state());
3403 }
3404
TEST_F(LowEnergyConnectionManagerTest,LocalDisconnectBeforeInterrogationCompletes)3405 TEST_F(LowEnergyConnectionManagerTest,
3406 LocalDisconnectBeforeInterrogationCompletes) {
3407 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3408 EXPECT_TRUE(peer->temporary());
3409
3410 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3411 auto fake_peer_ptr = fake_peer.get();
3412 test_device()->AddPeer(std::move(fake_peer));
3413
3414 // Cause interrogation to stall by not responding with a Read Remote Version
3415 // complete event.
3416 test_device()->SetDefaultCommandStatus(
3417 hci_spec::kReadRemoteVersionInfo,
3418 pw::bluetooth::emboss::StatusCode::SUCCESS);
3419
3420 int connect_count = 0;
3421 auto callback = [&connect_count](auto result) {
3422 ASSERT_TRUE(result.is_error());
3423 connect_count++;
3424 };
3425
3426 EXPECT_TRUE(connected_peers().empty());
3427 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3428 ASSERT_TRUE(peer->le());
3429 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3430 peer->le()->connection_state());
3431
3432 RunUntilIdle();
3433
3434 ASSERT_FALSE(fake_peer_ptr->logical_links().empty());
3435 auto handle = *fake_peer_ptr->logical_links().begin();
3436
3437 conn_mgr()->Disconnect(peer->identifier());
3438
3439 RunUntilIdle();
3440
3441 // Complete interrogation so that callback gets called.
3442 auto response = hci::EventPacket::New<
3443 pw::bluetooth::emboss::ReadRemoteVersionInfoCompleteEventWriter>(
3444 hci_spec::kReadRemoteVersionInfoCompleteEventCode);
3445 auto view = response.view_t();
3446 view.status().Write(pw::bluetooth::emboss::StatusCode::SUCCESS);
3447 view.connection_handle().Write(handle);
3448 test_device()->SendCommandChannelPacket(response.data());
3449
3450 RunUntilIdle();
3451 EXPECT_EQ(0u, connected_peers().size());
3452 EXPECT_EQ(1, connect_count);
3453 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3454 peer->le()->connection_state());
3455 }
3456
TEST_F(LowEnergyConnectionManagerTest,ConnectionFailedToBeEstablishedRetriesTwiceAndFails)3457 TEST_F(LowEnergyConnectionManagerTest,
3458 ConnectionFailedToBeEstablishedRetriesTwiceAndFails) {
3459 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3460 EXPECT_TRUE(peer->temporary());
3461
3462 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3463 test_device()->AddPeer(std::move(fake_peer));
3464
3465 size_t connected_count = 0;
3466 test_device()->set_connection_state_callback(
3467 [&](auto, auto, bool connected, bool) {
3468 if (connected) {
3469 connected_count++;
3470 }
3471 });
3472
3473 int connect_cb_count = 0;
3474 auto callback = [&connect_cb_count](auto result) {
3475 ASSERT_TRUE(result.is_error());
3476 connect_cb_count++;
3477 };
3478
3479 EXPECT_TRUE(connected_peers().empty());
3480
3481 // Cause interrogation to fail.
3482 test_device()->SetDefaultCommandStatus(
3483 hci_spec::kReadRemoteVersionInfo,
3484 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3485
3486 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3487 ASSERT_TRUE(peer->le());
3488 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3489 peer->le()->connection_state());
3490
3491 // Exhaust retries and cause connection to fail.
3492 for (size_t i = 0; i < kConnectDelays.size(); i++) {
3493 SCOPED_TRACE(i);
3494 if (i != 0) {
3495 RunFor(kConnectDelays[i] - std::chrono::nanoseconds(1));
3496 EXPECT_EQ(connected_count, i);
3497 RunFor(std::chrono::nanoseconds(1));
3498 } else {
3499 RunFor(kConnectDelays[i]);
3500 }
3501 EXPECT_EQ(connected_count, i + 1);
3502 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3503 peer->le()->connection_state());
3504
3505 test_device()->Disconnect(
3506 kAddress0,
3507 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3508 RunUntilIdle();
3509 EXPECT_EQ(connected_count, i + 1);
3510 // A connect command should be sent in connect_delays[i+1]
3511 }
3512
3513 RunUntilIdle();
3514 EXPECT_TRUE(connected_peers().empty());
3515 EXPECT_EQ(connect_cb_count, 1);
3516 EXPECT_FALSE(peer->temporary());
3517 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3518 peer->le()->connection_state());
3519 }
3520
TEST_F(LowEnergyConnectionManagerTest,ConnectionFailedToBeEstablishedRetriesAndSucceeds)3521 TEST_F(LowEnergyConnectionManagerTest,
3522 ConnectionFailedToBeEstablishedRetriesAndSucceeds) {
3523 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3524 EXPECT_TRUE(peer->temporary());
3525
3526 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3527 test_device()->AddPeer(std::move(fake_peer));
3528
3529 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
3530 auto callback = [&conn_handle](auto result) {
3531 ASSERT_EQ(fit::ok(), result);
3532 conn_handle = std::move(result).value();
3533 EXPECT_TRUE(conn_handle->active());
3534 };
3535
3536 EXPECT_TRUE(connected_peers().empty());
3537
3538 // Cause interrogation to fail.
3539 test_device()->SetDefaultCommandStatus(
3540 hci_spec::kReadRemoteVersionInfo,
3541 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3542
3543 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3544 ASSERT_TRUE(peer->le());
3545 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3546 peer->le()->connection_state());
3547
3548 RunUntilIdle();
3549 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3550 peer->le()->connection_state());
3551 EXPECT_FALSE(conn_handle);
3552
3553 // Allow the next interrogation to succeed.
3554 test_device()->ClearDefaultCommandStatus(hci_spec::kReadRemoteVersionInfo);
3555
3556 // Disconnect should initiate retry #2 after a pause.
3557 test_device()->Disconnect(
3558 kAddress0,
3559 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3560 RunFor(std::chrono::seconds(2));
3561 EXPECT_EQ(1u, connected_peers().size());
3562 EXPECT_EQ(1u, connected_peers().count(kAddress0));
3563 ASSERT_TRUE(conn_handle);
3564 EXPECT_TRUE(conn_handle->active());
3565 EXPECT_FALSE(peer->temporary());
3566 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
3567 }
3568
TEST_F(LowEnergyConnectionManagerTest,ConnectionFailedToBeEstablishedAndDisconnectDuringRetryPauseTimeout)3569 TEST_F(LowEnergyConnectionManagerTest,
3570 ConnectionFailedToBeEstablishedAndDisconnectDuringRetryPauseTimeout) {
3571 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3572 EXPECT_TRUE(peer->temporary());
3573
3574 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3575 test_device()->AddPeer(std::move(fake_peer));
3576
3577 int connect_cb_count = 0;
3578 auto callback = [&](auto result) {
3579 ASSERT_TRUE(result.is_error());
3580 EXPECT_EQ(HostError::kCanceled, result.error_value());
3581 connect_cb_count++;
3582 };
3583
3584 EXPECT_TRUE(connected_peers().empty());
3585
3586 // Cause interrogation to fail.
3587 test_device()->SetDefaultCommandStatus(
3588 hci_spec::kReadRemoteVersionInfo,
3589 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3590
3591 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3592 ASSERT_TRUE(peer->le());
3593 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3594 peer->le()->connection_state());
3595
3596 RunUntilIdle();
3597 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3598 peer->le()->connection_state());
3599 EXPECT_EQ(connect_cb_count, 0);
3600
3601 // Allow the next interrogation to succeed (even though it shouldn't happen).
3602 test_device()->ClearDefaultCommandStatus(hci_spec::kReadRemoteVersionInfo);
3603
3604 // Peer disconnection during interrogation should also cause retry (after a
3605 // pause)
3606 test_device()->Disconnect(
3607 kAddress0,
3608 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3609 RunUntilIdle();
3610 // Disconnect will cancel request.
3611 conn_mgr()->Disconnect(peer->identifier());
3612 // Ensure timer is canceled.
3613 // TODO(saeedali): run repeatedly?
3614 // RunLoopRepeatedlyFor(std::chrono::seconds(1));
3615 RunFor(std::chrono::seconds(1));
3616 EXPECT_EQ(connect_cb_count, 1);
3617 EXPECT_EQ(0u, connected_peers().size());
3618 EXPECT_FALSE(peer->temporary());
3619 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3620 peer->le()->connection_state());
3621 }
3622
3623 // Tests that receiving a peer kConnectionFailedToBeEstablished disconnect event
3624 // before interrogation fails does not crash.
TEST_F(LowEnergyConnectionManagerTest,ConnectionFailedToBeEstablishedDisconnectionBeforeInterrogationFails)3625 TEST_F(LowEnergyConnectionManagerTest,
3626 ConnectionFailedToBeEstablishedDisconnectionBeforeInterrogationFails) {
3627 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3628 EXPECT_TRUE(peer->temporary());
3629
3630 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3631 test_device()->AddPeer(std::move(fake_peer));
3632
3633 int connect_cb_count = 0;
3634 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
3635 auto callback = [&](auto result) {
3636 ASSERT_EQ(fit::ok(), result);
3637 connect_cb_count++;
3638 conn_handle = std::move(result).value();
3639 };
3640
3641 EXPECT_TRUE(connected_peers().empty());
3642
3643 // Cause interrogation to stall waiting for command complete event.
3644 test_device()->SetDefaultCommandStatus(
3645 hci_spec::kReadRemoteVersionInfo,
3646 pw::bluetooth::emboss::StatusCode::SUCCESS);
3647
3648 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3649 ASSERT_TRUE(peer->le());
3650 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3651 peer->le()->connection_state());
3652
3653 RunUntilIdle();
3654 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3655 peer->le()->connection_state());
3656 EXPECT_EQ(connect_cb_count, 0);
3657
3658 // Let retries succeed.
3659 test_device()->ClearDefaultCommandStatus(hci_spec::kReadRemoteVersionInfo);
3660
3661 // Peer disconnection during interrogation should also cause retry (after a
3662 // pause).
3663 test_device()->Disconnect(
3664 kAddress0,
3665 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
3666 RunUntilIdle();
3667
3668 // Complete interrogation with an error that will be received after the
3669 // disconnect event. Event params other than status will be ignored because
3670 // status is an error.
3671 auto response = hci::EventPacket::New<
3672 pw::bluetooth::emboss::ReadRemoteVersionInfoCompleteEventWriter>(
3673 hci_spec::kReadRemoteVersionInfoCompleteEventCode);
3674 auto view = response.view_t();
3675 view.status().Write(pw::bluetooth::emboss::StatusCode::UNKNOWN_CONNECTION_ID);
3676 test_device()->SendCommandChannelPacket(response.data());
3677
3678 RunUntilIdle();
3679 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3680 peer->le()->connection_state());
3681 EXPECT_EQ(connect_cb_count, 0);
3682
3683 // Wait for retry.
3684 RunFor(kConnectDelays[1]);
3685 EXPECT_EQ(connect_cb_count, 1);
3686 EXPECT_TRUE(conn_handle);
3687 EXPECT_EQ(1u, connected_peers().size());
3688 EXPECT_FALSE(peer->temporary());
3689 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
3690 }
3691
3692 // Behavior verified in this test:
3693 // 1. After a successful connection + bond to establish auto-connect for a peer,
3694 // an auto-connect-
3695 // initiated connection attempt to that peer that fails with any of
3696 // `statuses_that_disable_ autoconnect` disables auto-connect to that peer.
3697 // 2. After a successful ..., NON-autoconnect-inititated connection attempts
3698 // (inbound or outbound)
3699 // to that peer that fail with any of `statuses_that_disable_autoconnect` do
3700 // NOT disable auto- connect to that peer.
TEST_F(LowEnergyConnectionManagerTest,ConnectSucceedsThenAutoConnectFailsDisablesAutoConnect)3701 TEST_F(LowEnergyConnectionManagerTest,
3702 ConnectSucceedsThenAutoConnectFailsDisablesAutoConnect) {
3703 // If an auto-connect attempt fails with any of these status codes, we disable
3704 // the auto-connect behavior until the next successful connection to avoid
3705 // looping.
3706 // clang-format off
3707 std::array statuses_that_disable_autoconnect = {
3708 pw::bluetooth::emboss::StatusCode::CONNECTION_TIMEOUT,
3709 pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_SECURITY,
3710 pw::bluetooth::emboss::StatusCode::CONNECTION_ACCEPT_TIMEOUT_EXCEEDED,
3711 pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST,
3712 pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED
3713 };
3714 // clang-format on
3715 // Validate that looping with a uint8_t is safe, it makes the rest of the code
3716 // simpler.
3717 static_assert(statuses_that_disable_autoconnect.size() <
3718 std::numeric_limits<uint8_t>::max());
3719 for (uint8_t i = 0;
3720 i < static_cast<uint8_t>(statuses_that_disable_autoconnect.size());
3721 ++i) {
3722 SCOPED_TRACE(
3723 hci_spec::StatusCodeToString(statuses_that_disable_autoconnect[i]));
3724 const DeviceAddress kAddressI(DeviceAddress::Type::kLEPublic, {i});
3725 auto* peer = peer_cache()->NewPeer(kAddressI, /*connectable=*/true);
3726 auto fake_peer = std::make_unique<FakePeer>(kAddressI, dispatcher());
3727 test_device()->AddPeer(std::move(fake_peer));
3728
3729 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
3730 auto success_cb = [&conn_handle](auto result) {
3731 ASSERT_EQ(fit::ok(), result);
3732 conn_handle = std::move(result).value();
3733 EXPECT_TRUE(conn_handle->active());
3734 };
3735
3736 conn_mgr()->Connect(peer->identifier(), success_cb, kConnectionOptions);
3737 RunUntilIdle();
3738 // Peer needs to be bonded to set auto connect
3739 peer->MutLe().SetBondData(sm::PairingData{});
3740
3741 EXPECT_EQ(1u, connected_peers().count(kAddressI));
3742 ASSERT_TRUE(conn_handle);
3743 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
3744 EXPECT_TRUE(peer->le()->should_auto_connect());
3745 EXPECT_EQ(Peer::ConnectionState::kConnected,
3746 peer->le()->connection_state());
3747
3748 // Disconnect has to be initiated by the "remote" device - locally initiated
3749 // disconnects will unset auto connect behavior.
3750 test_device()->Disconnect(peer->address());
3751
3752 RunUntilIdle();
3753
3754 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3755 peer->le()->connection_state());
3756 EXPECT_TRUE(peer->le()->should_auto_connect());
3757
3758 // Causes interrogation to fail, so inbound connections will fail to
3759 // establish. This complexity is needed because inbound connections are
3760 // already HCI-connected when passed to the LECM.
3761 test_device()->SetDefaultCommandStatus(
3762 hci_spec::kReadRemoteVersionInfo, statuses_that_disable_autoconnect[i]);
3763
3764 ConnectionResult result = fit::ok(nullptr);
3765 auto failure_cb = [&result](auto res) { result = std::move(res); };
3766 // Create an inbound HCI connection and try to register it with the LECM
3767 test_device()->ConnectLowEnergy(kAddressI);
3768 RunUntilIdle();
3769 auto link = MoveLastRemoteInitiated();
3770 ASSERT_TRUE(link);
3771 result = fit::ok(nullptr);
3772 conn_mgr()->RegisterRemoteInitiatedLink(
3773 std::move(link), BondableMode::Bondable, failure_cb);
3774 RunUntilIdle();
3775 // We always wait until the peer disconnects to relay connection failure
3776 // when dealing with the 0x3e kConnectionFailedToBeEstablished error.
3777 if (statuses_that_disable_autoconnect[i] ==
3778 pw::bluetooth::emboss::StatusCode::
3779 CONNECTION_FAILED_TO_BE_ESTABLISHED) {
3780 test_device()->Disconnect(kAddressI,
3781 pw::bluetooth::emboss::StatusCode::
3782 CONNECTION_FAILED_TO_BE_ESTABLISHED);
3783 RunUntilIdle();
3784 }
3785 // Remote-initiated connection attempts that fail should not disable the
3786 // auto-connect flag.
3787 ASSERT_TRUE(result.is_error());
3788 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3789 peer->le()->connection_state());
3790 EXPECT_TRUE(peer->le()->should_auto_connect());
3791 // Allow successful interrogation later in the test
3792 test_device()->ClearDefaultCommandStatus(hci_spec::kReadRemoteVersionInfo);
3793
3794 // Set this peer to reject all connections with
3795 // statuses_that_disable_autoconnect[i]
3796 FakePeer* peer_ref = test_device()->FindPeer(peer->address());
3797 ASSERT_TRUE(peer);
3798 peer_ref->set_connect_response(statuses_that_disable_autoconnect[i]);
3799
3800 // User-initiated connection attempts that fail should not disable the
3801 // auto-connect flag.
3802 const LowEnergyConnectionOptions kNotAutoConnectOptions{.auto_connect =
3803 false};
3804 conn_mgr()->Connect(peer->identifier(), failure_cb, kNotAutoConnectOptions);
3805 RunUntilIdle();
3806
3807 ASSERT_TRUE(result.is_error());
3808 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3809 peer->le()->connection_state());
3810 EXPECT_TRUE(peer->le()->should_auto_connect());
3811
3812 // Emulate an auto-connection here, as we disable the auto-connect behavior
3813 // only for auto-connect-initiated attempts that fail, NOT for
3814 // user-initiated or remote-initiated connection attempts that fail.
3815 result = fit::ok(nullptr);
3816 const LowEnergyConnectionOptions kAutoConnectOptions{.auto_connect = true};
3817 conn_mgr()->Connect(peer->identifier(), failure_cb, kAutoConnectOptions);
3818 ASSERT_TRUE(peer->le());
3819 EXPECT_EQ(Peer::ConnectionState::kInitializing,
3820 peer->le()->connection_state());
3821
3822 RunUntilIdle();
3823
3824 ASSERT_TRUE(result.is_error());
3825 EXPECT_EQ(Peer::ConnectionState::kNotConnected,
3826 peer->le()->connection_state());
3827 EXPECT_FALSE(peer->le()->should_auto_connect());
3828 }
3829 }
3830
3831 #ifndef NINSPECT
TEST_F(LowEnergyConnectionManagerTest,Inspect)3832 TEST_F(LowEnergyConnectionManagerTest, Inspect) {
3833 inspect::Inspector inspector;
3834 conn_mgr()->AttachInspect(inspector.GetRoot(),
3835 "low_energy_connection_manager");
3836
3837 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3838 EXPECT_TRUE(peer->temporary());
3839
3840 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3841 test_device()->AddPeer(std::move(fake_peer));
3842
3843 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
3844 auto callback = [&conn_handle](auto result) {
3845 ASSERT_EQ(fit::ok(), result);
3846 conn_handle = std::move(result).value();
3847 };
3848 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3849
3850 auto requests_matcher =
3851 AllOf(NodeMatches(NameMatches("pending_requests")),
3852 ChildrenMatch(ElementsAre(NodeMatches(
3853 AllOf(NameMatches("pending_request_0x0"),
3854 PropertyList(UnorderedElementsAre(
3855 StringIs("peer_id", peer->identifier().ToString()),
3856 IntIs("callbacks", 1))))))));
3857
3858 auto outbound_connector_matcher_attempt_0 = AllOf(
3859 NodeMatches(AllOf(NameMatches("outbound_connector"),
3860 PropertyList(UnorderedElementsAre(
3861 StringIs("peer_id", peer->identifier().ToString()),
3862 IntIs("connection_attempt", 0),
3863 BoolIs("is_outbound", true),
3864 StringIs("state", "Connecting"))))));
3865
3866 auto empty_connections_matcher =
3867 AllOf(NodeMatches(NameMatches("connections")),
3868 ChildrenMatch(::testing::IsEmpty()));
3869
3870 auto conn_mgr_property_matcher = PropertyList(
3871 UnorderedElementsAre(UintIs("disconnect_explicit_disconnect_count", 0),
3872 UintIs("disconnect_link_error_count", 0),
3873 UintIs("disconnect_remote_disconnection_count", 0),
3874 UintIs("disconnect_zero_ref_count", 0),
3875 UintIs("incoming_connection_failure_count", 0),
3876 UintIs("incoming_connection_success_count", 0),
3877 UintIs("outgoing_connection_failure_count", 0),
3878 UintIs("outgoing_connection_success_count", 0),
3879 IntIs("recent_connection_failures", 0)));
3880
3881 auto conn_mgr_during_connecting_matcher =
3882 AllOf(NodeMatches(AllOf(NameMatches("low_energy_connection_manager"),
3883 conn_mgr_property_matcher)),
3884 ChildrenMatch(
3885 UnorderedElementsAre(requests_matcher,
3886 empty_connections_matcher,
3887 outbound_connector_matcher_attempt_0)));
3888
3889 auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
3890 EXPECT_THAT(hierarchy.value(),
3891 ChildrenMatch(ElementsAre(conn_mgr_during_connecting_matcher)));
3892
3893 // Finish connecting.
3894 RunUntilIdle();
3895
3896 auto empty_requests_matcher =
3897 AllOf(NodeMatches(NameMatches("pending_requests")),
3898 ChildrenMatch(::testing::IsEmpty()));
3899
3900 auto conn_matcher = NodeMatches(
3901 AllOf(NameMatches("connection_0x1"),
3902 PropertyList(UnorderedElementsAre(
3903 StringIs("peer_id", peer->identifier().ToString()),
3904 StringIs("peer_address", peer->address().ToString()),
3905 IntIs("ref_count", 1)))));
3906
3907 auto connections_matcher = AllOf(NodeMatches(NameMatches("connections")),
3908 ChildrenMatch(ElementsAre(conn_matcher)));
3909
3910 auto conn_mgr_property_matcher_after_connecting = PropertyList(
3911 UnorderedElementsAre(UintIs("disconnect_explicit_disconnect_count", 0),
3912 UintIs("disconnect_link_error_count", 0),
3913 UintIs("disconnect_remote_disconnection_count", 0),
3914 UintIs("disconnect_zero_ref_count", 0),
3915 UintIs("incoming_connection_failure_count", 0),
3916 UintIs("incoming_connection_success_count", 0),
3917 UintIs("outgoing_connection_failure_count", 0),
3918 UintIs("outgoing_connection_success_count", 1),
3919 IntIs("recent_connection_failures", 0)));
3920
3921 auto conn_mgr_after_connecting_matcher =
3922 AllOf(NodeMatches(conn_mgr_property_matcher_after_connecting),
3923 ChildrenMatch(UnorderedElementsAre(empty_requests_matcher,
3924 connections_matcher)));
3925
3926 hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
3927 EXPECT_THAT(hierarchy.value(),
3928 ChildrenMatch(ElementsAre(conn_mgr_after_connecting_matcher)));
3929
3930 // LECM must be destroyed before the inspector to avoid a page fault on
3931 // destruction of inspect properties (they try to update the inspect VMO,
3932 // which is deleted on inspector destruction).
3933 DeleteConnMgr();
3934 }
3935 #endif // NINSPECT
3936
3937 #ifndef NINSPECT
TEST_F(LowEnergyConnectionManagerTest,InspectFailedConnection)3938 TEST_F(LowEnergyConnectionManagerTest, InspectFailedConnection) {
3939 inspect::Inspector inspector;
3940 conn_mgr()->AttachInspect(inspector.GetRoot(),
3941 "low_energy_connection_manager");
3942
3943 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
3944 EXPECT_TRUE(peer->temporary());
3945
3946 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
3947 fake_peer->set_connect_status(
3948 pw::bluetooth::emboss::StatusCode::CONNECTION_LIMIT_EXCEEDED);
3949 test_device()->AddPeer(std::move(fake_peer));
3950
3951 auto callback = [](auto result) { ASSERT_TRUE(result.is_error()); };
3952 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
3953 RunUntilIdle();
3954
3955 auto conn_mgr_property_matcher = PropertyList(
3956 UnorderedElementsAre(UintIs("disconnect_explicit_disconnect_count", 0),
3957 UintIs("disconnect_link_error_count", 0),
3958 UintIs("disconnect_remote_disconnection_count", 0),
3959 UintIs("disconnect_zero_ref_count", 0),
3960 UintIs("incoming_connection_failure_count", 0),
3961 UintIs("incoming_connection_success_count", 0),
3962 UintIs("outgoing_connection_failure_count", 1),
3963 UintIs("outgoing_connection_success_count", 0),
3964 IntIs("recent_connection_failures", 1)));
3965
3966 auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
3967 EXPECT_THAT(
3968 hierarchy.value(),
3969 ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));
3970
3971 RunFor(LowEnergyConnectionManager::
3972 kInspectRecentConnectionFailuresExpiryDuration -
3973 std::chrono::nanoseconds(1));
3974 hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
3975 EXPECT_THAT(
3976 hierarchy.value(),
3977 ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));
3978
3979 // Failures should revert to 0 after expiry duration.
3980 RunFor(std::chrono::nanoseconds(1));
3981 conn_mgr_property_matcher = PropertyList(
3982 UnorderedElementsAre(UintIs("disconnect_explicit_disconnect_count", 0),
3983 UintIs("disconnect_link_error_count", 0),
3984 UintIs("disconnect_remote_disconnection_count", 0),
3985 UintIs("disconnect_zero_ref_count", 0),
3986 UintIs("incoming_connection_failure_count", 0),
3987 UintIs("incoming_connection_success_count", 0),
3988 UintIs("outgoing_connection_failure_count", 1),
3989 UintIs("outgoing_connection_success_count", 0),
3990 IntIs("recent_connection_failures", 0)));
3991 hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
3992 EXPECT_THAT(
3993 hierarchy.value(),
3994 ChildrenMatch(ElementsAre(NodeMatches(conn_mgr_property_matcher))));
3995
3996 // LECM must be destroyed before the inspector to avoid a page fault on
3997 // destruction of inspect properties (they try to update the inspect VMO,
3998 // which is deleted on inspector destruction).
3999 DeleteConnMgr();
4000 }
4001 #endif // NINSPECT
4002
TEST_F(LowEnergyConnectionManagerTest,RegisterRemoteInitiatedLinkWithAddressDifferentFromIdentityAddressDoesNotCrash)4003 TEST_F(
4004 LowEnergyConnectionManagerTest,
4005 RegisterRemoteInitiatedLinkWithAddressDifferentFromIdentityAddressDoesNotCrash) {
4006 DeviceAddress kIdentityAddress(DeviceAddress::Type::kLEPublic,
4007 {1, 0, 0, 0, 0, 0});
4008 DeviceAddress kRandomAddress(DeviceAddress::Type::kLERandom,
4009 {2, 0, 0, 0, 0, 0});
4010 Peer* peer = peer_cache()->NewPeer(kRandomAddress, /*connectable=*/true);
4011 sm::PairingData data;
4012 data.peer_ltk = kLTK;
4013 data.local_ltk = kLTK;
4014 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
4015 data.identity_address = kIdentityAddress;
4016 EXPECT_TRUE(peer_cache()->StoreLowEnergyBond(peer->identifier(), data));
4017 EXPECT_EQ(peer->address(), kIdentityAddress);
4018
4019 test_device()->AddPeer(
4020 std::make_unique<FakePeer>(kRandomAddress, dispatcher()));
4021 test_device()->ConnectLowEnergy(kRandomAddress);
4022 RunUntilIdle();
4023
4024 auto link = MoveLastRemoteInitiated();
4025 ASSERT_TRUE(link);
4026
4027 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4028 conn_mgr()->RegisterRemoteInitiatedLink(
4029 std::move(link), BondableMode::Bondable, [&](auto result) {
4030 ASSERT_EQ(fit::ok(), result);
4031 conn_handle = std::move(result).value();
4032 });
4033 EXPECT_EQ(peer->le()->connection_state(),
4034 Peer::ConnectionState::kInitializing);
4035
4036 RunUntilIdle();
4037
4038 ASSERT_TRUE(conn_handle);
4039 EXPECT_TRUE(conn_handle->active());
4040 EXPECT_EQ(peer->identifier(), conn_handle->peer_identifier());
4041 EXPECT_TRUE(peer->connected());
4042 }
4043
TEST_F(LowEnergyConnectionManagerTest,ConnectSinglePeerWithInterrogationLongerThanCentralPauseTimeout)4044 TEST_F(LowEnergyConnectionManagerTest,
4045 ConnectSinglePeerWithInterrogationLongerThanCentralPauseTimeout) {
4046 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
4047 EXPECT_TRUE(peer->temporary());
4048
4049 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
4050 test_device()->AddPeer(std::move(fake_peer));
4051
4052 // Cause interrogation to stall so that we can expire the central pause
4053 // timeout.
4054 fit::closure send_read_remote_features_rsp;
4055 test_device()->pause_responses_for_opcode(
4056 hci_spec::kLEReadRemoteFeatures, [&](fit::closure unpause) {
4057 send_read_remote_features_rsp = std::move(unpause);
4058 });
4059
4060 size_t hci_update_conn_param_count = 0;
4061 test_device()->set_le_connection_parameters_callback(
4062 [&](auto, auto) { hci_update_conn_param_count++; });
4063
4064 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4065 auto callback = [&conn_handle](auto result) {
4066 ASSERT_EQ(fit::ok(), result);
4067 conn_handle = std::move(result).value();
4068 EXPECT_TRUE(conn_handle->active());
4069 };
4070
4071 EXPECT_TRUE(connected_peers().empty());
4072 conn_mgr()->Connect(peer->identifier(), callback, kConnectionOptions);
4073 ASSERT_TRUE(peer->le());
4074 EXPECT_EQ(Peer::ConnectionState::kInitializing,
4075 peer->le()->connection_state());
4076
4077 RunUntilIdle();
4078 EXPECT_EQ(1u, connected_peers().size());
4079 EXPECT_EQ(1u, connected_peers().count(kAddress0));
4080 EXPECT_FALSE(conn_handle);
4081 EXPECT_EQ(hci_update_conn_param_count, 0u);
4082
4083 RunFor(kLEConnectionPausePeripheral);
4084 EXPECT_FALSE(conn_handle);
4085 EXPECT_EQ(hci_update_conn_param_count, 0u);
4086
4087 // Allow interrogation to complete.
4088 send_read_remote_features_rsp();
4089 RunUntilIdle();
4090 EXPECT_EQ(hci_update_conn_param_count, 1u);
4091 ASSERT_TRUE(conn_handle);
4092 EXPECT_TRUE(conn_handle->active());
4093 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
4094 }
4095
TEST_F(LowEnergyConnectionManagerTest,RegisterRemoteInitiatedLinkWithInterrogationLongerThanPeripheralPauseTimeout)4096 TEST_F(
4097 LowEnergyConnectionManagerTest,
4098 RegisterRemoteInitiatedLinkWithInterrogationLongerThanPeripheralPauseTimeout) {
4099 // A FakePeer does not support the HCI connection parameter update procedure
4100 // by default, so the L2CAP procedure will be used.
4101 test_device()->AddPeer(std::make_unique<FakePeer>(kAddress0, dispatcher()));
4102
4103 // Cause interrogation to stall so that we can expire the peripheral pause
4104 // timeout.
4105 fit::closure send_read_remote_features_rsp;
4106 test_device()->pause_responses_for_opcode(
4107 hci_spec::kLEReadRemoteFeatures, [&](fit::closure unpause) {
4108 send_read_remote_features_rsp = std::move(unpause);
4109 });
4110
4111 size_t l2cap_conn_param_update_count = 0;
4112 fake_l2cap()->set_connection_parameter_update_request_responder(
4113 [&](auto, auto) {
4114 l2cap_conn_param_update_count++;
4115 return true;
4116 });
4117
4118 // First create a fake incoming connection.
4119 test_device()->ConnectLowEnergy(kAddress0);
4120 RunUntilIdle();
4121 auto link = MoveLastRemoteInitiated();
4122 ASSERT_TRUE(link);
4123
4124 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4125 conn_mgr()->RegisterRemoteInitiatedLink(
4126 std::move(link), BondableMode::Bondable, [&](auto result) {
4127 ASSERT_EQ(fit::ok(), result);
4128 conn_handle = std::move(result).value();
4129 });
4130
4131 // A Peer should now exist in the cache.
4132 auto* peer = peer_cache()->FindByAddress(kAddress0);
4133 ASSERT_TRUE(peer);
4134 EXPECT_EQ(peer->le()->connection_state(),
4135 Peer::ConnectionState::kInitializing);
4136
4137 RunUntilIdle();
4138 EXPECT_EQ(1u, connected_peers().size());
4139 EXPECT_EQ(1u, connected_peers().count(kAddress0));
4140 EXPECT_FALSE(conn_handle);
4141 EXPECT_EQ(l2cap_conn_param_update_count, 0u);
4142
4143 RunFor(kLEConnectionPausePeripheral);
4144 EXPECT_FALSE(conn_handle);
4145 EXPECT_EQ(l2cap_conn_param_update_count, 0u);
4146
4147 // Allow interrogation to complete.
4148 send_read_remote_features_rsp();
4149 RunUntilIdle();
4150 EXPECT_EQ(l2cap_conn_param_update_count, 1u);
4151 ASSERT_TRUE(conn_handle);
4152 EXPECT_TRUE(conn_handle->active());
4153 EXPECT_EQ(Peer::ConnectionState::kConnected, peer->le()->connection_state());
4154 }
4155
4156 // Test fixture for tests that disconnect a connection in various ways and
4157 // expect that controller packet counts are not cleared on disconnecting, but
4158 // are cleared on disconnection complete. Tests should disconnect
4159 // conn_handle0().
4160 class PendingPacketsTest : public LowEnergyConnectionManagerTest {
4161 public:
4162 PendingPacketsTest() = default;
4163 ~PendingPacketsTest() override = default;
4164
SetUp()4165 void SetUp() override {
4166 LowEnergyConnectionManagerTest::SetUp();
4167 const DeviceAddress kPeerAddr0(DeviceAddress::Type::kLEPublic, {1});
4168 const DeviceAddress kPeerAddr1(DeviceAddress::Type::kLEPublic, {2});
4169
4170 peer0_ = peer_cache()->NewPeer(kPeerAddr0, /*connectable=*/true);
4171 EXPECT_TRUE(peer0_->temporary());
4172 test_device()->AddPeer(
4173 std::make_unique<FakePeer>(kPeerAddr0, dispatcher()));
4174
4175 peer1_ = peer_cache()->NewPeer(kPeerAddr1, /*connectable=*/true);
4176 EXPECT_TRUE(peer1_->temporary());
4177 test_device()->AddPeer(
4178 std::make_unique<FakePeer>(kPeerAddr1, dispatcher()));
4179
4180 // Connect |peer0|
4181 conn_handle0_.reset();
4182 auto callback0 = [this](auto result) {
4183 ASSERT_EQ(fit::ok(), result);
4184 conn_handle0_ = std::move(result).value();
4185 EXPECT_TRUE(conn_handle0_->active());
4186 };
4187 conn_mgr()->Connect(peer0_->identifier(), callback0, kConnectionOptions);
4188 RunUntilIdle();
4189
4190 // Connect |peer1|
4191 conn_handle1_.reset();
4192 auto callback1 = [this](auto result) {
4193 ASSERT_EQ(fit::ok(), result);
4194 conn_handle1_ = std::move(result).value();
4195 EXPECT_TRUE(conn_handle1_->active());
4196 };
4197 conn_mgr()->Connect(peer1_->identifier(), callback1, kConnectionOptions);
4198 RunUntilIdle();
4199
4200 packet_count_ = 0;
4201 test_device()->SetDataCallback([&](const auto&) { packet_count_++; },
4202 dispatcher());
4203 test_device()->set_auto_completed_packets_event_enabled(false);
4204 test_device()->set_auto_disconnection_complete_event_enabled(false);
4205 }
4206
TearDown()4207 void TearDown() override {
4208 peer0_ = nullptr;
4209 peer1_ = nullptr;
4210 conn_handle0_.reset();
4211 conn_handle1_.reset();
4212
4213 LowEnergyConnectionManagerTest::TearDown();
4214 }
4215
peer0()4216 Peer* peer0() { return peer0_; }
conn_handle0()4217 std::unique_ptr<LowEnergyConnectionHandle>& conn_handle0() {
4218 return conn_handle0_;
4219 }
4220
4221 protected:
4222 hci_spec::ConnectionHandle handle0_;
4223 std::unique_ptr<LowEnergyConnectionHandle> conn_handle0_;
4224 std::unique_ptr<LowEnergyConnectionHandle> conn_handle1_;
4225
4226 private:
4227 size_t packet_count_;
4228 Peer* peer0_;
4229 Peer* peer1_;
4230 };
4231
4232 using LowEnergyConnectionManagerPendingPacketsTest = PendingPacketsTest;
4233
TEST_F(LowEnergyConnectionManagerPendingPacketsTest,Disconnect)4234 TEST_F(LowEnergyConnectionManagerPendingPacketsTest, Disconnect) {
4235 hci::FakeAclConnection connection_0(
4236 acl_data_channel(), conn_handle0_->handle(), bt::LinkType::kLE);
4237 hci::FakeAclConnection connection_1(
4238 acl_data_channel(), conn_handle1_->handle(), bt::LinkType::kLE);
4239
4240 acl_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
4241 acl_data_channel()->RegisterConnection(connection_1.GetWeakPtr());
4242
4243 // Fill controller buffer by sending |kLEMaxNumPackets| packets to |peer0|
4244 for (size_t i = 0; i < kLEMaxNumPackets; i++) {
4245 hci::ACLDataPacketPtr packet = hci::ACLDataPacket::New(
4246 conn_handle0_->handle(),
4247 hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
4248 hci_spec::ACLBroadcastFlag::kPointToPoint,
4249 /*payload_size=*/1);
4250 connection_0.QueuePacket(std::move(packet));
4251 RunUntilIdle();
4252 }
4253
4254 // Queue packet for |peer1|
4255 hci::ACLDataPacketPtr packet = hci::ACLDataPacket::New(
4256 conn_handle1_->handle(),
4257 hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
4258 hci_spec::ACLBroadcastFlag::kPointToPoint,
4259 /*payload_size=*/1);
4260 connection_1.QueuePacket(std::move(packet));
4261 RunUntilIdle();
4262
4263 // Packet for |peer1| should not have been sent because controller buffer is
4264 // full
4265 EXPECT_EQ(connection_0.queued_packets().size(), 0u);
4266 EXPECT_EQ(connection_1.queued_packets().size(), 1u);
4267
4268 handle0_ = conn_handle0_->handle();
4269
4270 // Send HCI Disconnect to controller
4271 EXPECT_TRUE(conn_mgr()->Disconnect(peer0()->identifier()));
4272
4273 RunUntilIdle();
4274
4275 // Packet for |peer1| should not have been sent before Disconnection Complete
4276 // event
4277 EXPECT_EQ(connection_0.queued_packets().size(), 0u);
4278 EXPECT_EQ(connection_1.queued_packets().size(), 1u);
4279
4280 acl_data_channel()->UnregisterConnection(conn_handle0_->handle());
4281
4282 // FakeController send us the HCI Disconnection Complete event
4283 test_device()->SendDisconnectionCompleteEvent(handle0_);
4284 RunUntilIdle();
4285
4286 // |peer0|'s link should have been unregistered and packet for |peer1| should
4287 // have been sent
4288 EXPECT_EQ(connection_0.queued_packets().size(), 0u);
4289 EXPECT_EQ(connection_1.queued_packets().size(), 0u);
4290 }
4291
TEST_F(LowEnergyConnectionManagerPendingPacketsTest,ReleaseRef)4292 TEST_F(LowEnergyConnectionManagerPendingPacketsTest, ReleaseRef) {
4293 hci::FakeAclConnection connection_0(
4294 acl_data_channel(), conn_handle0_->handle(), bt::LinkType::kLE);
4295 hci::FakeAclConnection connection_1(
4296 acl_data_channel(), conn_handle1_->handle(), bt::LinkType::kLE);
4297
4298 acl_data_channel()->RegisterConnection(connection_0.GetWeakPtr());
4299 acl_data_channel()->RegisterConnection(connection_1.GetWeakPtr());
4300
4301 // Fill controller buffer by sending |kLEMaxNumPackets| packets to |peer0|
4302 for (size_t i = 0; i < kLEMaxNumPackets; i++) {
4303 hci::ACLDataPacketPtr packet = hci::ACLDataPacket::New(
4304 conn_handle0_->handle(),
4305 hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
4306 hci_spec::ACLBroadcastFlag::kPointToPoint,
4307 /*payload_size=*/1);
4308 connection_0.QueuePacket(std::move(packet));
4309 RunUntilIdle();
4310 }
4311
4312 // Queue packet for |peer1|
4313 hci::ACLDataPacketPtr packet = hci::ACLDataPacket::New(
4314 conn_handle1_->handle(),
4315 hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
4316 hci_spec::ACLBroadcastFlag::kPointToPoint,
4317 /*payload_size=*/1);
4318 connection_1.QueuePacket(std::move(packet));
4319 RunUntilIdle();
4320
4321 // Packet for |peer1| should not have been sent before Disconnection Complete
4322 // event
4323 EXPECT_EQ(connection_0.queued_packets().size(), 0u);
4324 EXPECT_EQ(connection_1.queued_packets().size(), 1u);
4325
4326 handle0_ = conn_handle0_->handle();
4327
4328 // Releasing ref should send HCI Disconnect to controller
4329 conn_handle0().reset();
4330
4331 RunUntilIdle();
4332
4333 // Packet for |peer1| should not have been sent before Disconnection Complete
4334 // event
4335 EXPECT_EQ(connection_0.queued_packets().size(), 0u);
4336 EXPECT_EQ(connection_1.queued_packets().size(), 1u);
4337
4338 acl_data_channel()->UnregisterConnection(handle0_);
4339
4340 // FakeController send us the HCI Disconnection Complete event
4341 test_device()->SendDisconnectionCompleteEvent(handle0_);
4342 RunUntilIdle();
4343
4344 // |peer0|'s link should have been unregistered and packet for |peer1| should
4345 // have been sent
4346 EXPECT_EQ(connection_0.queued_packets().size(), 0u);
4347 EXPECT_EQ(connection_1.queued_packets().size(), 0u);
4348 }
4349
TEST_F(LowEnergyConnectionManagerTest,ConnectAndOpenL2cap)4350 TEST_F(LowEnergyConnectionManagerTest, ConnectAndOpenL2cap) {
4351 constexpr l2cap::Psm kFakePsm = 15;
4352 constexpr l2cap::ChannelParameters kChannelParameters{
4353 .mode = l2cap::CreditBasedFlowControlMode::kLeCreditBasedFlowControl,
4354 .max_rx_sdu_size = std::nullopt,
4355 .flush_timeout = std::nullopt,
4356 };
4357 constexpr l2cap::ChannelId kFakeChannelId = l2cap::kFirstDynamicChannelId;
4358 constexpr sm::SecurityLevel kSecurityLevel = sm::SecurityLevel::kEncrypted;
4359
4360 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
4361 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
4362 test_device()->AddPeer(std::move(fake_peer));
4363
4364 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4365 auto connection_callback = [&conn_handle](auto result) {
4366 ASSERT_EQ(fit::ok(), result);
4367 conn_handle = std::move(result).value();
4368 };
4369
4370 EXPECT_TRUE(connected_peers().empty());
4371 conn_mgr()->Connect(
4372 peer->identifier(), connection_callback, kConnectionOptions);
4373 ASSERT_TRUE(peer->le());
4374 EXPECT_EQ(Peer::ConnectionState::kInitializing,
4375 peer->le()->connection_state());
4376
4377 RunUntilIdle();
4378 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::Bondable);
4379
4380 EXPECT_EQ(1u, connected_peers().count(kAddress0));
4381 ASSERT_TRUE(conn_handle);
4382 EXPECT_TRUE(conn_handle->active());
4383
4384 std::optional<WeakSelf<l2cap::Channel>::WeakPtr> channel;
4385 auto callback = [&channel](auto result) {
4386 ASSERT_TRUE(result.is_alive());
4387 channel = std::move(result);
4388 };
4389
4390 fake_l2cap()->ExpectOutboundL2capChannel(conn_handle->handle(),
4391 kFakePsm,
4392 kFakeChannelId,
4393 kFakeChannelId,
4394 kChannelParameters);
4395 conn_mgr()->OpenL2capChannel(peer->identifier(),
4396 kFakePsm,
4397 kChannelParameters,
4398 kSecurityLevel,
4399 callback);
4400
4401 RunUntilIdle();
4402 EXPECT_TRUE(channel);
4403 EXPECT_TRUE(channel->is_alive());
4404 EXPECT_TRUE(conn_handle->security().encrypted());
4405 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::Bondable);
4406 }
4407
TEST_F(LowEnergyConnectionManagerTest,UnknownPeerFailOpenL2cap)4408 TEST_F(LowEnergyConnectionManagerTest, UnknownPeerFailOpenL2cap) {
4409 constexpr PeerId kUnknownId(1);
4410 constexpr l2cap::Psm kFakePsm = 15;
4411 constexpr l2cap::ChannelParameters kChannelParameters{
4412 .mode = l2cap::CreditBasedFlowControlMode::kLeCreditBasedFlowControl,
4413 .max_rx_sdu_size = std::nullopt,
4414 .flush_timeout = std::nullopt,
4415 };
4416 constexpr sm::SecurityLevel kSecurityLevel = sm::SecurityLevel::kEncrypted;
4417
4418 std::optional<WeakSelf<l2cap::Channel>::WeakPtr> channel;
4419 auto callback = [&channel](auto result) { channel = std::move(result); };
4420
4421 conn_mgr()->OpenL2capChannel(
4422 kUnknownId, kFakePsm, kChannelParameters, kSecurityLevel, callback);
4423
4424 RunUntilIdle();
4425 EXPECT_TRUE(channel);
4426 EXPECT_FALSE(channel->is_alive());
4427 }
4428
TEST_F(LowEnergyConnectionManagerTest,ConnectAndOpenL2capAuthenticated)4429 TEST_F(LowEnergyConnectionManagerTest, ConnectAndOpenL2capAuthenticated) {
4430 constexpr l2cap::Psm kFakePsm = 15;
4431 constexpr l2cap::ChannelParameters kChannelParameters{
4432 .mode = l2cap::CreditBasedFlowControlMode::kLeCreditBasedFlowControl,
4433 .max_rx_sdu_size = std::nullopt,
4434 .flush_timeout = std::nullopt,
4435 };
4436 constexpr l2cap::ChannelId kFakeChannelId = l2cap::kFirstDynamicChannelId;
4437 constexpr sm::SecurityLevel kSecurityLevel =
4438 sm::SecurityLevel::kAuthenticated;
4439
4440 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
4441 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
4442 test_device()->AddPeer(std::move(fake_peer));
4443
4444 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4445 auto connection_callback = [&conn_handle](auto result) {
4446 ASSERT_EQ(fit::ok(), result);
4447 conn_handle = std::move(result).value();
4448 };
4449
4450 EXPECT_TRUE(connected_peers().empty());
4451 conn_mgr()->Connect(
4452 peer->identifier(), connection_callback, kConnectionOptions);
4453 ASSERT_TRUE(peer->le());
4454 EXPECT_EQ(Peer::ConnectionState::kInitializing,
4455 peer->le()->connection_state());
4456
4457 RunUntilIdle();
4458 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::Bondable);
4459
4460 EXPECT_EQ(1u, connected_peers().count(kAddress0));
4461 ASSERT_TRUE(conn_handle);
4462 EXPECT_TRUE(conn_handle->active());
4463
4464 std::optional<WeakSelf<l2cap::Channel>::WeakPtr> channel;
4465 auto callback = [&channel](auto result) {
4466 ASSERT_TRUE(result.is_alive());
4467 channel = std::move(result);
4468 };
4469
4470 fake_l2cap()->ExpectOutboundL2capChannel(conn_handle->handle(),
4471 kFakePsm,
4472 kFakeChannelId,
4473 kFakeChannelId,
4474 kChannelParameters);
4475 conn_mgr()->OpenL2capChannel(peer->identifier(),
4476 kFakePsm,
4477 kChannelParameters,
4478 kSecurityLevel,
4479 callback);
4480
4481 RunUntilIdle();
4482 EXPECT_TRUE(channel);
4483 EXPECT_TRUE(channel->is_alive());
4484 EXPECT_TRUE(conn_handle->security().encrypted());
4485 EXPECT_TRUE(conn_handle->security().authenticated());
4486 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::Bondable);
4487 }
4488
TEST_F(LowEnergyConnectionManagerTest,ConnectAndOpenL2capSecureAuthenticated)4489 TEST_F(LowEnergyConnectionManagerTest, ConnectAndOpenL2capSecureAuthenticated) {
4490 constexpr l2cap::Psm kFakePsm = 15;
4491 constexpr l2cap::ChannelParameters kChannelParameters{
4492 .mode = l2cap::CreditBasedFlowControlMode::kLeCreditBasedFlowControl,
4493 .max_rx_sdu_size = std::nullopt,
4494 .flush_timeout = std::nullopt,
4495 };
4496 constexpr l2cap::ChannelId kFakeChannelId = l2cap::kFirstDynamicChannelId;
4497 constexpr sm::SecurityLevel kSecurityLevel =
4498 sm::SecurityLevel::kSecureAuthenticated;
4499
4500 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
4501 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
4502 test_device()->AddPeer(std::move(fake_peer));
4503
4504 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4505 auto connection_callback = [&conn_handle](auto result) {
4506 ASSERT_EQ(fit::ok(), result);
4507 conn_handle = std::move(result).value();
4508 };
4509
4510 EXPECT_TRUE(connected_peers().empty());
4511 conn_mgr()->Connect(
4512 peer->identifier(), connection_callback, kConnectionOptions);
4513 ASSERT_TRUE(peer->le());
4514 EXPECT_EQ(Peer::ConnectionState::kInitializing,
4515 peer->le()->connection_state());
4516
4517 RunUntilIdle();
4518 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::Bondable);
4519
4520 EXPECT_EQ(1u, connected_peers().count(kAddress0));
4521 ASSERT_TRUE(conn_handle);
4522 EXPECT_TRUE(conn_handle->active());
4523
4524 std::optional<WeakSelf<l2cap::Channel>::WeakPtr> channel;
4525 auto callback = [&channel](auto result) {
4526 ASSERT_TRUE(result.is_alive());
4527 channel = std::move(result);
4528 };
4529
4530 fake_l2cap()->ExpectOutboundL2capChannel(conn_handle->handle(),
4531 kFakePsm,
4532 kFakeChannelId,
4533 kFakeChannelId,
4534 kChannelParameters);
4535 conn_mgr()->OpenL2capChannel(peer->identifier(),
4536 kFakePsm,
4537 kChannelParameters,
4538 kSecurityLevel,
4539 callback);
4540
4541 RunUntilIdle();
4542 EXPECT_TRUE(channel);
4543 EXPECT_TRUE(channel->is_alive());
4544 EXPECT_TRUE(conn_handle->security().encrypted());
4545 EXPECT_TRUE(conn_handle->security().authenticated());
4546 EXPECT_TRUE(conn_handle->security().secure_connections());
4547 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::Bondable);
4548 }
4549
TEST_F(LowEnergyConnectionManagerTest,ConnectAndOpenL2capNonBondable)4550 TEST_F(LowEnergyConnectionManagerTest, ConnectAndOpenL2capNonBondable) {
4551 constexpr l2cap::Psm kFakePsm = 15;
4552 constexpr l2cap::ChannelParameters kChannelParameters{
4553 .mode = l2cap::CreditBasedFlowControlMode::kLeCreditBasedFlowControl,
4554 .max_rx_sdu_size = std::nullopt,
4555 .flush_timeout = std::nullopt,
4556 };
4557 constexpr l2cap::ChannelId kFakeChannelId = l2cap::kFirstDynamicChannelId;
4558 constexpr sm::SecurityLevel kSecurityLevel =
4559 sm::SecurityLevel::kSecureAuthenticated;
4560 constexpr LowEnergyConnectionOptions kConnectionOptionsNonBondable{
4561 .bondable_mode = sm::BondableMode::NonBondable,
4562 };
4563
4564 auto* peer = peer_cache()->NewPeer(kAddress0, /*connectable=*/true);
4565 auto fake_peer = std::make_unique<FakePeer>(kAddress0, dispatcher());
4566 test_device()->AddPeer(std::move(fake_peer));
4567
4568 std::unique_ptr<LowEnergyConnectionHandle> conn_handle;
4569 auto connection_callback = [&conn_handle](auto result) {
4570 ASSERT_EQ(fit::ok(), result);
4571 conn_handle = std::move(result).value();
4572 };
4573
4574 EXPECT_TRUE(connected_peers().empty());
4575 conn_mgr()->Connect(
4576 peer->identifier(), connection_callback, kConnectionOptionsNonBondable);
4577 ASSERT_TRUE(peer->le());
4578 EXPECT_EQ(Peer::ConnectionState::kInitializing,
4579 peer->le()->connection_state());
4580
4581 RunUntilIdle();
4582 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::NonBondable);
4583
4584 EXPECT_EQ(1u, connected_peers().count(kAddress0));
4585 ASSERT_TRUE(conn_handle);
4586 EXPECT_TRUE(conn_handle->active());
4587
4588 std::optional<WeakSelf<l2cap::Channel>::WeakPtr> channel;
4589 auto callback = [&channel](auto result) {
4590 ASSERT_TRUE(result.is_alive());
4591 channel = std::move(result);
4592 };
4593
4594 fake_l2cap()->ExpectOutboundL2capChannel(conn_handle->handle(),
4595 kFakePsm,
4596 kFakeChannelId,
4597 kFakeChannelId,
4598 kChannelParameters);
4599 conn_mgr()->OpenL2capChannel(peer->identifier(),
4600 kFakePsm,
4601 kChannelParameters,
4602 kSecurityLevel,
4603 callback);
4604
4605 RunUntilIdle();
4606 EXPECT_TRUE(channel);
4607 EXPECT_TRUE(channel->is_alive());
4608 EXPECT_TRUE(conn_handle->security().encrypted());
4609 EXPECT_TRUE(conn_handle->security().authenticated());
4610 EXPECT_TRUE(conn_handle->security().secure_connections());
4611 EXPECT_EQ(conn_handle->bondable_mode(), sm::BondableMode::NonBondable);
4612 }
4613
4614 } // namespace
4615 } // namespace bt::gap
4616