xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/hci/connection_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/hci/connection.h"
16 
17 #include "pw_bluetooth/hci_common.emb.h"
18 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
19 #include "pw_bluetooth_sapphire/internal/host/hci/bredr_connection.h"
20 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_connection.h"
21 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
22 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
23 #include "pw_bluetooth_sapphire/internal/host/testing/mock_controller.h"
24 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
25 #include "pw_bluetooth_sapphire/internal/host/testing/test_packets.h"
26 #include "pw_bluetooth_sapphire/internal/host/transport/fake_acl_connection.h"
27 
28 namespace bt::hci {
29 namespace {
30 
31 const hci_spec::LEConnectionParameters kTestParams(1, 1, 1);
32 const DeviceAddress kLEAddress1(DeviceAddress::Type::kLEPublic, {1});
33 const DeviceAddress kLEAddress2(DeviceAddress::Type::kLEPublic, {2});
34 const DeviceAddress kACLAddress1(DeviceAddress::Type::kBREDR, {3});
35 const DeviceAddress kACLAddress2(DeviceAddress::Type::kBREDR, {4});
36 
37 constexpr UInt128 kLTK{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
38 constexpr uint64_t kRand = 1;
39 constexpr uint16_t kEDiv = 255;
40 constexpr hci_spec::LinkKeyType kLinkKeyType =
41     hci_spec::LinkKeyType::kAuthenticatedCombination256;
42 
43 const DataBufferInfo kBrEdrBufferInfo(1024, 5);
44 const DataBufferInfo kLeBufferInfo(1024, 1);
45 
46 using bt::testing::CommandTransaction;
47 
48 using TestingBase =
49     bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
50 
51 const StaticByteBuffer kReadEncryptionKeySizeCommand =
52     StaticByteBuffer(0x08,
53                      0x14,  // opcode: HCI_ReadEncryptionKeySize
54                      0x02,  // parameter size
55                      0x01,
56                      0x00  // connection handle: 0x0001
57     );
58 
59 // HCI_Disconnect (handle: 0x0001, reason: RemoteUserTerminatedConnection)
60 const StaticByteBuffer kDisconnectCommand(
61     0x06,
62     0x04,  // opcode: HCI_Disconnect
63     0x03,  // parameter total size
64     0x01,
65     0x00,  // handle: 1
66     pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
67 
68 // HCI_Disconnect (handle: 0x0001, reason: RemoteUserTerminatedConnection)
69 const StaticByteBuffer kDisconnectCommandAuthFailure(
70     0x06,
71     0x04,  // opcode: HCI_Disconnect
72     0x03,  // parameter total size
73     0x01,
74     0x00,  // handle: 1
75     pw::bluetooth::emboss::StatusCode::AUTHENTICATION_FAILURE);
76 
77 class ConnectionTest : public TestingBase {
78  public:
79   ConnectionTest() = default;
80   ~ConnectionTest() override = default;
81 
82  protected:
SetUp()83   void SetUp() override {
84     TestingBase::SetUp();
85     InitializeACLDataChannel(kBrEdrBufferInfo, kLeBufferInfo);
86   }
87 
NewLEConnection(pw::bluetooth::emboss::ConnectionRole role=pw::bluetooth::emboss::ConnectionRole::CENTRAL,hci_spec::ConnectionHandle handle=kTestHandle)88   std::unique_ptr<LowEnergyConnection> NewLEConnection(
89       pw::bluetooth::emboss::ConnectionRole role =
90           pw::bluetooth::emboss::ConnectionRole::CENTRAL,
91       hci_spec::ConnectionHandle handle = kTestHandle) {
92     return std::make_unique<LowEnergyConnection>(handle,
93                                                  kLEAddress1,
94                                                  kLEAddress2,
95                                                  kTestParams,
96                                                  role,
97                                                  transport()->GetWeakPtr());
98   }
99 
NewACLConnection(pw::bluetooth::emboss::ConnectionRole role=pw::bluetooth::emboss::ConnectionRole::CENTRAL,hci_spec::ConnectionHandle handle=kTestHandle)100   std::unique_ptr<BrEdrConnection> NewACLConnection(
101       pw::bluetooth::emboss::ConnectionRole role =
102           pw::bluetooth::emboss::ConnectionRole::CENTRAL,
103       hci_spec::ConnectionHandle handle = kTestHandle) {
104     return std::make_unique<BrEdrConnection>(
105         handle, kACLAddress1, kACLAddress2, role, transport()->GetWeakPtr());
106   }
107 };
108 
109 // Tests using this harness will be instantiated using ACL and LE link types.
110 // See INSTANTIATE_TEST_SUITE_P(ConnectionTest, LinkTypeConnectionTest, ...)
111 class LinkTypeConnectionTest
112     : public ConnectionTest,
113       public ::testing::WithParamInterface<bt::LinkType> {
114  protected:
NewConnection(pw::bluetooth::emboss::ConnectionRole role=pw::bluetooth::emboss::ConnectionRole::CENTRAL,hci_spec::ConnectionHandle handle=kTestHandle)115   std::unique_ptr<AclConnection> NewConnection(
116       pw::bluetooth::emboss::ConnectionRole role =
117           pw::bluetooth::emboss::ConnectionRole::CENTRAL,
118       hci_spec::ConnectionHandle handle = kTestHandle) {
119     const bt::LinkType ll_type = GetParam();
120     switch (ll_type) {
121       case bt::LinkType::kACL:
122         return NewACLConnection(role, handle);
123       case bt::LinkType::kLE:
124         return NewLEConnection(role, handle);
125       case bt::LinkType::kSCO:
126       case bt::LinkType::kESCO:
127         break;
128     }
129     BT_PANIC("Invalid link type: %u", static_cast<unsigned>(ll_type));
130     return nullptr;
131   }
132 
133   // Assigns the appropriate test link key based on the type of link being
134   // tested.
SetTestLinkKey(Connection * connection)135   void SetTestLinkKey(Connection* connection) {
136     const bt::LinkType ll_type = GetParam();
137     if (ll_type == bt::LinkType::kLE) {
138       static_cast<LowEnergyConnection*>(connection)
139           ->set_ltk(hci_spec::LinkKey(kLTK, kRand, kEDiv));
140     } else {
141       static_cast<BrEdrConnection*>(connection)
142           ->set_link_key(hci_spec::LinkKey(kLTK, 0, 0), kLinkKeyType);
143     }
144   }
145 };
146 
147 using HCI_ConnectionTest = ConnectionTest;
148 
TEST_F(ConnectionTest,Getters)149 TEST_F(ConnectionTest, Getters) {
150   std::unique_ptr<LowEnergyConnection> connection = NewLEConnection();
151 
152   EXPECT_EQ(kTestHandle, connection->handle());
153   EXPECT_EQ(pw::bluetooth::emboss::ConnectionRole::CENTRAL, connection->role());
154   EXPECT_EQ(kTestParams, connection->low_energy_parameters());
155   EXPECT_EQ(kLEAddress1, connection->local_address());
156   EXPECT_EQ(kLEAddress2, connection->peer_address());
157 
158   EXPECT_EQ(std::nullopt, connection->ltk());
159   connection->set_ltk(hci_spec::LinkKey());
160   ASSERT_TRUE(connection->ltk().has_value());
161   EXPECT_EQ(hci_spec::LinkKey(), connection->ltk().value());
162 
163   EXPECT_CMD_PACKET_OUT(test_device(),
164                         bt::testing::DisconnectPacket(kTestHandle));
165 }
166 
TEST_F(ConnectionTest,AclLinkKeyAndTypeAccessors)167 TEST_F(ConnectionTest, AclLinkKeyAndTypeAccessors) {
168   std::unique_ptr<BrEdrConnection> connection = NewACLConnection();
169 
170   EXPECT_EQ(std::nullopt, connection->ltk());
171   EXPECT_EQ(std::nullopt, connection->ltk_type());
172   connection->set_link_key(hci_spec::LinkKey(), kLinkKeyType);
173   ASSERT_TRUE(connection->ltk().has_value());
174   EXPECT_EQ(hci_spec::LinkKey(), connection->ltk().value());
175   ASSERT_TRUE(connection->ltk_type().has_value());
176   EXPECT_EQ(kLinkKeyType, connection->ltk_type().value());
177 
178   EXPECT_CMD_PACKET_OUT(test_device(),
179                         bt::testing::DisconnectPacket(kTestHandle));
180 }
181 
TEST_P(LinkTypeConnectionTest,Disconnect)182 TEST_P(LinkTypeConnectionTest, Disconnect) {
183   // clang-format off
184 
185   // Respond with Command Status and Disconnection Complete.
186   StaticByteBuffer cmd_status_bytes(
187       hci_spec::kCommandStatusEventCode, 0x04, pw::bluetooth::emboss::StatusCode::SUCCESS, 1,
188       0x06, 0x04);
189 
190   StaticByteBuffer disc_cmpl_bytes(
191       hci_spec::kDisconnectionCompleteEventCode, 0x04,
192       pw::bluetooth::emboss::StatusCode::SUCCESS, 0x01, 0x00,
193       pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST);
194 
195   // clang-format on
196 
197   EXPECT_CMD_PACKET_OUT(
198       test_device(), kDisconnectCommand, &cmd_status_bytes, &disc_cmpl_bytes);
199 
200   bool callback_called = false;
201   test_device()->SetTransactionCallback(
202       [&callback_called] { callback_called = true; });
203 
204   auto connection = NewConnection();
205 
206   size_t disconn_cb_count = 0;
207   auto disconn_complete_cb = [&](const Connection&, auto reason) {
208     disconn_cb_count++;
209     EXPECT_EQ(
210         reason,
211         pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST);
212   };
213   connection->set_peer_disconnect_callback(disconn_complete_cb);
214 
215   connection->Disconnect(
216       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
217 
218   RunUntilIdle();
219   EXPECT_TRUE(callback_called);
220   EXPECT_EQ(1u, disconn_cb_count);
221 }
222 
TEST_P(LinkTypeConnectionTest,LinkRegistrationAndLocalDisconnection)223 TEST_P(LinkTypeConnectionTest, LinkRegistrationAndLocalDisconnection) {
224   const bt::LinkType ll_type = GetParam();
225   const hci_spec::ConnectionHandle kHandle0 = 0x0001;
226   const hci_spec::ConnectionHandle kHandle1 = 0x0002;
227 
228   const auto& kBufferInfo =
229       ll_type == bt::LinkType::kACL ? kBrEdrBufferInfo : kLeBufferInfo;
230 
231   // Should register connection with ACL Data Channel.
232   FakeAclConnection acl_connection_0(acl_data_channel(), kHandle0, ll_type);
233   FakeAclConnection acl_connection_1(acl_data_channel(), kHandle1, ll_type);
234 
235   acl_data_channel()->RegisterConnection(acl_connection_0.GetWeakPtr());
236   acl_data_channel()->RegisterConnection(acl_connection_1.GetWeakPtr());
237 
238   // HCI Connections corresponding to respective |acl_connection_*|
239   auto hci_connection_0 =
240       NewConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle0);
241   auto hci_connection_1 =
242       NewConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle1);
243 
244   // Fill up BR/EDR controller buffer
245   for (size_t i = 0; i < kBufferInfo.max_num_packets(); i++) {
246     // Connection handle should have been registered with ACL Data Channel.
247     const StaticByteBuffer kPacket(
248         // ACL data header (handle: 0, length 1)
249         LowerBits(kHandle0),
250         UpperBits(kHandle0),
251         // payload length
252         0x01,
253         0x00,
254         // payload
255         static_cast<uint8_t>(i));
256     EXPECT_ACL_PACKET_OUT(test_device(), kPacket);
257     // Create packet to send on |acl_connection_0|
258     ACLDataPacketPtr packet =
259         ACLDataPacket::New(kHandle0,
260                            hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
261                            hci_spec::ACLBroadcastFlag::kPointToPoint,
262                            /*payload_size=*/1);
263     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
264     acl_connection_0.QueuePacket(std::move(packet));
265     RunUntilIdle();
266   }
267   // Create packet to send on |acl_connection_1|
268   ACLDataPacketPtr packet =
269       ACLDataPacket::New(kHandle1,
270                          hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
271                          hci_spec::ACLBroadcastFlag::kPointToPoint,
272                          /*payload_size=*/1);
273   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
274   acl_connection_1.QueuePacket(std::move(packet));
275   RunUntilIdle();
276 
277   // Packet for |acl_connection_1| should not have been sent because controller
278   // buffer is full
279   EXPECT_EQ(acl_connection_0.queued_packets().size(), 0u);
280   EXPECT_EQ(acl_connection_1.queued_packets().size(), 1u);
281   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
282 
283   const auto disconnect_status_rsp =
284       bt::testing::DisconnectStatusResponsePacket();
285   EXPECT_CMD_PACKET_OUT(test_device(),
286                         bt::testing::DisconnectPacket(kHandle0),
287                         &disconnect_status_rsp);
288   hci_connection_0->Disconnect(
289       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
290   RunUntilIdle();
291 
292   acl_data_channel()->UnregisterConnection(kHandle0);
293 
294   // Controller packet counts for |kHandle0| should not have been cleared after
295   // disconnect. Disconnection Complete handler should clear controller packet
296   // counts, so packet for |kHandle1| should be sent.
297   DynamicByteBuffer disconnection_complete(
298       bt::testing::DisconnectionCompletePacket(kHandle0));
299   test_device()->SendCommandChannelPacket(disconnection_complete);
300 
301   // Send out last packet
302   EXPECT_ACL_PACKET_OUT(test_device(),
303                         StaticByteBuffer(
304                             // ACL data header (handle: 0, length 1)
305                             LowerBits(kHandle1),
306                             UpperBits(kHandle1),
307                             // payload length
308                             0x01,
309                             0x00,
310                             // payload
311                             1));
312   RunUntilIdle();
313 
314   // Connection handle |kHandle0| should have been unregistered with ACL Data
315   // Channel. Since controller packet count was cleared, packet for |kHandle1|
316   // should have been sent.
317   EXPECT_EQ(acl_connection_0.queued_packets().size(), 0u);
318   EXPECT_EQ(acl_connection_1.queued_packets().size(), 0u);
319   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
320 
321   // |acl_connection_1| is destroyed in test destructor
322   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kHandle1));
323 }
324 
325 // In remote disconnection, Connection::Disconnect is not called. Instead,
326 // Connection::OnDisconnectionComplete is invoked and handles all cleanup.
TEST_P(LinkTypeConnectionTest,LinkRegistrationAndRemoteDisconnection)327 TEST_P(LinkTypeConnectionTest, LinkRegistrationAndRemoteDisconnection) {
328   const bt::LinkType ll_type = GetParam();
329   const hci_spec::ConnectionHandle kHandle0 = 0x0001;
330   const hci_spec::ConnectionHandle kHandle1 = 0x0002;
331 
332   const auto& kBufferInfo =
333       ll_type == bt::LinkType::kACL ? kBrEdrBufferInfo : kLeBufferInfo;
334 
335   // Should register connection with ACL Data Channel.
336   FakeAclConnection acl_connection_0(acl_data_channel(), kHandle0, ll_type);
337   FakeAclConnection acl_connection_1(acl_data_channel(), kHandle1, ll_type);
338 
339   acl_data_channel()->RegisterConnection(acl_connection_0.GetWeakPtr());
340   acl_data_channel()->RegisterConnection(acl_connection_1.GetWeakPtr());
341 
342   // HCI Connections corresponding to respective |acl_connection_*|
343   auto hci_connection_0 =
344       NewConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle0);
345   auto hci_connection_1 =
346       NewConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle1);
347 
348   // Fill up BR/EDR controller buffer
349   for (size_t i = 0; i < kBufferInfo.max_num_packets(); i++) {
350     // Connection handle should have been registered with ACL Data Channel.
351     const StaticByteBuffer kPacket(
352         // ACL data header (handle: 0, length 1)
353         LowerBits(kHandle0),
354         UpperBits(kHandle0),
355         // payload length
356         0x01,
357         0x00,
358         // payload
359         static_cast<uint8_t>(i));
360     EXPECT_ACL_PACKET_OUT(test_device(), kPacket);
361     // Create packet to send on |acl_connection_0|
362     ACLDataPacketPtr packet =
363         ACLDataPacket::New(kHandle0,
364                            hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
365                            hci_spec::ACLBroadcastFlag::kPointToPoint,
366                            /*payload_size=*/1);
367     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
368     acl_connection_0.QueuePacket(std::move(packet));
369     RunUntilIdle();
370   }
371   // Create packet to send on |acl_connection_1|
372   ACLDataPacketPtr packet =
373       ACLDataPacket::New(kHandle1,
374                          hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
375                          hci_spec::ACLBroadcastFlag::kPointToPoint,
376                          /*payload_size=*/1);
377   packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(1);
378   acl_connection_1.QueuePacket(std::move(packet));
379   RunUntilIdle();
380 
381   // Packet for |acl_connection_1| should not have been sent because controller
382   // buffer is full
383   EXPECT_EQ(acl_connection_0.queued_packets().size(), 0u);
384   EXPECT_EQ(acl_connection_1.queued_packets().size(), 1u);
385   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
386 
387   size_t disconn_cb_count = 0;
388   auto disconn_complete_cb = [&](const Connection& cb_conn, auto /*reason*/) {
389     EXPECT_EQ(kHandle0, cb_conn.handle());
390     disconn_cb_count++;
391   };
392   hci_connection_0->set_peer_disconnect_callback(disconn_complete_cb);
393 
394   acl_data_channel()->UnregisterConnection(kHandle0);
395 
396   // Disconnection Complete handler should clear controller packet counts, so
397   // packet for |kHandle1| should be sent.
398   DynamicByteBuffer disconnection_complete(
399       bt::testing::DisconnectionCompletePacket(kHandle0));
400   test_device()->SendCommandChannelPacket(disconnection_complete);
401 
402   // Send out last packet
403   EXPECT_ACL_PACKET_OUT(test_device(),
404                         StaticByteBuffer(
405                             // ACL data header (handle: 0, length 1)
406                             LowerBits(kHandle1),
407                             UpperBits(kHandle1),
408                             // payload length
409                             0x01,
410                             0x00,
411                             // payload
412                             1));
413   test_device()->SendCommandChannelPacket(
414       bt::testing::NumberOfCompletedPacketsPacket(kHandle0, 10));
415   RunUntilIdle();
416 
417   // Connection handle |kHandle0| should have been unregistered with ACL Data
418   // Channel. Since controller packet count was cleared, packet for |kHandle1|
419   // should have been sent.
420   EXPECT_EQ(acl_connection_0.queued_packets().size(), 0u);
421   EXPECT_EQ(acl_connection_1.queued_packets().size(), 0u);
422   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
423 
424   // |acl_connection_1| is destroyed in test destructor
425   EXPECT_CMD_PACKET_OUT(test_device(), bt::testing::DisconnectPacket(kHandle1));
426 }
427 
TEST_F(ConnectionTest,StartEncryptionFailsAsLowEnergyPeripheral)428 TEST_F(ConnectionTest, StartEncryptionFailsAsLowEnergyPeripheral) {
429   auto conn =
430       NewLEConnection(pw::bluetooth::emboss::ConnectionRole::PERIPHERAL);
431   conn->set_ltk(hci_spec::LinkKey());
432   EXPECT_FALSE(conn->StartEncryption());
433   EXPECT_CMD_PACKET_OUT(test_device(),
434                         bt::testing::DisconnectPacket(kTestHandle));
435 }
436 
TEST_F(ConnectionTest,StartEncryptionSucceedsAsLowEnergyCentral)437 TEST_F(ConnectionTest, StartEncryptionSucceedsAsLowEnergyCentral) {
438   auto conn = NewLEConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL);
439   auto ltk = hci_spec::LinkKey();
440   conn->set_ltk(ltk);
441   EXPECT_TRUE(conn->StartEncryption());
442   EXPECT_CMD_PACKET_OUT(test_device(),
443                         bt::testing::LEStartEncryptionPacket(
444                             kTestHandle, ltk.rand(), ltk.ediv(), ltk.value()));
445 }
446 
TEST_F(ConnectionTest,StartEncryptionSucceedsWithBrEdrLinkKeyType)447 TEST_F(ConnectionTest, StartEncryptionSucceedsWithBrEdrLinkKeyType) {
448   auto conn = NewACLConnection();
449   conn->set_link_key(hci_spec::LinkKey(), kLinkKeyType);
450   EXPECT_TRUE(conn->StartEncryption());
451   EXPECT_CMD_PACKET_OUT(
452       test_device(),
453       bt::testing::SetConnectionEncryption(kTestHandle, /*enable=*/true));
454 }
455 
TEST_P(LinkTypeConnectionTest,DisconnectError)456 TEST_P(LinkTypeConnectionTest, DisconnectError) {
457   // clang-format off
458 
459   // Respond with Command Status and Disconnection Complete.
460   StaticByteBuffer cmd_status_bytes(
461       hci_spec::kCommandStatusEventCode, 0x04, pw::bluetooth::emboss::StatusCode::SUCCESS, 1,
462       0x06, 0x04);
463 
464   StaticByteBuffer disc_cmpl_bytes(
465       hci_spec::kDisconnectionCompleteEventCode, 0x04,
466       pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED, 0x01, 0x00,
467       pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_BY_LOCAL_HOST);
468 
469   // clang-format on
470 
471   EXPECT_CMD_PACKET_OUT(
472       test_device(), kDisconnectCommand, &cmd_status_bytes, &disc_cmpl_bytes);
473 
474   // The callback should get called regardless of the procedure status.
475   bool callback_called = false;
476   test_device()->SetTransactionCallback(
477       [&callback_called] { callback_called = true; });
478 
479   auto connection = NewConnection();
480 
481   connection->Disconnect(
482       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION);
483 
484   RunUntilIdle();
485   EXPECT_TRUE(callback_called);
486 }
487 
TEST_P(LinkTypeConnectionTest,StartEncryptionNoLinkKey)488 TEST_P(LinkTypeConnectionTest, StartEncryptionNoLinkKey) {
489   auto conn = NewConnection();
490   EXPECT_FALSE(conn->StartEncryption());
491   EXPECT_CMD_PACKET_OUT(test_device(),
492                         bt::testing::DisconnectPacket(kTestHandle));
493 }
494 
495 // HCI Command Status event is received with an error status.
TEST_F(ConnectionTest,LEStartEncryptionFailsAtStatus)496 TEST_F(ConnectionTest, LEStartEncryptionFailsAtStatus) {
497   // clang-format off
498   StaticByteBuffer kExpectedCommand(
499     0x19, 0x20,  // HCI_LE_Start_Encryption
500     28,          // parameter total size
501     0x01, 0x00,  // connection handle: 1
502     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // rand: 1
503     0xFF, 0x00,  // ediv: 255
504     1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16  // LTK
505   );
506   StaticByteBuffer kErrorStatus(
507     0x0F,       // HCI Command Status event code
508     4,          // parameter total size
509     0x0C,       // "Command Disallowed" error
510     1,          // num_hci_command_packets
511     0x19, 0x20  // opcode: HCI_LE_Start_Encryption
512   );
513   // clang-format on
514 
515   EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kErrorStatus);
516 
517   bool callback = false;
518   auto conn = NewLEConnection();
519   conn->set_ltk(hci_spec::LinkKey(kLTK, kRand, kEDiv));
520   conn->set_encryption_change_callback([&](Result<bool> result) {
521     ASSERT_TRUE(result.is_error());
522     EXPECT_TRUE(result.error_value().is(
523         pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED));
524     callback = true;
525   });
526 
527   EXPECT_TRUE(conn->StartEncryption());
528 
529   RunUntilIdle();
530   EXPECT_TRUE(callback);
531   EXPECT_CMD_PACKET_OUT(test_device(),
532                         bt::testing::DisconnectPacket(kTestHandle));
533 }
534 
TEST_F(ConnectionTest,LEStartEncryptionSendsSetLeConnectionEncryptionCommand)535 TEST_F(ConnectionTest, LEStartEncryptionSendsSetLeConnectionEncryptionCommand) {
536   StaticByteBuffer kExpectedCommand(0x19,
537                                     0x20,  // HCI_LE_Start_Encryption
538                                     28,    // parameter total size
539                                     0x01,
540                                     0x00,  // connection handle: 1
541                                     0x01,
542                                     0x00,
543                                     0x00,
544                                     0x00,
545                                     0x00,
546                                     0x00,
547                                     0x00,
548                                     0x00,  // rand: 1
549                                     0xFF,
550                                     0x00,  // ediv: 255
551                                     1,
552                                     2,
553                                     3,
554                                     4,
555                                     5,
556                                     6,
557                                     7,
558                                     8,
559                                     9,
560                                     10,
561                                     11,
562                                     12,
563                                     13,
564                                     14,
565                                     15,
566                                     16  // LTK
567   );
568   StaticByteBuffer kStatus(0x0F,  // HCI Command Status event code
569                            4,     // parameter total size
570                            0x00,  // success status
571                            1,     // num_hci_command_packets
572                            0x19,
573                            0x20  // opcode: HCI_LE_Start_Encryption
574   );
575 
576   EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kStatus);
577 
578   bool callback = false;
579   auto conn = NewLEConnection();
580   conn->set_ltk(hci_spec::LinkKey(kLTK, kRand, kEDiv));
581   conn->set_encryption_change_callback([&](auto) { callback = true; });
582 
583   EXPECT_TRUE(conn->StartEncryption());
584 
585   // Callback shouldn't be called until the controller sends an encryption
586   // changed event.
587   RunUntilIdle();
588   EXPECT_FALSE(callback);
589   EXPECT_CMD_PACKET_OUT(test_device(),
590                         bt::testing::DisconnectPacket(kTestHandle));
591 }
592 
593 // HCI Command Status event is received with an error status.
TEST_F(ConnectionTest,AclStartEncryptionFailsAtStatus)594 TEST_F(ConnectionTest, AclStartEncryptionFailsAtStatus) {
595   StaticByteBuffer kExpectedCommand(0x13,
596                                     0x04,  // HCI_Set_Connection_Encryption
597                                     3,     // parameter total size
598                                     0x01,
599                                     0x00,  // connection handle
600                                     0x01   // encryption enable
601   );
602   StaticByteBuffer kErrorStatus(0x0F,  // HCI Command Status event code
603                                 4,     // parameter total size
604                                 0x0C,  // "Command Disallowed" error
605                                 1,     // num_hci_command_packets
606                                 0x13,
607                                 0x04  // opcode: HCI_Set_Connection_Encryption
608   );
609 
610   EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kErrorStatus);
611 
612   bool callback = false;
613   auto conn = NewACLConnection();
614   conn->set_link_key(hci_spec::LinkKey(kLTK, 0, 0), kLinkKeyType);
615   conn->set_encryption_change_callback([&](Result<bool> result) {
616     ASSERT_TRUE(result.is_error());
617     EXPECT_TRUE(result.error_value().is(
618         pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED));
619     callback = true;
620   });
621 
622   EXPECT_TRUE(conn->StartEncryption());
623 
624   RunUntilIdle();
625   EXPECT_TRUE(callback);
626   EXPECT_CMD_PACKET_OUT(test_device(),
627                         bt::testing::DisconnectPacket(kTestHandle));
628 }
629 
TEST_F(ConnectionTest,AclStartEncryptionSendsSetConnectionEncryptionCommand)630 TEST_F(ConnectionTest, AclStartEncryptionSendsSetConnectionEncryptionCommand) {
631   StaticByteBuffer kExpectedCommand(0x13,
632                                     0x04,  // HCI_Set_Connection_Encryption
633                                     3,     // parameter total size
634                                     0x01,
635                                     0x00,  // connection handle
636                                     0x01   // encryption enable
637   );
638   StaticByteBuffer kStatus(0x0F,  // HCI Command Status event code
639                            4,     // parameter total size
640                            0x00,  // success status
641                            1,     // num_hci_command_packets
642                            0x13,
643                            0x04  // opcode: HCI_Set_Connection_Encryption
644   );
645 
646   EXPECT_CMD_PACKET_OUT(test_device(), kExpectedCommand, &kStatus);
647 
648   bool callback = false;
649   auto conn = NewACLConnection();
650   conn->set_link_key(hci_spec::LinkKey(kLTK, 0, 0), kLinkKeyType);
651   conn->set_encryption_change_callback([&](auto) { callback = true; });
652 
653   EXPECT_TRUE(conn->StartEncryption());
654 
655   // Callback shouldn't be called until the controller sends an encryption
656   // changed event.
657   RunUntilIdle();
658   EXPECT_FALSE(callback);
659   EXPECT_CMD_PACKET_OUT(test_device(),
660                         bt::testing::DisconnectPacket(kTestHandle));
661 }
662 
TEST_P(LinkTypeConnectionTest,EncryptionChangeIgnoredEvents)663 TEST_P(LinkTypeConnectionTest, EncryptionChangeIgnoredEvents) {
664   // clang-format off
665   StaticByteBuffer kEncChangeMalformed(
666     0x08,       // HCI Encryption Change event code
667     3,          // parameter total size
668     0x00,       // status
669     0x01, 0x00  // connection handle: 1
670     // Last byte missing
671   );
672   StaticByteBuffer kEncChangeWrongHandle(
673     0x08,        // HCI Encryption Change event code
674     4,           // parameter total size
675     0x00,        // status
676     0x02, 0x00,  // connection handle: 2
677     0x01         // encryption enabled
678   );
679   // clang-format on
680 
681   bool callback = false;
682   auto conn = NewConnection();
683   SetTestLinkKey(conn.get());
684   conn->set_encryption_change_callback([&](auto) { callback = true; });
685 
686   test_device()->SendCommandChannelPacket(kEncChangeMalformed);
687   test_device()->SendCommandChannelPacket(kEncChangeWrongHandle);
688 
689   RunUntilIdle();
690   EXPECT_FALSE(callback);
691   EXPECT_CMD_PACKET_OUT(test_device(),
692                         bt::testing::DisconnectPacket(kTestHandle));
693 }
694 
TEST_P(LinkTypeConnectionTest,EncryptionChangeEvents)695 TEST_P(LinkTypeConnectionTest, EncryptionChangeEvents) {
696   // clang-format off
697   StaticByteBuffer kEncryptionChangeEventDisabled(
698     0x08,        // HCI Encryption Change event code
699     4,           // parameter total size
700     0x00,        // status
701     0x01, 0x00,  // connection handle: 1
702     0x00         // encryption disabled
703   );
704   StaticByteBuffer kEncryptionChangeEventFailed(
705     0x08,        // HCI Encryption Change event code
706     4,           // parameter total size
707     0x06,        // status: Pin or Key missing
708     0x01, 0x00,  // connection handle: 1
709     0x00         // encryption disabled
710   );
711 
712   StaticByteBuffer kKeySizeComplete(
713     0x0E,        // event code: Command Complete
714     0x07,        // parameters total size
715     0xFF,        // num command packets allowed (255)
716     0x08, 0x14,  // original opcode
717 
718     // return parameters
719     0x00,        // status (success)
720     0x01, 0x00,  // connection handle: 0x0001
721     0x10         // encryption key size: 16
722   );
723   // clang-format on
724 
725   int callback_count = 0;
726   auto conn = NewConnection();
727 
728   Result<bool> result = fit::error(Error(HostError::kFailed));
729   conn->set_encryption_change_callback([&](Result<bool> cb_result) {
730     callback_count++;
731     result = cb_result;
732   });
733 
734   if (GetParam() == bt::LinkType::kACL) {
735     // The host tries to validate the size of key used to encrypt ACL links.
736     EXPECT_CMD_PACKET_OUT(
737         test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
738   }
739 
740   test_device()->SendCommandChannelPacket(
741       bt::testing::EncryptionChangeEventPacket(
742           pw::bluetooth::emboss::StatusCode::SUCCESS,
743           kTestHandle,
744           hci_spec::EncryptionStatus::kOn));
745   RunUntilIdle();
746 
747   EXPECT_EQ(1, callback_count);
748   EXPECT_EQ(fit::ok(), result);
749   EXPECT_TRUE(result.value_or(false));
750 
751   test_device()->SendCommandChannelPacket(kEncryptionChangeEventDisabled);
752   RunUntilIdle();
753 
754   EXPECT_EQ(2, callback_count);
755   EXPECT_EQ(fit::ok(), result);
756   EXPECT_FALSE(result.value_or(true));
757 
758   // The host should disconnect the link if encryption fails.
759   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
760   test_device()->SendCommandChannelPacket(kEncryptionChangeEventFailed);
761   RunUntilIdle();
762 
763   EXPECT_EQ(3, callback_count);
764   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING)
765                 .error_value(),
766             result);
767 }
768 
TEST_F(ConnectionTest,EncryptionFailureNotifiesPeerDisconnectCallback)769 TEST_F(ConnectionTest, EncryptionFailureNotifiesPeerDisconnectCallback) {
770   bool peer_disconnect_callback_received = false;
771   auto conn = NewLEConnection();
772   conn->set_peer_disconnect_callback([&](const auto& self, auto /*reason*/) {
773     EXPECT_EQ(conn.get(), &self);
774     peer_disconnect_callback_received = true;
775   });
776 
777   // Send the encryption change failure. The host should disconnect the link as
778   // a result.
779   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
780   test_device()->SendCommandChannelPacket(
781       bt::testing::EncryptionChangeEventPacket(
782           pw::bluetooth::emboss::StatusCode::CONNECTION_TERMINATED_MIC_FAILURE,
783           kTestHandle,
784           hci_spec::EncryptionStatus::kOff));
785   RunUntilIdle();
786   EXPECT_FALSE(peer_disconnect_callback_received);
787 
788   // Send the disconnection complete resulting from the encryption failure (this
789   // usually does not correspond to the Disconnect command sent by
790   // hci::Connection, which will cause a later subsequent event).
791   test_device()->SendCommandChannelPacket(
792       bt::testing::DisconnectionCompletePacket(
793           kTestHandle,
794           pw::bluetooth::emboss::StatusCode::
795               CONNECTION_TERMINATED_MIC_FAILURE));
796   RunUntilIdle();
797   EXPECT_TRUE(peer_disconnect_callback_received);
798 }
799 
TEST_F(ConnectionTest,AclEncryptionEnableCanNotReadKeySizeClosesLink)800 TEST_F(ConnectionTest, AclEncryptionEnableCanNotReadKeySizeClosesLink) {
801   StaticByteBuffer kKeySizeComplete(0x0E,  // event code: Command Complete
802                                     0x07,  // parameters total size
803                                     0xFF,  // num command packets allowed (255)
804                                     0x08,
805                                     0x14,  // original opcode
806 
807                                     // return parameters
808                                     0x2F,  // status (insufficient security)
809                                     0x01,
810                                     0x00,  // connection handle: 0x0001
811                                     0x10   // encryption key size: 16
812   );
813 
814   int callback_count = 0;
815   auto conn = NewACLConnection();
816   conn->set_encryption_change_callback([&callback_count](Result<bool> result) {
817     callback_count++;
818     EXPECT_TRUE(result.is_error());
819   });
820 
821   EXPECT_CMD_PACKET_OUT(
822       test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
823   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
824   test_device()->SendCommandChannelPacket(
825       bt::testing::EncryptionChangeEventPacket(
826           pw::bluetooth::emboss::StatusCode::SUCCESS,
827           kTestHandle,
828           hci_spec::EncryptionStatus::kOn));
829   RunUntilIdle();
830 
831   EXPECT_EQ(1, callback_count);
832 }
833 
TEST_F(ConnectionTest,AclEncryptionEnableKeySizeOneByteClosesLink)834 TEST_F(ConnectionTest, AclEncryptionEnableKeySizeOneByteClosesLink) {
835   StaticByteBuffer kKeySizeComplete(0x0E,  // event code: Command Complete
836                                     0x07,  // parameters total size
837                                     0xFF,  // num command packets allowed (255)
838                                     0x08,
839                                     0x14,  // original opcode
840 
841                                     // return parameters
842                                     0x00,  // status (success)
843                                     0x01,
844                                     0x00,  // connection handle: 0x0001
845                                     0x01   // encryption key size: 1
846   );
847 
848   int callback_count = 0;
849   auto conn = NewACLConnection();
850   conn->set_encryption_change_callback([&callback_count](Result<bool> result) {
851     callback_count++;
852     EXPECT_TRUE(result.is_error());
853   });
854 
855   EXPECT_CMD_PACKET_OUT(
856       test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
857   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
858   test_device()->SendCommandChannelPacket(
859       bt::testing::EncryptionChangeEventPacket(
860           pw::bluetooth::emboss::StatusCode::SUCCESS,
861           kTestHandle,
862           hci_spec::EncryptionStatus::kOn));
863   RunUntilIdle();
864 
865   EXPECT_EQ(1, callback_count);
866 }
867 
TEST_F(ConnectionTest,SecureConnectionsSucceedsWithAESEncryptionAlgorithm)868 TEST_F(ConnectionTest, SecureConnectionsSucceedsWithAESEncryptionAlgorithm) {
869   StaticByteBuffer kKeySizeComplete(0x0E,  // event code: Command Complete
870                                     0x07,  // parameters total size
871                                     0xFF,  // num command packets allowed (255)
872                                     0x08,
873                                     0x14,  // original opcode
874 
875                                     // return parameters
876                                     0x00,  // status (success)
877                                     0x01,
878                                     0x00,  // connection handle: 0x0001
879                                     0x10   // encryption key size: 16
880   );
881 
882   std::unique_ptr<BrEdrConnection> connection = NewACLConnection(
883       pw::bluetooth::emboss::ConnectionRole::CENTRAL, kTestHandle);
884 
885   int callback_count = 0;
886   Result<bool> result = fit::error(Error(HostError::kFailed));
887   connection->set_encryption_change_callback([&](Result<bool> cb_result) {
888     callback_count++;
889     result = cb_result;
890   });
891 
892   EXPECT_CMD_PACKET_OUT(
893       test_device(), kReadEncryptionKeySizeCommand, &kKeySizeComplete);
894   test_device()->SendCommandChannelPacket(
895       bt::testing::EncryptionChangeEventPacket(
896           pw::bluetooth::emboss::StatusCode::SUCCESS,
897           kTestHandle,
898           hci_spec::EncryptionStatus::kBredrSecureConnections));
899   RunUntilIdle();
900 
901   EXPECT_EQ(1, callback_count);
902   EXPECT_EQ(fit::ok(), result);
903   EXPECT_TRUE(result.value_or(false));
904 
905   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommand);
906   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
907 }
908 
TEST_F(ConnectionTest,EncryptionSecureConnectionsWrongAlgorithmClosesLink)909 TEST_F(ConnectionTest, EncryptionSecureConnectionsWrongAlgorithmClosesLink) {
910   std::unique_ptr<BrEdrConnection> connection = NewACLConnection(
911       pw::bluetooth::emboss::ConnectionRole::CENTRAL, kTestHandle);
912 
913   connection->set_use_secure_connections(true);
914 
915   int callback_count = 0;
916   Result<bool> result = fit::error(Error(HostError::kFailed));
917   connection->set_encryption_change_callback([&](Result<bool> cb_result) {
918     ASSERT_TRUE(cb_result.is_error());
919     EXPECT_TRUE(cb_result.error_value().is(HostError::kInsufficientSecurity));
920     callback_count++;
921     result = cb_result;
922   });
923 
924   // The host should disconnect the link if encryption fails.
925   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
926   test_device()->SendCommandChannelPacket(
927       bt::testing::EncryptionChangeEventPacket(
928           pw::bluetooth::emboss::StatusCode::SUCCESS,
929           kTestHandle,
930           hci_spec::EncryptionStatus::kOn));
931   RunUntilIdle();
932 
933   EXPECT_EQ(1, callback_count);
934   EXPECT_TRUE(result.is_error());
935 
936   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
937 }
938 
TEST_P(LinkTypeConnectionTest,EncryptionKeyRefreshEvents)939 TEST_P(LinkTypeConnectionTest, EncryptionKeyRefreshEvents) {
940   // clang-format off
941   StaticByteBuffer kEncryptionKeyRefresh(
942     0x30,       // HCI Encryption Key Refresh Complete event
943     3,          // parameter total size
944     0x00,       // status
945     0x01, 0x00  // connection handle: 1
946   );
947   StaticByteBuffer kEncryptionKeyRefreshFailed(
948     0x30,       // HCI Encryption Key Refresh Complete event
949     3,          // parameter total size
950     0x06,       // status: Pin or Key missing
951     0x01, 0x00  // connection handle: 1
952   );
953   // clang-format on
954 
955   int callback_count = 0;
956   auto conn = NewConnection();
957 
958   Result<bool> result = fit::error(Error(HostError::kFailed));
959   conn->set_encryption_change_callback([&](Result<bool> cb_result) {
960     callback_count++;
961     result = cb_result;
962   });
963 
964   test_device()->SendCommandChannelPacket(kEncryptionKeyRefresh);
965   RunUntilIdle();
966 
967   EXPECT_EQ(1, callback_count);
968   ASSERT_EQ(fit::ok(), result);
969   EXPECT_TRUE(result.value());
970 
971   // The host should disconnect the link if encryption fails.
972   EXPECT_CMD_PACKET_OUT(test_device(), kDisconnectCommandAuthFailure);
973   test_device()->SendCommandChannelPacket(kEncryptionKeyRefreshFailed);
974   RunUntilIdle();
975 
976   EXPECT_EQ(2, callback_count);
977   EXPECT_EQ(ToResult(pw::bluetooth::emboss::StatusCode::PIN_OR_KEY_MISSING)
978                 .error_value(),
979             result);
980 }
981 
TEST_F(ConnectionTest,LELongTermKeyRequestIgnoredEvent)982 TEST_F(ConnectionTest, LELongTermKeyRequestIgnoredEvent) {
983   // clang-format off
984   StaticByteBuffer kMalformed(
985     0x3E,        // LE Meta Event code
986     12,          // parameter total size
987     0x05,        // LE LTK Request subevent code
988     0x01, 0x00,  // connection handle: 1
989 
990     // rand:
991     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992 
993     // ediv: (missing 1 byte)
994     0x00
995   );
996   StaticByteBuffer kWrongHandle(
997     0x3E,        // LE Meta Event code
998     13,          // parameter total size
999     0x05,        // LE LTK Request subevent code
1000     0x02, 0x00,  // connection handle: 2 (wrong)
1001 
1002     // rand: 0
1003     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1004 
1005     // ediv: 0
1006     0x00, 0x00
1007   );
1008   // clang-format on
1009 
1010   auto conn = NewLEConnection();
1011   conn->set_ltk(hci_spec::LinkKey(kLTK, 0, 0));
1012 
1013   test_device()->SendCommandChannelPacket(kMalformed);
1014   test_device()->SendCommandChannelPacket(kWrongHandle);
1015 
1016   RunUntilIdle();
1017 
1018   // Test will fail if the connection sends a response without ignoring these
1019   // events.
1020   EXPECT_CMD_PACKET_OUT(test_device(),
1021                         bt::testing::DisconnectPacket(kTestHandle));
1022 }
1023 
TEST_F(ConnectionTest,LELongTermKeyRequestNoKey)1024 TEST_F(ConnectionTest, LELongTermKeyRequestNoKey) {
1025   // clang-format off
1026   StaticByteBuffer kEvent(
1027     0x3E,        // LE Meta Event code
1028     13,          // parameter total size
1029     0x05,        // LE LTK Request subevent code
1030     0x01, 0x00,  // connection handle: 2 (wrong)
1031 
1032     // rand: 0
1033     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1034 
1035     // ediv: 0
1036     0x00, 0x00
1037   );
1038   StaticByteBuffer kResponse(
1039     0x1B, 0x20,  // opcode: HCI_LE_Long_Term_Key_Request_Negative_Reply
1040     2,           // parameter total size
1041     0x01, 0x00   // connection handle: 1
1042   );
1043   // clang-format on
1044 
1045   // The request should be rejected since there is no LTK.
1046   EXPECT_CMD_PACKET_OUT(test_device(), kResponse);
1047   auto conn = NewLEConnection();
1048 
1049   test_device()->SendCommandChannelPacket(kEvent);
1050   RunUntilIdle();
1051 }
1052 
1053 // There is a link key but EDiv and Rand values don't match.
TEST_F(ConnectionTest,LELongTermKeyRequestNoMatchinKey)1054 TEST_F(ConnectionTest, LELongTermKeyRequestNoMatchinKey) {
1055   // clang-format off
1056   StaticByteBuffer kEvent(
1057     0x3E,        // LE Meta Event code
1058     13,          // parameter total size
1059     0x05,        // LE LTK Request subevent code
1060     0x01, 0x00,  // connection handle: 2 (wrong)
1061 
1062     // rand: 0
1063     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064 
1065     // ediv: 0
1066     0x00, 0x00
1067   );
1068   StaticByteBuffer kResponse(
1069     0x1B, 0x20,  // opcode: HCI_LE_Long_Term_Key_Request_Negative_Reply
1070     2,           // parameter total size
1071     0x01, 0x00   // connection handle: 1
1072   );
1073   // clang-format on
1074 
1075   // The request should be rejected since there is no LTK.
1076   EXPECT_CMD_PACKET_OUT(test_device(), kResponse);
1077   auto conn = NewLEConnection();
1078   conn->set_ltk(hci_spec::LinkKey(kLTK, 1, 1));
1079 
1080   test_device()->SendCommandChannelPacket(kEvent);
1081   RunUntilIdle();
1082 }
1083 
TEST_F(ConnectionTest,LELongTermKeyRequestReply)1084 TEST_F(ConnectionTest, LELongTermKeyRequestReply) {
1085   // clang-format off
1086   StaticByteBuffer kEvent(
1087     0x3E,        // LE Meta Event code
1088     13,          // parameter total size
1089     0x05,        // LE LTK Request subevent code
1090     0x01, 0x00,  // connection handle: 2 (wrong)
1091 
1092     // rand: 0x8899AABBCCDDEEFF
1093     0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88,
1094     // ediv: 0xBEEF
1095     0xEF, 0xBE
1096   );
1097   StaticByteBuffer kResponse(
1098     0x1A, 0x20,  // opcode: HCI_LE_Long_Term_Key_Request_Reply
1099     18,          // parameter total size
1100     0x01, 0x00,  // connection handle: 1
1101 
1102     // LTK:
1103     1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
1104   );
1105   // clang-format on
1106 
1107   // The request should be rejected since there is no LTK.
1108   EXPECT_CMD_PACKET_OUT(test_device(), kResponse);
1109   auto conn = NewLEConnection();
1110   conn->set_ltk(hci_spec::LinkKey(kLTK, 0x8899AABBCCDDEEFF, 0xBEEF));
1111 
1112   test_device()->SendCommandChannelPacket(kEvent);
1113   RunUntilIdle();
1114 }
1115 
TEST_F(ConnectionTest,QueuedPacketsGetDroppedOnDisconnectionCompleteAndStalePacketsAreNotSentOnHandleReuse)1116 TEST_F(
1117     ConnectionTest,
1118     QueuedPacketsGetDroppedOnDisconnectionCompleteAndStalePacketsAreNotSentOnHandleReuse) {
1119   const hci_spec::ConnectionHandle kHandle = 0x0001;
1120 
1121   // Should register connection with ACL Data Channel.
1122   FakeAclConnection acl_connection_0(
1123       acl_data_channel(), kHandle, bt::LinkType::kACL);
1124 
1125   acl_data_channel()->RegisterConnection(acl_connection_0.GetWeakPtr());
1126 
1127   // HCI Connection corresponding to |acl_connection_0|
1128   auto hci_connection_0 =
1129       NewACLConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle);
1130 
1131   // Fill up BR/EDR controller buffer then queue one additional packet
1132   for (size_t i = 0; i < kBrEdrBufferInfo.max_num_packets() + 1; i++) {
1133     // Last packet should remain queued
1134     if (i < kBrEdrBufferInfo.max_num_packets()) {
1135       const StaticByteBuffer kPacket(
1136           // ACL data header (handle: 0, length 1)
1137           LowerBits(kHandle),
1138           UpperBits(kHandle),
1139           // payload length
1140           0x01,
1141           0x00,
1142           // payload
1143           static_cast<uint8_t>(i));
1144       EXPECT_ACL_PACKET_OUT(test_device(), kPacket);
1145     }
1146     // Create packet to send
1147     ACLDataPacketPtr packet =
1148         ACLDataPacket::New(kHandle,
1149                            hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
1150                            hci_spec::ACLBroadcastFlag::kPointToPoint,
1151                            /*payload_size=*/1);
1152     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
1153     acl_connection_0.QueuePacket(std::move(packet));
1154     RunUntilIdle();
1155   }
1156   // Run until the data is flushed out to the MockController.
1157   RunUntilIdle();
1158 
1159   // Only packets that fit in buffer should have been received.
1160   EXPECT_EQ(acl_connection_0.queued_packets().size(), 1u);
1161   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
1162 
1163   acl_data_channel()->UnregisterConnection(kHandle);
1164 
1165   // All future packets received should be for the next connection.
1166   const auto disconnect_status_rsp =
1167       bt::testing::DisconnectStatusResponsePacket();
1168   DynamicByteBuffer disconnection_complete(
1169       bt::testing::DisconnectionCompletePacket(kHandle));
1170   EXPECT_CMD_PACKET_OUT(test_device(),
1171                         bt::testing::DisconnectPacket(kHandle),
1172                         &disconnect_status_rsp,
1173                         &disconnection_complete);
1174 
1175   // Disconnect |hci_connection_0| by destroying it. The received disconnection
1176   // complete event will cause the handler to clear pending packets.
1177   hci_connection_0.reset();
1178   RunUntilIdle();
1179 
1180   // Register connection with same handle.
1181   FakeAclConnection acl_connection_1(
1182       acl_data_channel(), kHandle, bt::LinkType::kACL);
1183 
1184   acl_data_channel()->RegisterConnection(acl_connection_1.GetWeakPtr());
1185 
1186   // HCI Connection corresponding to |acl_connection_1|
1187   auto hci_connection_1 =
1188       NewACLConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle);
1189 
1190   // Fill up BR/EDR controller buffer then queue one additional packet
1191   for (size_t i = 0; i < kBrEdrBufferInfo.max_num_packets() + 1; i++) {
1192     // Last packet should remain queued
1193     if (i < kBrEdrBufferInfo.max_num_packets()) {
1194       const StaticByteBuffer kPacket(
1195           // ACL data header (handle: 0, length 1)
1196           LowerBits(kHandle),
1197           UpperBits(kHandle),
1198           // payload length
1199           0x01,
1200           0x00,
1201           // payload
1202           static_cast<uint8_t>(i));
1203       EXPECT_ACL_PACKET_OUT(test_device(), kPacket);
1204     }
1205     // Create packet to send
1206     ACLDataPacketPtr packet =
1207         ACLDataPacket::New(kHandle,
1208                            hci_spec::ACLPacketBoundaryFlag::kFirstNonFlushable,
1209                            hci_spec::ACLBroadcastFlag::kPointToPoint,
1210                            /*payload_size=*/1);
1211     packet->mutable_view()->mutable_payload_data()[0] = static_cast<uint8_t>(i);
1212     acl_connection_1.QueuePacket(std::move(packet));
1213     RunUntilIdle();
1214   }
1215   // Run until the data is flushed out to the MockController.
1216   RunUntilIdle();
1217 
1218   EXPECT_EQ(acl_connection_1.queued_packets().size(), 1u);
1219   EXPECT_TRUE(test_device()->AllExpectedDataPacketsSent());
1220 
1221   acl_data_channel()->UnregisterConnection(kHandle);
1222 
1223   // Disconnect |hci_connection_1| by destroying it. The received disconnection
1224   // complete event will cause the handler to clear pending packets.
1225   hci_connection_1.reset();
1226   EXPECT_CMD_PACKET_OUT(test_device(),
1227                         bt::testing::DisconnectPacket(kHandle),
1228                         &disconnect_status_rsp,
1229                         &disconnection_complete);
1230   RunUntilIdle();
1231 }
1232 
TEST_F(ConnectionTest,PeerDisconnectCallback)1233 TEST_F(ConnectionTest, PeerDisconnectCallback) {
1234   const hci_spec::ConnectionHandle kHandle = 0x0001;
1235 
1236   auto conn =
1237       NewACLConnection(pw::bluetooth::emboss::ConnectionRole::CENTRAL, kHandle);
1238 
1239   size_t cb_count = 0;
1240   auto disconn_complete_cb = [&](const Connection&, auto /*reason*/) {
1241     cb_count++;
1242 
1243     // Should be safe to destroy connection from this callback, as a connection
1244     // manager does.
1245     conn.reset();
1246   };
1247   conn->set_peer_disconnect_callback(disconn_complete_cb);
1248 
1249   RunUntilIdle();
1250   EXPECT_EQ(0u, cb_count);
1251 
1252   DynamicByteBuffer disconnection_complete(
1253       bt::testing::DisconnectionCompletePacket(kHandle));
1254   test_device()->SendCommandChannelPacket(disconnection_complete);
1255   RunUntilIdle();
1256 
1257   EXPECT_EQ(1u, cb_count);
1258 }
1259 
1260 // Test connection handling cases for all types of links.
1261 INSTANTIATE_TEST_SUITE_P(ConnectionTest,
1262                          LinkTypeConnectionTest,
1263                          ::testing::Values(bt::LinkType::kACL,
1264                                            bt::LinkType::kLE));
1265 
1266 }  // namespace
1267 }  // namespace bt::hci
1268