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