• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_bluetooth_sapphire/internal/host/sco/sco_connection_manager.h"
15 
16 #include <optional>
17 
18 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
19 #include "pw_bluetooth_sapphire/internal/host/testing/mock_controller.h"
20 #include "pw_bluetooth_sapphire/internal/host/testing/test_packets.h"
21 
22 namespace bt::sco {
23 namespace {
24 
25 using OpenConnectionResult = ScoConnectionManager::OpenConnectionResult;
26 using AcceptConnectionResult = ScoConnectionManager::AcceptConnectionResult;
27 
28 constexpr hci_spec::ConnectionHandle kAclConnectionHandle = 0x40;
29 constexpr hci_spec::ConnectionHandle kScoConnectionHandle = 0x41;
30 const DeviceAddress kLocalAddress(DeviceAddress::Type::kBREDR,
31                                   {0x00, 0x00, 0x00, 0x00, 0x00, 0x01});
32 const DeviceAddress kPeerAddress(DeviceAddress::Type::kBREDR,
33                                  {0x00, 0x00, 0x00, 0x00, 0x00, 0x02});
34 bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
35     kConnectionParams;
36 
37 bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
InitializeConnectionParams()38 InitializeConnectionParams() {
39   bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
40       out;
41   auto view = out.view();
42   view.transmit_bandwidth().Write(1);
43   view.receive_bandwidth().Write(2);
44   view.transmit_coding_format().coding_format().Write(
45       pw::bluetooth::emboss::CodingFormat::MSBC);
46   view.transmit_coding_format().company_id().Write(3);
47   view.transmit_coding_format().vendor_codec_id().Write(4);
48   view.receive_coding_format().coding_format().Write(
49       pw::bluetooth::emboss::CodingFormat::CVSD);
50   view.receive_coding_format().company_id().Write(5);
51   view.receive_coding_format().vendor_codec_id().Write(6);
52   view.transmit_codec_frame_size_bytes().Write(7);
53   view.receive_codec_frame_size_bytes().Write(8);
54   view.input_bandwidth().Write(9);
55   view.output_bandwidth().Write(10);
56   view.input_coding_format().coding_format().Write(
57       pw::bluetooth::emboss::CodingFormat::A_LAW);
58   view.input_coding_format().company_id().Write(11);
59   view.input_coding_format().vendor_codec_id().Write(12);
60   view.output_coding_format().coding_format().Write(
61       pw::bluetooth::emboss::CodingFormat::LINEAR_PCM);
62   view.output_coding_format().company_id().Write(13);
63   view.output_coding_format().vendor_codec_id().Write(14);
64   view.input_coded_data_size_bits().Write(15);
65   view.output_coded_data_size_bits().Write(16);
66   view.input_pcm_data_format().Write(
67       pw::bluetooth::emboss::PcmDataFormat::ONES_COMPLEMENT);
68   view.output_pcm_data_format().Write(
69       pw::bluetooth::emboss::PcmDataFormat::TWOS_COMPLEMENT);
70   view.input_pcm_sample_payload_msb_position().Write(17);
71   view.output_pcm_sample_payload_msb_position().Write(18);
72   view.input_data_path().Write(
73       pw::bluetooth::emboss::ScoDataPath::AUDIO_TEST_MODE);
74   view.output_data_path().Write(pw::bluetooth::emboss::ScoDataPath::HCI);
75   view.input_transport_unit_size_bits().Write(19);
76   view.output_transport_unit_size_bits().Write(20);
77   view.max_latency_ms().Write(21);
78   view.packet_types().BackingStorage().WriteUInt(0x003F);  // All packet types
79   view.retransmission_effort().Write(
80       pw::bluetooth::emboss::SynchronousConnectionParameters::
81           ScoRetransmissionEffort::QUALITY_OPTIMIZED);
82   return out;
83 }
84 
85 bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
ScoConnectionParams()86 ScoConnectionParams() {
87   auto params = kConnectionParams;
88   params.view().packet_types().BackingStorage().WriteUInt(0);
89   params.view().packet_types().hv3().Write(true);
90   return params;
91 }
92 
93 bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
EscoConnectionParams()94 EscoConnectionParams() {
95   auto params = kConnectionParams;
96   params.view().packet_types().BackingStorage().WriteUInt(0);
97   params.view().packet_types().ev3().Write(true);
98   return params;
99 }
100 
101 using TestingBase =
102     bt::testing::FakeDispatcherControllerTest<bt::testing::MockController>;
103 
104 // Activate a SCO connection and set the close handler to call Deactivate()
activate_connection(OpenConnectionResult & result)105 void activate_connection(OpenConnectionResult& result) {
106   if (result.is_ok()) {
107     result.value()->Activate(
108         /*rx_callback=*/[]() {},
109         /*closed_callback=*/[result] { result.value()->Deactivate(); });
110   };
111 }
112 
113 class ScoConnectionManagerTest : public TestingBase {
114  public:
115   ScoConnectionManagerTest() = default;
116   ~ScoConnectionManagerTest() override = default;
117 
SetUp()118   void SetUp() override {
119     TestingBase::SetUp();
120     InitializeACLDataChannel();
121     InitializeScoDataChannel();
122 
123     manager_ =
124         std::make_unique<ScoConnectionManager>(PeerId(1),
125                                                kAclConnectionHandle,
126                                                kPeerAddress,
127                                                kLocalAddress,
128                                                transport()->GetWeakPtr());
129     kConnectionParams = InitializeConnectionParams();
130   }
131 
TearDown()132   void TearDown() override {
133     manager_.reset();
134     RunUntilIdle();
135     TestingBase::TearDown();
136   }
137 
DestroyManager()138   void DestroyManager() { manager_.reset(); }
139 
manager() const140   ScoConnectionManager* manager() const { return manager_.get(); }
141 
142  private:
143   std::unique_ptr<ScoConnectionManager> manager_;
144 
145   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ScoConnectionManagerTest);
146 };
147 
TEST_F(ScoConnectionManagerTest,OpenConnectionSuccess)148 TEST_F(ScoConnectionManagerTest, OpenConnectionSuccess) {
149   auto setup_status_packet = testing::CommandStatusPacket(
150       hci_spec::kEnhancedSetupSynchronousConnection,
151       pw::bluetooth::emboss::StatusCode::SUCCESS);
152   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
153       kScoConnectionHandle,
154       kPeerAddress,
155       hci_spec::LinkType::kExtendedSCO,
156       pw::bluetooth::emboss::StatusCode::SUCCESS);
157   EXPECT_CMD_PACKET_OUT(test_device(),
158                         testing::EnhancedSetupSynchronousConnectionPacket(
159                             kAclConnectionHandle, kConnectionParams),
160                         &setup_status_packet,
161                         &conn_complete_packet);
162 
163   std::optional<OpenConnectionResult> conn_result;
164   auto conn_cb = [&conn_result](auto result) {
165     activate_connection(result);
166     conn_result = std::move(result);
167   };
168 
169   auto req_handle =
170       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
171 
172   RunUntilIdle();
173   ASSERT_TRUE(conn_result.has_value());
174   ASSERT_TRUE(conn_result->is_ok());
175   ASSERT_TRUE(conn_result->value().is_alive());
176   EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);
177 
178   EXPECT_CMD_PACKET_OUT(test_device(),
179                         testing::DisconnectPacket(kScoConnectionHandle));
180   conn_result->value()->Close();
181   RunUntilIdle();
182 }
183 
TEST_F(ScoConnectionManagerTest,OpenConnectionAndReceiveFailureStatusEvent)184 TEST_F(ScoConnectionManagerTest, OpenConnectionAndReceiveFailureStatusEvent) {
185   auto setup_status_packet = testing::CommandStatusPacket(
186       hci_spec::kEnhancedSetupSynchronousConnection,
187       pw::bluetooth::emboss::StatusCode::CONNECTION_LIMIT_EXCEEDED);
188   EXPECT_CMD_PACKET_OUT(test_device(),
189                         testing::EnhancedSetupSynchronousConnectionPacket(
190                             kAclConnectionHandle, kConnectionParams),
191                         &setup_status_packet);
192 
193   std::optional<OpenConnectionResult> conn;
194   auto conn_cb = [&conn](auto cb_result) {
195     activate_connection(cb_result);
196     conn = std::move(cb_result);
197   };
198 
199   auto req_handle =
200       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
201 
202   RunUntilIdle();
203   ASSERT_TRUE(conn.has_value());
204   ASSERT_TRUE(conn->is_error());
205   EXPECT_EQ(conn->error_value(), HostError::kFailed);
206 }
207 
TEST_F(ScoConnectionManagerTest,OpenConnectionAndReceiveFailureCompleteEvent)208 TEST_F(ScoConnectionManagerTest, OpenConnectionAndReceiveFailureCompleteEvent) {
209   auto setup_status_packet = testing::CommandStatusPacket(
210       hci_spec::kEnhancedSetupSynchronousConnection,
211       pw::bluetooth::emboss::StatusCode::SUCCESS);
212   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
213       kScoConnectionHandle,
214       kPeerAddress,
215       hci_spec::LinkType::kExtendedSCO,
216       pw::bluetooth::emboss::StatusCode::CONNECTION_FAILED_TO_BE_ESTABLISHED);
217   EXPECT_CMD_PACKET_OUT(test_device(),
218                         testing::EnhancedSetupSynchronousConnectionPacket(
219                             kAclConnectionHandle, kConnectionParams),
220                         &setup_status_packet,
221                         &conn_complete_packet);
222 
223   std::optional<OpenConnectionResult> conn;
224   auto conn_cb = [&conn](auto cb_result) {
225     activate_connection(cb_result);
226     conn = std::move(cb_result);
227   };
228 
229   auto req_handle =
230       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
231 
232   RunUntilIdle();
233   ASSERT_TRUE(conn.has_value());
234   ASSERT_TRUE(conn->is_error());
235   EXPECT_EQ(conn->error_value(), HostError::kFailed);
236 }
237 
TEST_F(ScoConnectionManagerTest,AcceptConnectionCompleteEventErrorAndResultCallbackDestroysRequestHandle)238 TEST_F(
239     ScoConnectionManagerTest,
240     AcceptConnectionCompleteEventErrorAndResultCallbackDestroysRequestHandle) {
241   std::optional<AcceptConnectionResult> conn;
242   std::optional<ScoConnectionManager::RequestHandle> req_handle;
243   auto conn_cb = [&conn, &req_handle](auto cb_result) {
244     req_handle.reset();
245     conn = std::move(cb_result);
246   };
247 
248   req_handle =
249       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
250 
251   auto conn_req_packet =
252       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
253   test_device()->SendCommandChannelPacket(conn_req_packet);
254 
255   auto accept_status_packet = testing::CommandStatusPacket(
256       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
257       pw::bluetooth::emboss::StatusCode::UNSPECIFIED_ERROR);
258   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
259       kScoConnectionHandle,
260       kPeerAddress,
261       hci_spec::LinkType::kExtendedSCO,
262       pw::bluetooth::emboss::StatusCode::CONNECTION_ACCEPT_TIMEOUT_EXCEEDED);
263   EXPECT_CMD_PACKET_OUT(
264       test_device(),
265       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
266           kPeerAddress, kConnectionParams),
267       &accept_status_packet,
268       &conn_complete_packet);
269 
270   RunUntilIdle();
271   ASSERT_TRUE(conn.has_value());
272   ASSERT_TRUE(conn->is_error());
273   EXPECT_EQ(conn->error_value(), HostError::kParametersRejected);
274 }
275 
TEST_F(ScoConnectionManagerTest,IgnoreWrongAddressInConnectionComplete)276 TEST_F(ScoConnectionManagerTest, IgnoreWrongAddressInConnectionComplete) {
277   auto setup_status_packet = testing::CommandStatusPacket(
278       hci_spec::kEnhancedSetupSynchronousConnection,
279       pw::bluetooth::emboss::StatusCode::SUCCESS);
280   const DeviceAddress kWrongPeerAddress(DeviceAddress::Type::kBREDR,
281                                         {0x00, 0x00, 0x00, 0x00, 0x00, 0x05});
282   auto conn_complete_packet_wrong =
283       testing::SynchronousConnectionCompletePacket(
284           kScoConnectionHandle,
285           kWrongPeerAddress,
286           hci_spec::LinkType::kExtendedSCO,
287           pw::bluetooth::emboss::StatusCode::SUCCESS);
288   EXPECT_CMD_PACKET_OUT(test_device(),
289                         testing::EnhancedSetupSynchronousConnectionPacket(
290                             kAclConnectionHandle, kConnectionParams),
291                         &setup_status_packet,
292                         &conn_complete_packet_wrong);
293 
294   std::optional<OpenConnectionResult> conn_result;
295   auto conn_cb = [&conn_result](auto result) {
296     activate_connection(result);
297     conn_result = std::move(result);
298   };
299 
300   auto req_handle =
301       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
302 
303   RunUntilIdle();
304   EXPECT_FALSE(conn_result.has_value());
305 
306   // Ensure subsequent correct complete packet completes request.
307   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
308       kScoConnectionHandle,
309       kPeerAddress,
310       hci_spec::LinkType::kExtendedSCO,
311       pw::bluetooth::emboss::StatusCode::SUCCESS);
312   test_device()->SendCommandChannelPacket(conn_complete_packet);
313   RunUntilIdle();
314   ASSERT_TRUE(conn_result.has_value());
315   ASSERT_TRUE(conn_result->is_ok());
316   EXPECT_CMD_PACKET_OUT(test_device(),
317                         testing::DisconnectPacket(kScoConnectionHandle));
318 }
319 
TEST_F(ScoConnectionManagerTest,UnexpectedConnectionCompleteDisconnectsConnection)320 TEST_F(ScoConnectionManagerTest,
321        UnexpectedConnectionCompleteDisconnectsConnection) {
322   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
323       kScoConnectionHandle,
324       kPeerAddress,
325       hci_spec::LinkType::kExtendedSCO,
326       pw::bluetooth::emboss::StatusCode::SUCCESS);
327   EXPECT_CMD_PACKET_OUT(test_device(),
328                         testing::DisconnectPacket(kScoConnectionHandle));
329   test_device()->SendCommandChannelPacket(conn_complete_packet);
330   RunUntilIdle();
331 }
332 
TEST_F(ScoConnectionManagerTest,DestroyingManagerClosesConnections)333 TEST_F(ScoConnectionManagerTest, DestroyingManagerClosesConnections) {
334   auto setup_status_packet = testing::CommandStatusPacket(
335       hci_spec::kEnhancedSetupSynchronousConnection,
336       pw::bluetooth::emboss::StatusCode::SUCCESS);
337   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
338       kScoConnectionHandle,
339       kPeerAddress,
340       hci_spec::LinkType::kExtendedSCO,
341       pw::bluetooth::emboss::StatusCode::SUCCESS);
342   EXPECT_CMD_PACKET_OUT(test_device(),
343                         testing::EnhancedSetupSynchronousConnectionPacket(
344                             kAclConnectionHandle, kConnectionParams),
345                         &setup_status_packet,
346                         &conn_complete_packet);
347 
348   std::optional<OpenConnectionResult> conn_result;
349   auto conn_cb = [&conn_result](OpenConnectionResult result) {
350     activate_connection(result);
351     conn_result = std::move(result);
352   };
353 
354   auto req_handle =
355       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
356 
357   RunUntilIdle();
358   ASSERT_TRUE(conn_result.has_value());
359   ASSERT_TRUE(conn_result->is_ok());
360   EXPECT_TRUE(conn_result->value().is_alive());
361 
362   EXPECT_CMD_PACKET_OUT(test_device(),
363                         testing::DisconnectPacket(kScoConnectionHandle));
364   DestroyManager();
365   RunUntilIdle();
366   // WeakPtr should become invalid.
367   EXPECT_FALSE(conn_result->value().is_alive());
368 }
369 
TEST_F(ScoConnectionManagerTest,QueueThreeRequestsCancelsSecond)370 TEST_F(ScoConnectionManagerTest, QueueThreeRequestsCancelsSecond) {
371   const hci_spec::ConnectionHandle handle_0 = kScoConnectionHandle;
372   const hci_spec::ConnectionHandle handle_1 = handle_0 + 1;
373   const hci_spec::ConnectionHandle handle_2 = handle_1 + 1;
374 
375   auto setup_status_packet = testing::CommandStatusPacket(
376       hci_spec::kEnhancedSetupSynchronousConnection,
377       pw::bluetooth::emboss::StatusCode::SUCCESS);
378   EXPECT_CMD_PACKET_OUT(test_device(),
379                         testing::EnhancedSetupSynchronousConnectionPacket(
380                             kAclConnectionHandle, kConnectionParams),
381                         &setup_status_packet);
382 
383   std::optional<OpenConnectionResult> conn_result_0;
384   auto conn_cb_0 = [&conn_result_0](auto cb_conn) {
385     // No need to activate the connection here since Deactivate is called
386     // manually.
387     conn_result_0 = std::move(cb_conn);
388   };
389   auto req_handle_0 =
390       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
391 
392   std::optional<OpenConnectionResult> conn_result_1;
393   auto conn_cb_1 = [&conn_result_1](auto cb_result) {
394     activate_connection(cb_result);
395     conn_result_1 = std::move(cb_result);
396   };
397   auto req_handle_1 =
398       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
399 
400   std::optional<OpenConnectionResult> conn_result_2;
401   auto conn_cb_2 = [&conn_result_2](auto cb_conn) {
402     // No need to activate the connection here since Deactivate is called
403     // manually.
404     conn_result_2 = std::move(cb_conn);
405   };
406   auto req_handle_2 =
407       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_2));
408 
409   RunUntilIdle();
410   EXPECT_FALSE(conn_result_0.has_value());
411   EXPECT_FALSE(conn_result_2.has_value());
412   ASSERT_TRUE(conn_result_1.has_value());
413   ASSERT_TRUE(conn_result_1->is_error());
414   EXPECT_EQ(conn_result_1->error_value(), HostError::kCanceled);
415 
416   EXPECT_CMD_PACKET_OUT(test_device(),
417                         testing::EnhancedSetupSynchronousConnectionPacket(
418                             kAclConnectionHandle, kConnectionParams),
419                         &setup_status_packet);
420 
421   auto conn_complete_packet_0 = testing::SynchronousConnectionCompletePacket(
422       handle_0,
423       kPeerAddress,
424       hci_spec::LinkType::kExtendedSCO,
425       pw::bluetooth::emboss::StatusCode::SUCCESS);
426   test_device()->SendCommandChannelPacket(conn_complete_packet_0);
427   RunUntilIdle();
428   ASSERT_TRUE(conn_result_0.has_value());
429   ASSERT_TRUE(conn_result_0->is_ok());
430   EXPECT_FALSE(conn_result_2.has_value());
431 
432   auto conn_complete_packet_2 = testing::SynchronousConnectionCompletePacket(
433       handle_2,
434       kPeerAddress,
435       hci_spec::LinkType::kExtendedSCO,
436       pw::bluetooth::emboss::StatusCode::SUCCESS);
437   test_device()->SendCommandChannelPacket(conn_complete_packet_2);
438   RunUntilIdle();
439   ASSERT_TRUE(conn_result_2.has_value());
440   ASSERT_TRUE(conn_result_2->is_ok());
441 
442   // Send status and complete events so second disconnect command isn't queued
443   // in CommandChannel.
444   auto disconn_status_packet_0 = testing::CommandStatusPacket(
445       hci_spec::kDisconnect, pw::bluetooth::emboss::StatusCode::SUCCESS);
446   auto disconn_complete_0 = testing::DisconnectionCompletePacket(handle_0);
447   EXPECT_CMD_PACKET_OUT(test_device(),
448                         testing::DisconnectPacket(handle_0),
449                         &disconn_status_packet_0,
450                         &disconn_complete_0);
451   conn_result_0.value()->Deactivate();
452   EXPECT_CMD_PACKET_OUT(test_device(), testing::DisconnectPacket(handle_2));
453   conn_result_2.value()->Deactivate();
454   RunUntilIdle();
455 }
456 
TEST_F(ScoConnectionManagerTest,HandleReuse)457 TEST_F(ScoConnectionManagerTest, HandleReuse) {
458   auto setup_status_packet = testing::CommandStatusPacket(
459       hci_spec::kEnhancedSetupSynchronousConnection,
460       pw::bluetooth::emboss::StatusCode::SUCCESS);
461   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
462       kScoConnectionHandle,
463       kPeerAddress,
464       hci_spec::LinkType::kExtendedSCO,
465       pw::bluetooth::emboss::StatusCode::SUCCESS);
466   EXPECT_CMD_PACKET_OUT(test_device(),
467                         testing::EnhancedSetupSynchronousConnectionPacket(
468                             kAclConnectionHandle, kConnectionParams),
469                         &setup_status_packet,
470                         &conn_complete_packet);
471 
472   std::optional<OpenConnectionResult> conn_result;
473   auto conn_cb = [&conn_result](auto cb_conn) {
474     // No need to activate the connection here since Deactivate is called
475     // manually.
476     conn_result = std::move(cb_conn);
477   };
478 
479   auto req_handle_0 = manager()->OpenConnection(kConnectionParams, conn_cb);
480 
481   RunUntilIdle();
482   ASSERT_TRUE(conn_result.has_value());
483   ASSERT_TRUE(conn_result->is_ok());
484   ScoConnection::WeakPtr conn = conn_result->value();
485   EXPECT_EQ(conn->handle(), kScoConnectionHandle);
486 
487   auto disconn_status_packet = testing::CommandStatusPacket(
488       hci_spec::kDisconnect, pw::bluetooth::emboss::StatusCode::SUCCESS);
489   auto disconn_complete =
490       testing::DisconnectionCompletePacket(kScoConnectionHandle);
491   EXPECT_CMD_PACKET_OUT(test_device(),
492                         testing::DisconnectPacket(kScoConnectionHandle),
493                         &disconn_status_packet,
494                         &disconn_complete);
495   conn->Deactivate();
496   conn_result.reset();
497 
498   EXPECT_CMD_PACKET_OUT(test_device(),
499                         testing::EnhancedSetupSynchronousConnectionPacket(
500                             kAclConnectionHandle, kConnectionParams),
501                         &setup_status_packet,
502                         &conn_complete_packet);
503 
504   auto req_handle_1 = manager()->OpenConnection(kConnectionParams, conn_cb);
505 
506   RunUntilIdle();
507   ASSERT_TRUE(conn_result.has_value());
508   ASSERT_TRUE(conn_result->is_ok());
509   EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);
510 
511   EXPECT_CMD_PACKET_OUT(test_device(),
512                         testing::DisconnectPacket(kScoConnectionHandle));
513 }
514 
TEST_F(ScoConnectionManagerTest,AcceptConnectionSuccess)515 TEST_F(ScoConnectionManagerTest, AcceptConnectionSuccess) {
516   std::optional<AcceptConnectionResult> conn_result;
517   auto conn_cb = [&conn_result](auto cb_conn) {
518     EXPECT_TRUE(cb_conn.is_ok());
519     conn_result = std::move(cb_conn);
520   };
521   auto req_handle =
522       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
523 
524   auto conn_req_packet =
525       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
526   test_device()->SendCommandChannelPacket(conn_req_packet);
527 
528   auto accept_status_packet = testing::CommandStatusPacket(
529       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
530       pw::bluetooth::emboss::StatusCode::SUCCESS);
531   EXPECT_CMD_PACKET_OUT(
532       test_device(),
533       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
534           kPeerAddress, kConnectionParams),
535       &accept_status_packet);
536   RunUntilIdle();
537   EXPECT_FALSE(conn_result.has_value());
538 
539   test_device()->SendCommandChannelPacket(
540       testing::SynchronousConnectionCompletePacket(
541           kScoConnectionHandle,
542           kPeerAddress,
543           hci_spec::LinkType::kSCO,
544           pw::bluetooth::emboss::StatusCode::SUCCESS));
545 
546   RunUntilIdle();
547   ASSERT_TRUE(conn_result.has_value());
548   ASSERT_TRUE(conn_result->is_ok());
549   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
550 
551   EXPECT_CMD_PACKET_OUT(test_device(),
552                         testing::DisconnectPacket(kScoConnectionHandle));
553 }
554 
TEST_F(ScoConnectionManagerTest,AcceptConnectionAndReceiveStatusAndCompleteEventWithErrors)555 TEST_F(ScoConnectionManagerTest,
556        AcceptConnectionAndReceiveStatusAndCompleteEventWithErrors) {
557   std::optional<AcceptConnectionResult> conn_result;
558   auto conn_cb = [&conn_result](auto cb_conn) {
559     conn_result = std::move(cb_conn);
560   };
561 
562   auto req_handle =
563       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
564 
565   auto conn_req_packet =
566       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
567   test_device()->SendCommandChannelPacket(conn_req_packet);
568 
569   auto accept_status_packet = testing::CommandStatusPacket(
570       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
571       pw::bluetooth::emboss::StatusCode::INVALID_HCI_COMMAND_PARAMETERS);
572   EXPECT_CMD_PACKET_OUT(
573       test_device(),
574       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
575           kPeerAddress, kConnectionParams),
576       &accept_status_packet);
577   RunUntilIdle();
578   EXPECT_FALSE(conn_result.has_value());
579 
580   test_device()->SendCommandChannelPacket(
581       testing::SynchronousConnectionCompletePacket(
582           kScoConnectionHandle,
583           kPeerAddress,
584           hci_spec::LinkType::kSCO,
585           pw::bluetooth::emboss::StatusCode::
586               CONNECTION_ACCEPT_TIMEOUT_EXCEEDED));
587 
588   RunUntilIdle();
589   ASSERT_TRUE(conn_result.has_value());
590   ASSERT_TRUE(conn_result->is_error());
591   EXPECT_EQ(conn_result->error_value(), HostError::kParametersRejected);
592 }
593 
TEST_F(ScoConnectionManagerTest,AcceptConnectionAndReceiveCompleteEventWithFailureStatus)594 TEST_F(ScoConnectionManagerTest,
595        AcceptConnectionAndReceiveCompleteEventWithFailureStatus) {
596   std::optional<AcceptConnectionResult> conn_result;
597   auto conn_cb = [&conn_result](auto cb_conn) {
598     conn_result = std::move(cb_conn);
599   };
600 
601   auto req_handle =
602       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
603 
604   auto conn_req_packet =
605       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
606   test_device()->SendCommandChannelPacket(conn_req_packet);
607 
608   auto accept_status_packet = testing::CommandStatusPacket(
609       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
610       pw::bluetooth::emboss::StatusCode::SUCCESS);
611   EXPECT_CMD_PACKET_OUT(
612       test_device(),
613       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
614           kPeerAddress, kConnectionParams),
615       &accept_status_packet);
616   RunUntilIdle();
617   EXPECT_FALSE(conn_result.has_value());
618 
619   test_device()->SendCommandChannelPacket(
620       testing::SynchronousConnectionCompletePacket(
621           kScoConnectionHandle,
622           kPeerAddress,
623           hci_spec::LinkType::kSCO,
624           pw::bluetooth::emboss::StatusCode::
625               CONNECTION_FAILED_TO_BE_ESTABLISHED));
626 
627   RunUntilIdle();
628   ASSERT_TRUE(conn_result.has_value());
629   ASSERT_TRUE(conn_result->is_error());
630   EXPECT_EQ(conn_result->error_value(), HostError::kParametersRejected);
631 }
632 
TEST_F(ScoConnectionManagerTest,RejectInboundRequestWhileInitiatorRequestPending)633 TEST_F(ScoConnectionManagerTest,
634        RejectInboundRequestWhileInitiatorRequestPending) {
635   size_t conn_cb_count = 0;
636   auto conn_cb = [&conn_cb_count](auto cb_conn) {
637     activate_connection(cb_conn);
638     conn_cb_count++;
639   };
640 
641   auto setup_status_packet = testing::CommandStatusPacket(
642       hci_spec::kEnhancedSetupSynchronousConnection,
643       pw::bluetooth::emboss::StatusCode::SUCCESS);
644   EXPECT_CMD_PACKET_OUT(test_device(),
645                         testing::EnhancedSetupSynchronousConnectionPacket(
646                             kAclConnectionHandle, kConnectionParams),
647                         &setup_status_packet);
648 
649   auto req_handle =
650       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
651 
652   auto conn_req_packet =
653       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
654   test_device()->SendCommandChannelPacket(conn_req_packet);
655 
656   auto reject_status_packet = testing::CommandStatusPacket(
657       hci_spec::kRejectSynchronousConnectionRequest,
658       pw::bluetooth::emboss::StatusCode::SUCCESS);
659   EXPECT_CMD_PACKET_OUT(
660       test_device(),
661       testing::RejectSynchronousConnectionRequest(
662           kPeerAddress,
663           pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
664       &reject_status_packet);
665   RunUntilIdle();
666   EXPECT_EQ(conn_cb_count, 0u);
667   // Destroy manager so that callback gets called before callback reference is
668   // invalid.
669   DestroyManager();
670   EXPECT_EQ(conn_cb_count, 1u);
671 }
672 
TEST_F(ScoConnectionManagerTest,RejectInboundRequestWhenNoRequestsPending)673 TEST_F(ScoConnectionManagerTest, RejectInboundRequestWhenNoRequestsPending) {
674   auto conn_req_packet =
675       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
676   test_device()->SendCommandChannelPacket(conn_req_packet);
677 
678   auto reject_status_packet = testing::CommandStatusPacket(
679       hci_spec::kRejectSynchronousConnectionRequest,
680       pw::bluetooth::emboss::StatusCode::SUCCESS);
681   EXPECT_CMD_PACKET_OUT(
682       test_device(),
683       testing::RejectSynchronousConnectionRequest(
684           kPeerAddress,
685           pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
686       &reject_status_packet);
687   RunUntilIdle();
688 }
689 
TEST_F(ScoConnectionManagerTest,IgnoreInboundAclRequest)690 TEST_F(ScoConnectionManagerTest, IgnoreInboundAclRequest) {
691   auto conn_req_packet =
692       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kACL);
693   test_device()->SendCommandChannelPacket(conn_req_packet);
694   RunUntilIdle();
695 }
696 
TEST_F(ScoConnectionManagerTest,IgnoreInboundRequestWrongPeerAddress)697 TEST_F(ScoConnectionManagerTest, IgnoreInboundRequestWrongPeerAddress) {
698   const DeviceAddress address(DeviceAddress::Type::kBREDR,
699                               {0x00, 0x00, 0x00, 0x00, 0x00, 0x05});
700   auto conn_req_packet =
701       testing::ConnectionRequestPacket(address, hci_spec::LinkType::kACL);
702   test_device()->SendCommandChannelPacket(conn_req_packet);
703   RunUntilIdle();
704 }
705 
TEST_F(ScoConnectionManagerTest,QueueTwoAcceptConnectionRequestsCancelsFirstRequest)706 TEST_F(ScoConnectionManagerTest,
707        QueueTwoAcceptConnectionRequestsCancelsFirstRequest) {
708   std::optional<AcceptConnectionResult> conn_result_0;
709   auto conn_cb = [&conn_result_0](auto cb_conn) {
710     conn_result_0 = std::move(cb_conn);
711   };
712   auto req_handle_0 = manager()->AcceptConnection({kConnectionParams}, conn_cb);
713 
714   auto second_conn_params = kConnectionParams;
715   second_conn_params.view().transmit_bandwidth().Write(99);
716 
717   std::optional<AcceptConnectionResult> conn_result_1;
718   auto req_handle_1 = manager()->AcceptConnection(
719       {second_conn_params},
720       [&conn_result_1](auto cb_conn) { conn_result_1 = std::move(cb_conn); });
721 
722   ASSERT_TRUE(conn_result_0.has_value());
723   ASSERT_TRUE(conn_result_0->is_error());
724   EXPECT_EQ(conn_result_0->error_value(), HostError::kCanceled);
725 
726   auto conn_req_packet =
727       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
728   test_device()->SendCommandChannelPacket(conn_req_packet);
729 
730   auto accept_status_packet = testing::CommandStatusPacket(
731       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
732       pw::bluetooth::emboss::StatusCode::SUCCESS);
733   EXPECT_CMD_PACKET_OUT(
734       test_device(),
735       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
736           kPeerAddress, second_conn_params),
737       &accept_status_packet);
738   RunUntilIdle();
739   EXPECT_FALSE(conn_result_1.has_value());
740 
741   test_device()->SendCommandChannelPacket(
742       testing::SynchronousConnectionCompletePacket(
743           kScoConnectionHandle,
744           kPeerAddress,
745           hci_spec::LinkType::kSCO,
746           pw::bluetooth::emboss::StatusCode::SUCCESS));
747 
748   RunUntilIdle();
749   ASSERT_TRUE(conn_result_1.has_value());
750   ASSERT_TRUE(conn_result_1->is_ok());
751   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
752 
753   EXPECT_CMD_PACKET_OUT(test_device(),
754                         testing::DisconnectPacket(kScoConnectionHandle));
755 }
756 
TEST_F(ScoConnectionManagerTest,QueueTwoAcceptConnectionRequestsCancelsFirstRequestAndFirstRequestCallbackDestroysRequestHandle)757 TEST_F(
758     ScoConnectionManagerTest,
759     QueueTwoAcceptConnectionRequestsCancelsFirstRequestAndFirstRequestCallbackDestroysRequestHandle) {
760   std::optional<ScoConnectionManager::RequestHandle> req_handle_0;
761   std::optional<AcceptConnectionResult> conn_result_0;
762   auto conn_cb = [&conn_result_0, &req_handle_0](auto cb_conn) {
763     conn_result_0 = std::move(cb_conn);
764     req_handle_0.reset();
765   };
766   req_handle_0 = manager()->AcceptConnection({kConnectionParams}, conn_cb);
767 
768   auto second_conn_params = kConnectionParams;
769   second_conn_params.view().transmit_bandwidth().Write(99);
770 
771   std::optional<AcceptConnectionResult> conn_result_1;
772   auto req_handle_1 = manager()->AcceptConnection(
773       {second_conn_params},
774       [&conn_result_1](auto cb_conn) { conn_result_1 = std::move(cb_conn); });
775 
776   ASSERT_TRUE(conn_result_0.has_value());
777   ASSERT_TRUE(conn_result_0->is_error());
778   EXPECT_EQ(conn_result_0->error_value(), HostError::kCanceled);
779 
780   auto conn_req_packet =
781       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
782   test_device()->SendCommandChannelPacket(conn_req_packet);
783 
784   auto accept_status_packet = testing::CommandStatusPacket(
785       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
786       pw::bluetooth::emboss::StatusCode::SUCCESS);
787   EXPECT_CMD_PACKET_OUT(
788       test_device(),
789       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
790           kPeerAddress, second_conn_params),
791       &accept_status_packet);
792   RunUntilIdle();
793   EXPECT_FALSE(conn_result_1.has_value());
794 
795   test_device()->SendCommandChannelPacket(
796       testing::SynchronousConnectionCompletePacket(
797           kScoConnectionHandle,
798           kPeerAddress,
799           hci_spec::LinkType::kSCO,
800           pw::bluetooth::emboss::StatusCode::SUCCESS));
801 
802   RunUntilIdle();
803   ASSERT_TRUE(conn_result_1.has_value());
804   ASSERT_TRUE(conn_result_1->is_ok());
805   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
806 
807   EXPECT_CMD_PACKET_OUT(test_device(),
808                         testing::DisconnectPacket(kScoConnectionHandle));
809 }
810 
TEST_F(ScoConnectionManagerTest,QueueSecondAcceptRequestAfterFirstRequestReceivesEvent)811 TEST_F(ScoConnectionManagerTest,
812        QueueSecondAcceptRequestAfterFirstRequestReceivesEvent) {
813   std::optional<AcceptConnectionResult> conn_result_0;
814   auto req_handle_0 = manager()->AcceptConnection(
815       {kConnectionParams},
816       [&conn_result_0](auto cb_conn) { conn_result_0 = std::move(cb_conn); });
817 
818   auto conn_req_packet =
819       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
820   test_device()->SendCommandChannelPacket(conn_req_packet);
821 
822   EXPECT_CMD_PACKET_OUT(
823       test_device(),
824       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
825           kPeerAddress, kConnectionParams));
826   RunUntilIdle();
827 
828   std::optional<AcceptConnectionResult> conn_result_1;
829   auto req_handle_1 = manager()->AcceptConnection(
830       {kConnectionParams},
831       [&conn_result_1](auto cb_conn) { conn_result_1 = std::move(cb_conn); });
832 
833   // First request should not be cancelled because a request event was received.
834   EXPECT_FALSE(conn_result_0.has_value());
835 
836   // Send failure events to fail first request.
837   test_device()->SendCommandChannelPacket(testing::CommandStatusPacket(
838       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
839       pw::bluetooth::emboss::StatusCode::COMMAND_DISALLOWED));
840   test_device()->SendCommandChannelPacket(
841       testing::SynchronousConnectionCompletePacket(
842           kScoConnectionHandle,
843           kPeerAddress,
844           hci_spec::LinkType::kSCO,
845           pw::bluetooth::emboss::StatusCode::
846               CONNECTION_ACCEPT_TIMEOUT_EXCEEDED));
847   RunUntilIdle();
848   ASSERT_TRUE(conn_result_0.has_value());
849   ASSERT_TRUE(conn_result_0->is_error());
850   EXPECT_EQ(conn_result_0->error_value(), HostError::kParametersRejected);
851 
852   // Second request should now be in progress.
853   test_device()->SendCommandChannelPacket(conn_req_packet);
854 
855   auto accept_status_packet = testing::CommandStatusPacket(
856       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
857       pw::bluetooth::emboss::StatusCode::SUCCESS);
858   EXPECT_CMD_PACKET_OUT(
859       test_device(),
860       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
861           kPeerAddress, kConnectionParams),
862       &accept_status_packet);
863   RunUntilIdle();
864   EXPECT_FALSE(conn_result_1.has_value());
865 
866   test_device()->SendCommandChannelPacket(
867       testing::SynchronousConnectionCompletePacket(
868           kScoConnectionHandle,
869           kPeerAddress,
870           hci_spec::LinkType::kSCO,
871           pw::bluetooth::emboss::StatusCode::SUCCESS));
872 
873   RunUntilIdle();
874   ASSERT_TRUE(conn_result_1.has_value());
875   ASSERT_TRUE(conn_result_1->is_ok());
876   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
877 
878   EXPECT_CMD_PACKET_OUT(test_device(),
879                         testing::DisconnectPacket(kScoConnectionHandle));
880 }
881 
TEST_F(ScoConnectionManagerTest,RequestsCancelledOnManagerDestruction)882 TEST_F(ScoConnectionManagerTest, RequestsCancelledOnManagerDestruction) {
883   auto setup_status_packet = testing::CommandStatusPacket(
884       hci_spec::kEnhancedSetupSynchronousConnection,
885       pw::bluetooth::emboss::StatusCode::SUCCESS);
886   EXPECT_CMD_PACKET_OUT(test_device(),
887                         testing::EnhancedSetupSynchronousConnectionPacket(
888                             kAclConnectionHandle, kConnectionParams),
889                         &setup_status_packet);
890 
891   std::optional<OpenConnectionResult> conn_result_0;
892   auto conn_cb_0 = [&conn_result_0](auto cb_conn) {
893     activate_connection(cb_conn);
894     conn_result_0 = std::move(cb_conn);
895   };
896   auto req_handle_0 =
897       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
898 
899   std::optional<OpenConnectionResult> conn_result_1;
900   auto conn_cb_1 = [&conn_result_1](auto cb_conn) {
901     activate_connection(cb_conn);
902     conn_result_1 = std::move(cb_conn);
903   };
904   auto req_handle_1 =
905       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
906 
907   RunUntilIdle();
908 
909   DestroyManager();
910   ASSERT_TRUE(conn_result_0.has_value());
911   ASSERT_TRUE(conn_result_0->is_error());
912   EXPECT_EQ(conn_result_0->error_value(), HostError::kCanceled);
913   ASSERT_TRUE(conn_result_1.has_value());
914   ASSERT_TRUE(conn_result_1->is_error());
915   EXPECT_EQ(conn_result_1->error_value(), HostError::kCanceled);
916 }
917 
TEST_F(ScoConnectionManagerTest,AcceptConnectionExplicitlyCancelledByClient)918 TEST_F(ScoConnectionManagerTest, AcceptConnectionExplicitlyCancelledByClient) {
919   std::optional<AcceptConnectionResult> conn_result;
920   auto conn_cb = [&conn_result](auto cb_conn) {
921     conn_result = std::move(cb_conn);
922   };
923   auto req_handle =
924       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
925 
926   req_handle.Cancel();
927   ASSERT_TRUE(conn_result.has_value());
928   ASSERT_TRUE(conn_result->is_error());
929   EXPECT_EQ(conn_result->error_value(), HostError::kCanceled);
930 
931   auto conn_req_packet =
932       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
933   test_device()->SendCommandChannelPacket(conn_req_packet);
934 
935   auto reject_status_packet = testing::CommandStatusPacket(
936       hci_spec::kRejectSynchronousConnectionRequest,
937       pw::bluetooth::emboss::StatusCode::SUCCESS);
938   EXPECT_CMD_PACKET_OUT(
939       test_device(),
940       testing::RejectSynchronousConnectionRequest(
941           kPeerAddress,
942           pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
943       &reject_status_packet);
944   RunUntilIdle();
945   ASSERT_TRUE(conn_result->is_error());
946   EXPECT_EQ(conn_result->error_value(), HostError::kCanceled);
947 }
948 
TEST_F(ScoConnectionManagerTest,AcceptConnectionCancelledByClientDestroyingHandle)949 TEST_F(ScoConnectionManagerTest,
950        AcceptConnectionCancelledByClientDestroyingHandle) {
951   std::optional<AcceptConnectionResult> conn_result;
952   auto conn_cb = [&conn_result](auto cb_conn) {
953     conn_result = std::move(cb_conn);
954   };
955 
956   // req_handle destroyed at end of scope
957   {
958     auto req_handle =
959         manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
960   }
961   ASSERT_TRUE(conn_result.has_value());
962   ASSERT_TRUE(conn_result->is_error());
963   EXPECT_EQ(conn_result->error_value(), HostError::kCanceled);
964 
965   auto conn_req_packet =
966       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
967   test_device()->SendCommandChannelPacket(conn_req_packet);
968 
969   auto reject_status_packet = testing::CommandStatusPacket(
970       hci_spec::kRejectSynchronousConnectionRequest,
971       pw::bluetooth::emboss::StatusCode::SUCCESS);
972   EXPECT_CMD_PACKET_OUT(
973       test_device(),
974       testing::RejectSynchronousConnectionRequest(
975           kPeerAddress,
976           pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_BAD_BD_ADDR),
977       &reject_status_packet);
978   RunUntilIdle();
979   ASSERT_TRUE(conn_result->is_error());
980   EXPECT_EQ(conn_result->error_value(), HostError::kCanceled);
981 }
982 
TEST_F(ScoConnectionManagerTest,OpenConnectionCantBeCancelledOnceInProgress)983 TEST_F(ScoConnectionManagerTest, OpenConnectionCantBeCancelledOnceInProgress) {
984   auto setup_status_packet = testing::CommandStatusPacket(
985       hci_spec::kEnhancedSetupSynchronousConnection,
986       pw::bluetooth::emboss::StatusCode::SUCCESS);
987   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
988       kScoConnectionHandle,
989       kPeerAddress,
990       hci_spec::LinkType::kExtendedSCO,
991       pw::bluetooth::emboss::StatusCode::SUCCESS);
992   EXPECT_CMD_PACKET_OUT(test_device(),
993                         testing::EnhancedSetupSynchronousConnectionPacket(
994                             kAclConnectionHandle, kConnectionParams),
995                         &setup_status_packet);
996 
997   std::optional<OpenConnectionResult> conn_result;
998   auto conn_cb = [&conn_result](auto cb_conn) {
999     activate_connection(cb_conn);
1000     conn_result = std::move(cb_conn);
1001   };
1002 
1003   auto req_handle =
1004       manager()->OpenConnection(kConnectionParams, std::move(conn_cb));
1005   req_handle.Cancel();
1006 
1007   RunUntilIdle();
1008   EXPECT_FALSE(conn_result.has_value());
1009   test_device()->SendCommandChannelPacket(conn_complete_packet);
1010 
1011   RunUntilIdle();
1012   ASSERT_TRUE(conn_result.has_value());
1013   ASSERT_TRUE(conn_result->is_ok());
1014   EXPECT_EQ(conn_result->value()->handle(), kScoConnectionHandle);
1015 
1016   EXPECT_CMD_PACKET_OUT(test_device(),
1017                         testing::DisconnectPacket(kScoConnectionHandle));
1018   conn_result.value()->Close();
1019   RunUntilIdle();
1020 }
1021 
TEST_F(ScoConnectionManagerTest,QueueTwoRequestsAndCancelSecond)1022 TEST_F(ScoConnectionManagerTest, QueueTwoRequestsAndCancelSecond) {
1023   const hci_spec::ConnectionHandle handle_0 = kScoConnectionHandle;
1024 
1025   auto setup_status_packet = testing::CommandStatusPacket(
1026       hci_spec::kEnhancedSetupSynchronousConnection,
1027       pw::bluetooth::emboss::StatusCode::SUCCESS);
1028   EXPECT_CMD_PACKET_OUT(test_device(),
1029                         testing::EnhancedSetupSynchronousConnectionPacket(
1030                             kAclConnectionHandle, kConnectionParams),
1031                         &setup_status_packet);
1032 
1033   std::optional<OpenConnectionResult> conn_result_0;
1034   auto conn_cb_0 = [&conn_result_0](auto cb_conn) {
1035     // No need to activate the connection here since Deactivate is called
1036     // manually.
1037     conn_result_0 = std::move(cb_conn);
1038   };
1039   auto req_handle_0 =
1040       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
1041 
1042   size_t cb_count_1 = 0;
1043   std::optional<OpenConnectionResult> conn_result_1;
1044   auto conn_cb_1 = [&cb_count_1, &conn_result_1](auto cb_conn) {
1045     activate_connection(cb_conn);
1046     cb_count_1++;
1047     conn_result_1 = std::move(cb_conn);
1048   };
1049   auto req_handle_1 =
1050       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
1051 
1052   RunUntilIdle();
1053   EXPECT_FALSE(conn_result_0.has_value());
1054 
1055   req_handle_1.Cancel();
1056   EXPECT_EQ(cb_count_1, 1u);
1057   ASSERT_TRUE(conn_result_1.has_value());
1058   ASSERT_TRUE(conn_result_1->is_error());
1059   EXPECT_EQ(conn_result_1->error_value(), HostError::kCanceled);
1060 
1061   auto conn_complete_packet_0 = testing::SynchronousConnectionCompletePacket(
1062       handle_0,
1063       kPeerAddress,
1064       hci_spec::LinkType::kExtendedSCO,
1065       pw::bluetooth::emboss::StatusCode::SUCCESS);
1066   test_device()->SendCommandChannelPacket(conn_complete_packet_0);
1067   RunUntilIdle();
1068   ASSERT_TRUE(conn_result_0.has_value());
1069   ASSERT_TRUE(conn_result_0->is_ok());
1070   EXPECT_EQ(cb_count_1, 1u);
1071 
1072   auto disconn_status_packet_0 = testing::CommandStatusPacket(
1073       hci_spec::kDisconnect, pw::bluetooth::emboss::StatusCode::SUCCESS);
1074   auto disconn_complete_0 = testing::DisconnectionCompletePacket(handle_0);
1075   EXPECT_CMD_PACKET_OUT(test_device(),
1076                         testing::DisconnectPacket(handle_0),
1077                         &disconn_status_packet_0,
1078                         &disconn_complete_0);
1079   conn_result_0.value()->Deactivate();
1080   RunUntilIdle();
1081 }
1082 
TEST_F(ScoConnectionManagerTest,QueueingThreeRequestsCancelsSecondAndRequestHandleDestroyedInResultCallback)1083 TEST_F(
1084     ScoConnectionManagerTest,
1085     QueueingThreeRequestsCancelsSecondAndRequestHandleDestroyedInResultCallback) {
1086   auto setup_status_packet = testing::CommandStatusPacket(
1087       hci_spec::kEnhancedSetupSynchronousConnection,
1088       pw::bluetooth::emboss::StatusCode::SUCCESS);
1089   EXPECT_CMD_PACKET_OUT(test_device(),
1090                         testing::EnhancedSetupSynchronousConnectionPacket(
1091                             kAclConnectionHandle, kConnectionParams),
1092                         &setup_status_packet);
1093 
1094   std::optional<OpenConnectionResult> conn_result_0;
1095   auto conn_cb_0 = [&conn_result_0](auto cb_conn) {
1096     activate_connection(cb_conn);
1097     conn_result_0 = std::move(cb_conn);
1098   };
1099   auto req_handle_0 =
1100       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
1101 
1102   std::optional<ScoConnectionManager::RequestHandle> req_handle_1;
1103   std::optional<OpenConnectionResult> conn_result_1;
1104   auto conn_cb_1 = [&conn_result_1, &req_handle_1](auto cb_conn) {
1105     activate_connection(cb_conn);
1106     req_handle_1.reset();
1107     conn_result_1 = std::move(cb_conn);
1108   };
1109   req_handle_1 =
1110       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
1111 
1112   std::optional<OpenConnectionResult> conn_result_2;
1113   auto conn_cb_2 = [&conn_result_2](auto cb_conn) {
1114     activate_connection(cb_conn);
1115     conn_result_2 = std::move(cb_conn);
1116   };
1117   auto req_handle_2 =
1118       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_2));
1119 
1120   RunUntilIdle();
1121   EXPECT_FALSE(conn_result_0.has_value());
1122   EXPECT_FALSE(conn_result_2.has_value());
1123   ASSERT_TRUE(conn_result_1.has_value());
1124   ASSERT_TRUE(conn_result_1->is_error());
1125   EXPECT_EQ(conn_result_1->error_value(), HostError::kCanceled);
1126 
1127   DestroyManager();
1128   RunUntilIdle();
1129 }
1130 
TEST_F(ScoConnectionManagerTest,OpenConnectionFollowedByPeerDisconnectAndSecondOpenConnectonWithHandleReuse)1131 TEST_F(
1132     ScoConnectionManagerTest,
1133     OpenConnectionFollowedByPeerDisconnectAndSecondOpenConnectonWithHandleReuse) {
1134   auto setup_status_packet = testing::CommandStatusPacket(
1135       hci_spec::kEnhancedSetupSynchronousConnection,
1136       pw::bluetooth::emboss::StatusCode::SUCCESS);
1137   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
1138       kScoConnectionHandle,
1139       kPeerAddress,
1140       hci_spec::LinkType::kExtendedSCO,
1141       pw::bluetooth::emboss::StatusCode::SUCCESS);
1142   EXPECT_CMD_PACKET_OUT(test_device(),
1143                         testing::EnhancedSetupSynchronousConnectionPacket(
1144                             kAclConnectionHandle, kConnectionParams),
1145                         &setup_status_packet,
1146                         &conn_complete_packet);
1147 
1148   std::optional<OpenConnectionResult> conn_result_0;
1149   auto conn_cb_0 = [&conn_result_0](auto result) {
1150     activate_connection(result);
1151     conn_result_0 = std::move(result);
1152   };
1153 
1154   auto req_handle_0 =
1155       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
1156 
1157   RunUntilIdle();
1158   ASSERT_TRUE(conn_result_0.has_value());
1159   ASSERT_TRUE(conn_result_0->is_ok());
1160   ASSERT_TRUE(conn_result_0->value().is_alive());
1161   EXPECT_EQ(conn_result_0->value()->handle(), kScoConnectionHandle);
1162 
1163   test_device()->SendCommandChannelPacket(testing::DisconnectionCompletePacket(
1164       kScoConnectionHandle,
1165       pw::bluetooth::emboss::StatusCode::REMOTE_USER_TERMINATED_CONNECTION));
1166   RunUntilIdle();
1167 
1168   EXPECT_CMD_PACKET_OUT(test_device(),
1169                         testing::EnhancedSetupSynchronousConnectionPacket(
1170                             kAclConnectionHandle, kConnectionParams),
1171                         &setup_status_packet,
1172                         &conn_complete_packet);
1173 
1174   std::optional<OpenConnectionResult> conn_result_1;
1175   auto conn_cb_1 = [&conn_result_1](auto result) {
1176     activate_connection(result);
1177     conn_result_1 = std::move(result);
1178   };
1179 
1180   auto req_handle_1 =
1181       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
1182 
1183   RunUntilIdle();
1184   ASSERT_TRUE(conn_result_1.has_value());
1185   ASSERT_TRUE(conn_result_1->is_ok());
1186   ASSERT_TRUE(conn_result_1->value().is_alive());
1187   EXPECT_EQ(conn_result_1->value()->handle(), kScoConnectionHandle);
1188 
1189   EXPECT_CMD_PACKET_OUT(test_device(),
1190                         testing::DisconnectPacket(kScoConnectionHandle));
1191   conn_result_1.value()->Close();
1192   RunUntilIdle();
1193 }
1194 
TEST_F(ScoConnectionManagerTest,DestroyManagerWhileResponderRequestInProgressAndDestroyRequestHandleInResultCallback)1195 TEST_F(
1196     ScoConnectionManagerTest,
1197     DestroyManagerWhileResponderRequestInProgressAndDestroyRequestHandleInResultCallback) {
1198   std::optional<AcceptConnectionResult> conn;
1199   std::optional<ScoConnectionManager::RequestHandle> req_handle;
1200   auto conn_cb = [&conn, &req_handle](auto cb_result) {
1201     req_handle.reset();
1202     conn = std::move(cb_result);
1203   };
1204 
1205   req_handle =
1206       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb));
1207   RunUntilIdle();
1208 
1209   DestroyManager();
1210   RunUntilIdle();
1211 
1212   ASSERT_TRUE(conn.has_value());
1213   ASSERT_TRUE(conn->is_error());
1214   EXPECT_EQ(conn->error_value(), HostError::kCanceled);
1215 }
1216 
TEST_F(ScoConnectionManagerTest,DestroyManagerWhileInitiatorRequestQueuedAndDestroyRequestHandleInResultCallback)1217 TEST_F(
1218     ScoConnectionManagerTest,
1219     DestroyManagerWhileInitiatorRequestQueuedAndDestroyRequestHandleInResultCallback) {
1220   auto setup_status_packet = testing::CommandStatusPacket(
1221       hci_spec::kEnhancedSetupSynchronousConnection,
1222       pw::bluetooth::emboss::StatusCode::SUCCESS);
1223   EXPECT_CMD_PACKET_OUT(test_device(),
1224                         testing::EnhancedSetupSynchronousConnectionPacket(
1225                             kAclConnectionHandle, kConnectionParams),
1226                         &setup_status_packet);
1227 
1228   std::optional<OpenConnectionResult> conn_result_0;
1229   auto conn_cb_0 = [&conn_result_0](auto cb_conn) {
1230     activate_connection(cb_conn);
1231     conn_result_0 = std::move(cb_conn);
1232   };
1233   auto req_handle_0 =
1234       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_0));
1235 
1236   std::optional<ScoConnectionManager::RequestHandle> req_handle_1;
1237   std::optional<OpenConnectionResult> conn_result_1;
1238   auto conn_cb_1 = [&conn_result_1, &req_handle_1](auto cb_conn) {
1239     activate_connection(cb_conn);
1240     req_handle_1.reset();
1241     conn_result_1 = std::move(cb_conn);
1242   };
1243   req_handle_1 =
1244       manager()->OpenConnection(kConnectionParams, std::move(conn_cb_1));
1245 
1246   RunUntilIdle();
1247   EXPECT_FALSE(conn_result_0.has_value());
1248 
1249   DestroyManager();
1250   ASSERT_TRUE(conn_result_0.has_value());
1251   ASSERT_TRUE(conn_result_0->is_error());
1252   EXPECT_EQ(conn_result_0->error_value(), HostError::kCanceled);
1253   ASSERT_TRUE(conn_result_1.has_value());
1254   ASSERT_TRUE(conn_result_1->is_error());
1255   EXPECT_EQ(conn_result_1->error_value(), HostError::kCanceled);
1256 }
1257 
TEST_F(ScoConnectionManagerTest,AcceptConnectionFirstParametersRejectedSecondParametersAccepted)1258 TEST_F(ScoConnectionManagerTest,
1259        AcceptConnectionFirstParametersRejectedSecondParametersAccepted) {
1260   bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
1261       esco_params_0 = kConnectionParams;
1262   esco_params_0.view().packet_types().ev3().Write(true);
1263   bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
1264       esco_params_1 = kConnectionParams;
1265   esco_params_1.view().packet_types().ev4().Write(true);
1266 
1267   std::optional<AcceptConnectionResult> conn_result;
1268   auto conn_cb = [&conn_result](auto cb_conn) {
1269     conn_result = std::move(cb_conn);
1270   };
1271   auto req_handle = manager()->AcceptConnection({esco_params_0, esco_params_1},
1272                                                 std::move(conn_cb));
1273 
1274   auto conn_req_packet_0 = testing::ConnectionRequestPacket(
1275       kPeerAddress, hci_spec::LinkType::kExtendedSCO);
1276   test_device()->SendCommandChannelPacket(conn_req_packet_0);
1277 
1278   auto accept_status_packet_0 = testing::CommandStatusPacket(
1279       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
1280       pw::bluetooth::emboss::StatusCode::SUCCESS);
1281   EXPECT_CMD_PACKET_OUT(
1282       test_device(),
1283       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress,
1284                                                                 esco_params_0),
1285       &accept_status_packet_0);
1286   RunUntilIdle();
1287   EXPECT_FALSE(conn_result.has_value());
1288 
1289   test_device()->SendCommandChannelPacket(
1290       testing::SynchronousConnectionCompletePacket(
1291           kScoConnectionHandle,
1292           kPeerAddress,
1293           hci_spec::LinkType::kExtendedSCO,
1294           pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER));
1295 
1296   RunUntilIdle();
1297   EXPECT_FALSE(conn_result.has_value());
1298 
1299   auto conn_req_packet_1 = testing::ConnectionRequestPacket(
1300       kPeerAddress, hci_spec::LinkType::kExtendedSCO);
1301   test_device()->SendCommandChannelPacket(conn_req_packet_1);
1302 
1303   auto accept_status_packet_1 = testing::CommandStatusPacket(
1304       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
1305       pw::bluetooth::emboss::StatusCode::SUCCESS);
1306   EXPECT_CMD_PACKET_OUT(
1307       test_device(),
1308       testing::EnhancedAcceptSynchronousConnectionRequestPacket(kPeerAddress,
1309                                                                 esco_params_1),
1310       &accept_status_packet_1);
1311   RunUntilIdle();
1312   EXPECT_FALSE(conn_result.has_value());
1313 
1314   test_device()->SendCommandChannelPacket(
1315       testing::SynchronousConnectionCompletePacket(
1316           kScoConnectionHandle,
1317           kPeerAddress,
1318           hci_spec::LinkType::kExtendedSCO,
1319           pw::bluetooth::emboss::StatusCode::SUCCESS));
1320 
1321   RunUntilIdle();
1322   ASSERT_TRUE(conn_result.has_value());
1323   ASSERT_TRUE(conn_result->is_ok());
1324   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
1325   size_t result_parameter_index = conn_result->value().second;
1326   EXPECT_EQ(result_parameter_index, 1u);
1327 
1328   EXPECT_CMD_PACKET_OUT(test_device(),
1329                         testing::DisconnectPacket(kScoConnectionHandle));
1330 }
1331 
TEST_F(ScoConnectionManagerTest,AcceptScoConnectionWithFirstParametersEscoPacketTypeAndSecondScoPacketTypeSkipsToSecondParameters)1332 TEST_F(
1333     ScoConnectionManagerTest,
1334     AcceptScoConnectionWithFirstParametersEscoPacketTypeAndSecondScoPacketTypeSkipsToSecondParameters) {
1335   std::optional<AcceptConnectionResult> conn_result;
1336   auto conn_cb = [&conn_result](auto cb_conn) {
1337     conn_result = std::move(cb_conn);
1338   };
1339   auto req_handle = manager()->AcceptConnection(
1340       {EscoConnectionParams(), ScoConnectionParams()}, std::move(conn_cb));
1341 
1342   auto conn_req_packet =
1343       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
1344   test_device()->SendCommandChannelPacket(conn_req_packet);
1345 
1346   auto accept_status_packet = testing::CommandStatusPacket(
1347       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
1348       pw::bluetooth::emboss::StatusCode::SUCCESS);
1349   EXPECT_CMD_PACKET_OUT(
1350       test_device(),
1351       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
1352           kPeerAddress, ScoConnectionParams()),
1353       &accept_status_packet);
1354   RunUntilIdle();
1355   EXPECT_FALSE(conn_result.has_value());
1356 
1357   test_device()->SendCommandChannelPacket(
1358       testing::SynchronousConnectionCompletePacket(
1359           kScoConnectionHandle,
1360           kPeerAddress,
1361           hci_spec::LinkType::kSCO,
1362           pw::bluetooth::emboss::StatusCode::SUCCESS));
1363 
1364   RunUntilIdle();
1365   ASSERT_TRUE(conn_result.has_value());
1366   ASSERT_TRUE(conn_result->is_ok());
1367   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
1368   size_t result_parameter_index = conn_result->value().second;
1369   EXPECT_EQ(result_parameter_index, 1u);
1370 
1371   // Verify that the correct parameters were given to the ScoConnection.
1372   ASSERT_TRUE(
1373       conn_result->value().first->parameters().view().packet_types().Equals(
1374           ScoConnectionParams().view().packet_types()));
1375   EXPECT_CMD_PACKET_OUT(test_device(),
1376                         testing::DisconnectPacket(kScoConnectionHandle));
1377 }
1378 
TEST_F(ScoConnectionManagerTest,AcceptEscoConnectionWithFirstParametersScoPacketTypeAndSecondEscoPacketTypeSkipsToSecondParameters)1379 TEST_F(
1380     ScoConnectionManagerTest,
1381     AcceptEscoConnectionWithFirstParametersScoPacketTypeAndSecondEscoPacketTypeSkipsToSecondParameters) {
1382   std::optional<AcceptConnectionResult> conn_result;
1383   auto conn_cb = [&conn_result](auto cb_conn) {
1384     conn_result = std::move(cb_conn);
1385   };
1386   auto req_handle = manager()->AcceptConnection(
1387       {ScoConnectionParams(), EscoConnectionParams()}, std::move(conn_cb));
1388 
1389   auto conn_req_packet = testing::ConnectionRequestPacket(
1390       kPeerAddress, hci_spec::LinkType::kExtendedSCO);
1391   test_device()->SendCommandChannelPacket(conn_req_packet);
1392 
1393   auto accept_status_packet = testing::CommandStatusPacket(
1394       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
1395       pw::bluetooth::emboss::StatusCode::SUCCESS);
1396   EXPECT_CMD_PACKET_OUT(
1397       test_device(),
1398       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
1399           kPeerAddress, EscoConnectionParams()),
1400       &accept_status_packet);
1401   RunUntilIdle();
1402   EXPECT_FALSE(conn_result.has_value());
1403 
1404   test_device()->SendCommandChannelPacket(
1405       testing::SynchronousConnectionCompletePacket(
1406           kScoConnectionHandle,
1407           kPeerAddress,
1408           hci_spec::LinkType::kExtendedSCO,
1409           pw::bluetooth::emboss::StatusCode::SUCCESS));
1410 
1411   RunUntilIdle();
1412   ASSERT_TRUE(conn_result.has_value());
1413   ASSERT_TRUE(conn_result->is_ok());
1414   EXPECT_EQ(conn_result->value().first->handle(), kScoConnectionHandle);
1415   size_t result_parameter_index = conn_result->value().second;
1416   EXPECT_EQ(result_parameter_index, 1u);
1417 
1418   EXPECT_CMD_PACKET_OUT(test_device(),
1419                         testing::DisconnectPacket(kScoConnectionHandle));
1420 }
1421 
TEST_F(ScoConnectionManagerTest,AcceptScoConnectionWithEscoParametersFailsAndSendsRejectCommand)1422 TEST_F(ScoConnectionManagerTest,
1423        AcceptScoConnectionWithEscoParametersFailsAndSendsRejectCommand) {
1424   std::optional<AcceptConnectionResult> conn_result;
1425   auto conn_cb = [&conn_result](auto cb_conn) {
1426     conn_result = std::move(cb_conn);
1427   };
1428   auto req_handle =
1429       manager()->AcceptConnection({EscoConnectionParams()}, std::move(conn_cb));
1430 
1431   auto conn_req_packet =
1432       testing::ConnectionRequestPacket(kPeerAddress, hci_spec::LinkType::kSCO);
1433   test_device()->SendCommandChannelPacket(conn_req_packet);
1434 
1435   auto reject_status_packet = testing::CommandStatusPacket(
1436       hci_spec::kRejectSynchronousConnectionRequest,
1437       pw::bluetooth::emboss::StatusCode::SUCCESS);
1438 
1439   auto conn_complete_packet = testing::SynchronousConnectionCompletePacket(
1440       /*conn=*/0,
1441       kPeerAddress,
1442       hci_spec::LinkType::kExtendedSCO,
1443       pw::bluetooth::emboss::StatusCode::CONNECTION_REJECTED_LIMITED_RESOURCES);
1444 
1445   EXPECT_CMD_PACKET_OUT(test_device(),
1446                         testing::RejectSynchronousConnectionRequest(
1447                             kPeerAddress,
1448                             pw::bluetooth::emboss::StatusCode::
1449                                 CONNECTION_REJECTED_LIMITED_RESOURCES),
1450                         &reject_status_packet);
1451   RunUntilIdle();
1452   // The AcceptConnection request should not be completed until the connection
1453   // complete event is received.
1454   EXPECT_FALSE(conn_result.has_value());
1455 
1456   test_device()->SendCommandChannelPacket(conn_complete_packet);
1457   RunUntilIdle();
1458   ASSERT_TRUE(conn_result.has_value());
1459   ASSERT_TRUE(conn_result->is_error());
1460   EXPECT_EQ(conn_result->error_value(), HostError::kParametersRejected);
1461 }
1462 
TEST_F(ScoConnectionManagerTest,AcceptScoConnectionWithEmptyParametersFails)1463 TEST_F(ScoConnectionManagerTest, AcceptScoConnectionWithEmptyParametersFails) {
1464   std::optional<AcceptConnectionResult> conn_result;
1465   auto conn_cb = [&conn_result](auto cb_conn) {
1466     conn_result = std::move(cb_conn);
1467   };
1468   auto req_handle =
1469       manager()->AcceptConnection(/*parameters=*/{}, std::move(conn_cb));
1470   ASSERT_TRUE(conn_result.has_value());
1471   ASSERT_TRUE(conn_result->is_error());
1472   EXPECT_EQ(conn_result->error_value(), HostError::kInvalidParameters);
1473 }
1474 
TEST_F(ScoConnectionManagerTest,QueuedRequestAfterAcceptConnectionCommandCancelsNextAcceptConnectionParameterAttemptWhenThereAreMultipleParameters)1475 TEST_F(
1476     ScoConnectionManagerTest,
1477     QueuedRequestAfterAcceptConnectionCommandCancelsNextAcceptConnectionParameterAttemptWhenThereAreMultipleParameters) {
1478   std::optional<AcceptConnectionResult> conn_result_0;
1479   auto conn_cb_0 = [&conn_result_0](auto cb_conn) {
1480     conn_result_0 = std::move(cb_conn);
1481   };
1482 
1483   // Queue an accept request with 2 parameters. The first parameters should fail
1484   // and the second should never be used due to the second request canceling the
1485   // first request.
1486   auto req_handle_0 = manager()->AcceptConnection(
1487       {kConnectionParams, kConnectionParams}, std::move(conn_cb_0));
1488 
1489   auto conn_req_packet_0 = testing::ConnectionRequestPacket(
1490       kPeerAddress, hci_spec::LinkType::kExtendedSCO);
1491   test_device()->SendCommandChannelPacket(conn_req_packet_0);
1492 
1493   auto accept_status_packet_0 = testing::CommandStatusPacket(
1494       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
1495       pw::bluetooth::emboss::StatusCode::SUCCESS);
1496   EXPECT_CMD_PACKET_OUT(
1497       test_device(),
1498       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
1499           kPeerAddress, kConnectionParams),
1500       &accept_status_packet_0);
1501   RunUntilIdle();
1502   EXPECT_FALSE(conn_result_0.has_value());
1503 
1504   // Second request should cancel first request when connection complete event
1505   // is received.
1506   std::optional<AcceptConnectionResult> conn_result_1;
1507   auto conn_cb_1 = [&conn_result_1](auto cb_conn) {
1508     conn_result_1 = std::move(cb_conn);
1509   };
1510   auto req_handle_1 =
1511       manager()->AcceptConnection({kConnectionParams}, std::move(conn_cb_1));
1512   EXPECT_FALSE(conn_result_0.has_value());
1513 
1514   test_device()->SendCommandChannelPacket(
1515       testing::SynchronousConnectionCompletePacket(
1516           kScoConnectionHandle,
1517           kPeerAddress,
1518           hci_spec::LinkType::kExtendedSCO,
1519           pw::bluetooth::emboss::StatusCode::UNSUPPORTED_FEATURE_OR_PARAMETER));
1520 
1521   RunUntilIdle();
1522   ASSERT_TRUE(conn_result_0.has_value());
1523   ASSERT_TRUE(conn_result_0->is_error());
1524   EXPECT_EQ(conn_result_0->error_value(), HostError::kCanceled);
1525   EXPECT_FALSE(conn_result_1.has_value());
1526 
1527   // Complete the second accept request with an incoming connection.
1528   auto conn_req_packet_1 = testing::ConnectionRequestPacket(
1529       kPeerAddress, hci_spec::LinkType::kExtendedSCO);
1530   test_device()->SendCommandChannelPacket(conn_req_packet_1);
1531   auto accept_status_packet_1 = testing::CommandStatusPacket(
1532       hci_spec::kEnhancedAcceptSynchronousConnectionRequest,
1533       pw::bluetooth::emboss::StatusCode::SUCCESS);
1534   EXPECT_CMD_PACKET_OUT(
1535       test_device(),
1536       testing::EnhancedAcceptSynchronousConnectionRequestPacket(
1537           kPeerAddress, kConnectionParams),
1538       &accept_status_packet_1);
1539   RunUntilIdle();
1540   EXPECT_FALSE(conn_result_1.has_value());
1541 
1542   test_device()->SendCommandChannelPacket(
1543       testing::SynchronousConnectionCompletePacket(
1544           kScoConnectionHandle,
1545           kPeerAddress,
1546           hci_spec::LinkType::kExtendedSCO,
1547           pw::bluetooth::emboss::StatusCode::SUCCESS));
1548 
1549   RunUntilIdle();
1550   ASSERT_TRUE(conn_result_1.has_value());
1551   ASSERT_TRUE(conn_result_1->is_ok());
1552   EXPECT_EQ(conn_result_1->value().first->handle(), kScoConnectionHandle);
1553   size_t result_parameter_index = conn_result_1->value().second;
1554   EXPECT_EQ(result_parameter_index, 0u);
1555 
1556   EXPECT_CMD_PACKET_OUT(test_device(),
1557                         testing::DisconnectPacket(kScoConnectionHandle));
1558 }
1559 
1560 }  // namespace
1561 }  // namespace bt::sco
1562