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