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