xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/fuchsia/host/controllers/fidl_controller_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 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/fuchsia/host/controllers/fidl_controller.h"
16 
17 #include <optional>
18 
19 #include "gmock/gmock.h"
20 #include "pw_bluetooth_sapphire/fuchsia/host/fidl/fake_vendor_server.h"
21 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
22 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
23 #include "pw_bluetooth_sapphire/internal/host/testing/loop_fixture.h"
24 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
25 
26 namespace fhbt = fuchsia_hardware_bluetooth;
27 
28 namespace bt::controllers {
29 
30 namespace {
31 
32 constexpr hci_spec::ConnectionHandle kConnectionHandle = 0x0001;
33 const StaticByteBuffer kSetAclPriorityNormalCommand(0x00);
34 const StaticByteBuffer kSetAclPrioritySourceCommand(0x01);
35 const StaticByteBuffer kSetAclPrioritySinkCommand(0x02);
36 
37 }  // namespace
38 
39 class FidlControllerTest : public bt::testing::TestLoopFixture {
40  public:
SetUp()41   void SetUp() override {
42     auto [vendor_client_end, vendor_server_end] =
43         ::fidl::Endpoints<fhbt::Vendor>::Create();
44 
45     fake_vendor_server_.emplace(std::move(vendor_server_end), dispatcher());
46     fidl_controller_.emplace(std::move(vendor_client_end), dispatcher());
47   }
48 
InitializeController()49   void InitializeController() {
50     controller()->Initialize(
51         [&](pw::Status cb_complete_status) {
52           complete_status_ = cb_complete_status;
53         },
54         [&](pw::Status cb_error) { controller_error_ = cb_error; });
55     ASSERT_FALSE(complete_status_.has_value());
56     ASSERT_FALSE(controller_error_.has_value());
57   }
58 
controller()59   FidlController* controller() { return &fidl_controller_.value(); }
60 
hci_server()61   fidl::testing::FakeHciTransportServer* hci_server() {
62     return fake_vendor_server_->hci_server();
63   }
64 
vendor_server()65   fidl::testing::FakeVendorServer* vendor_server() {
66     return &fake_vendor_server_.value();
67   }
68 
complete_status() const69   std::optional<pw::Status> complete_status() const { return complete_status_; }
70 
controller_error() const71   std::optional<pw::Status> controller_error() const {
72     return controller_error_;
73   }
74 
75  private:
76   std::optional<pw::Status> complete_status_;
77   std::optional<pw::Status> controller_error_;
78   std::optional<fidl::testing::FakeVendorServer> fake_vendor_server_;
79   std::optional<FidlController> fidl_controller_;
80 };
81 
TEST_F(FidlControllerTest,SendAndReceiveAclPackets)82 TEST_F(FidlControllerTest, SendAndReceiveAclPackets) {
83   RETURN_IF_FATAL(InitializeController());
84   RunLoopUntilIdle();
85   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
86 
87   const StaticByteBuffer acl_packet_0(0x00, 0x01, 0x02, 0x03);
88   controller()->SendAclData(acl_packet_0.subspan());
89   RunLoopUntilIdle();
90   ASSERT_EQ(hci_server()->acl_packets_received().size(), 1u);
91   EXPECT_THAT(hci_server()->acl_packets_received()[0], BufferEq(acl_packet_0));
92 
93   const StaticByteBuffer acl_packet_1(0x04, 0x05, 0x06, 0x07);
94   controller()->SendAclData(acl_packet_1.subspan());
95   RunLoopUntilIdle();
96   ASSERT_EQ(hci_server()->acl_packets_received().size(), 2u);
97   EXPECT_THAT(hci_server()->acl_packets_received()[1], BufferEq(acl_packet_1));
98 
99   std::vector<DynamicByteBuffer> received_acl;
100   controller()->SetReceiveAclFunction([&](pw::span<const std::byte> buffer) {
101     received_acl.emplace_back(BufferView(buffer.data(), buffer.size()));
102   });
103 
104   hci_server()->SendAcl(acl_packet_0.view());
105   RunLoopUntilIdle();
106   ASSERT_EQ(received_acl.size(), 1u);
107   EXPECT_THAT(received_acl[0], BufferEq(acl_packet_0));
108   EXPECT_EQ(hci_server()->acks_received(), 1u);
109 
110   hci_server()->SendAcl(acl_packet_1.view());
111   RunLoopUntilIdle();
112   ASSERT_EQ(received_acl.size(), 2u);
113   EXPECT_THAT(received_acl[1], BufferEq(acl_packet_1));
114   EXPECT_EQ(hci_server()->acks_received(), 2u);
115 
116   std::optional<pw::Status> close_status;
117   controller()->Close([&](pw::Status status) { close_status = status; });
118   ASSERT_TRUE(close_status.has_value());
119   EXPECT_EQ(close_status.value(), PW_STATUS_OK);
120 }
121 
TEST_F(FidlControllerTest,SendCommandsAndReceiveEvents)122 TEST_F(FidlControllerTest, SendCommandsAndReceiveEvents) {
123   RETURN_IF_FATAL(InitializeController());
124   RunLoopUntilIdle();
125   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
126 
127   const StaticByteBuffer packet_0(0x00, 0x01, 0x02, 0x03);
128   controller()->SendCommand(packet_0.subspan());
129   RunLoopUntilIdle();
130   ASSERT_EQ(hci_server()->commands_received().size(), 1u);
131   EXPECT_THAT(hci_server()->commands_received()[0], BufferEq(packet_0));
132 
133   const StaticByteBuffer packet_1(0x04, 0x05, 0x06, 0x07);
134   controller()->SendCommand(packet_1.subspan());
135   RunLoopUntilIdle();
136   ASSERT_EQ(hci_server()->commands_received().size(), 2u);
137   EXPECT_THAT(hci_server()->commands_received()[1], BufferEq(packet_1));
138 
139   std::vector<DynamicByteBuffer> events;
140   controller()->SetEventFunction([&](pw::span<const std::byte> buffer) {
141     events.emplace_back(BufferView(buffer.data(), buffer.size()));
142   });
143 
144   hci_server()->SendEvent(packet_1.view());
145   RunLoopUntilIdle();
146   ASSERT_EQ(events.size(), 1u);
147   EXPECT_THAT(events[0], BufferEq(packet_1));
148   EXPECT_EQ(hci_server()->acks_received(), 1u);
149 
150   hci_server()->SendEvent(packet_1.view());
151   RunLoopUntilIdle();
152   ASSERT_EQ(events.size(), 2u);
153   EXPECT_THAT(events[1], BufferEq(packet_1));
154   EXPECT_EQ(hci_server()->acks_received(), 2u);
155 
156   std::optional<pw::Status> close_status;
157   controller()->Close([&](pw::Status status) { close_status = status; });
158   ASSERT_TRUE(close_status.has_value());
159   EXPECT_EQ(close_status.value(), PW_STATUS_OK);
160 }
161 
TEST_F(FidlControllerTest,SendScoWhenNotConfigured)162 TEST_F(FidlControllerTest, SendScoWhenNotConfigured) {
163   RETURN_IF_FATAL(InitializeController());
164   RunLoopUntilIdle();
165   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
166 
167   const StaticByteBuffer packet_0(0x00, 0x01, 0x02, 0x03);
168   controller()->SendScoData(packet_0.subspan());
169   RunLoopUntilIdle();
170   ASSERT_EQ(hci_server()->sco_packets_received().size(), 0u);
171   ASSERT_THAT(controller_error(), ::testing::Optional(PW_STATUS_UNKNOWN));
172 }
173 
TEST_F(FidlControllerTest,SendAndReceiveSco)174 TEST_F(FidlControllerTest, SendAndReceiveSco) {
175   RETURN_IF_FATAL(InitializeController());
176   RunLoopUntilIdle();
177   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
178 
179   int controller_cb_count = 0;
180   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kCvsd,
181                              pw::bluetooth::Controller::ScoEncoding::k8Bits,
182                              pw::bluetooth::Controller::ScoSampleRate::k8Khz,
183                              [&controller_cb_count](pw::Status status) {
184                                controller_cb_count++;
185                                EXPECT_EQ(status, PW_STATUS_OK);
186                              });
187   EXPECT_EQ(controller_cb_count, 1);
188 
189   const StaticByteBuffer packet_0(0x00, 0x01, 0x02, 0x03);
190   controller()->SendScoData(packet_0.subspan());
191   RunLoopUntilIdle();
192   ASSERT_EQ(hci_server()->sco_packets_received().size(), 1u);
193   EXPECT_THAT(hci_server()->sco_packets_received()[0], BufferEq(packet_0));
194 
195   const StaticByteBuffer packet_1(0x04, 0x05, 0x06, 0x07);
196   controller()->SendScoData(packet_1.subspan());
197   RunLoopUntilIdle();
198   ASSERT_EQ(hci_server()->sco_packets_received().size(), 2u);
199   EXPECT_THAT(hci_server()->sco_packets_received()[1], BufferEq(packet_1));
200 
201   std::vector<DynamicByteBuffer> received_sco;
202   controller()->SetReceiveScoFunction([&](pw::span<const std::byte> buffer) {
203     received_sco.emplace_back(BufferView(buffer.data(), buffer.size()));
204   });
205 
206   hci_server()->SendSco(packet_1.view());
207   RunLoopUntilIdle();
208   ASSERT_EQ(received_sco.size(), 1u);
209   EXPECT_THAT(received_sco[0], BufferEq(packet_1));
210   EXPECT_EQ(hci_server()->sco_acks_received(), 1u);
211   EXPECT_EQ(hci_server()->acks_received(), 0u);
212 
213   hci_server()->SendSco(packet_1.view());
214   RunLoopUntilIdle();
215   ASSERT_EQ(received_sco.size(), 2u);
216   EXPECT_THAT(received_sco[1], BufferEq(packet_1));
217   EXPECT_EQ(hci_server()->sco_acks_received(), 2u);
218 
219   std::optional<pw::Status> close_status;
220   controller()->Close([&](pw::Status status) { close_status = status; });
221   ASSERT_TRUE(close_status.has_value());
222   EXPECT_EQ(close_status.value(), PW_STATUS_OK);
223 }
224 
TEST_F(FidlControllerTest,SendAndReceiveIso)225 TEST_F(FidlControllerTest, SendAndReceiveIso) {
226   RETURN_IF_FATAL(InitializeController());
227   RunLoopUntilIdle();
228   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
229 
230   const StaticByteBuffer iso_packet_0(0x00, 0x01, 0x02, 0x03);
231   controller()->SendIsoData(iso_packet_0.subspan());
232   RunLoopUntilIdle();
233   ASSERT_EQ(hci_server()->iso_packets_received().size(), 1u);
234   EXPECT_THAT(hci_server()->iso_packets_received()[0], BufferEq(iso_packet_0));
235 
236   const StaticByteBuffer iso_packet_1(0x04, 0x05, 0x06, 0x07);
237   controller()->SendIsoData(iso_packet_1.subspan());
238   RunLoopUntilIdle();
239   ASSERT_EQ(hci_server()->iso_packets_received().size(), 2u);
240   EXPECT_THAT(hci_server()->iso_packets_received()[1], BufferEq(iso_packet_1));
241 
242   std::vector<DynamicByteBuffer> received_iso;
243   controller()->SetReceiveIsoFunction([&](pw::span<const std::byte> buffer) {
244     received_iso.emplace_back(BufferView(buffer.data(), buffer.size()));
245   });
246 
247   hci_server()->SendIso(iso_packet_0.view());
248   RunLoopUntilIdle();
249   ASSERT_EQ(received_iso.size(), 1u);
250   EXPECT_THAT(received_iso[0], BufferEq(iso_packet_0));
251   EXPECT_EQ(hci_server()->acks_received(), 1u);
252 
253   hci_server()->SendIso(iso_packet_1.view());
254   RunLoopUntilIdle();
255   ASSERT_EQ(received_iso.size(), 2u);
256   EXPECT_THAT(received_iso[1], BufferEq(iso_packet_1));
257   EXPECT_EQ(hci_server()->acks_received(), 2u);
258 
259   std::optional<pw::Status> close_status;
260   controller()->Close([&](pw::Status status) { close_status = status; });
261   ASSERT_TRUE(close_status.has_value());
262   EXPECT_EQ(close_status.value(), PW_STATUS_OK);
263 }
264 
TEST_F(FidlControllerTest,ConfigureScoWithFormatCvsdEncoding8BitsSampleRate8Khz)265 TEST_F(FidlControllerTest,
266        ConfigureScoWithFormatCvsdEncoding8BitsSampleRate8Khz) {
267   RETURN_IF_FATAL(InitializeController());
268   RunLoopUntilIdle();
269   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
270 
271   int device_cb_count = 0;
272   hci_server()->set_check_configure_sco(
273       [&device_cb_count](fhbt::ScoCodingFormat format,
274                          fhbt::ScoEncoding encoding,
275                          fhbt::ScoSampleRate rate) mutable {
276         device_cb_count++;
277         EXPECT_EQ(format, fhbt::ScoCodingFormat::kCvsd);
278         EXPECT_EQ(encoding, fhbt::ScoEncoding::kBits8);
279         EXPECT_EQ(rate, fhbt::ScoSampleRate::kKhz8);
280       });
281 
282   int controller_cb_count = 0;
283   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kCvsd,
284                              pw::bluetooth::Controller::ScoEncoding::k8Bits,
285                              pw::bluetooth::Controller::ScoSampleRate::k8Khz,
286                              [&controller_cb_count](pw::Status status) {
287                                controller_cb_count++;
288                                EXPECT_EQ(status, PW_STATUS_OK);
289                              });
290 
291   EXPECT_EQ(device_cb_count, 0);
292   EXPECT_EQ(controller_cb_count, 1);
293   RunLoopUntilIdle();
294   EXPECT_EQ(controller_cb_count, 1);
295   EXPECT_EQ(device_cb_count, 1);
296 }
297 
TEST_F(FidlControllerTest,ConfigureScoWithFormatCvsdEncoding16BitsSampleRate8Khz)298 TEST_F(FidlControllerTest,
299        ConfigureScoWithFormatCvsdEncoding16BitsSampleRate8Khz) {
300   RETURN_IF_FATAL(InitializeController());
301   RunLoopUntilIdle();
302   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
303 
304   hci_server()->set_check_configure_sco([](fhbt::ScoCodingFormat format,
305                                            fhbt::ScoEncoding encoding,
306                                            fhbt::ScoSampleRate rate) {
307     EXPECT_EQ(format, fhbt::ScoCodingFormat::kCvsd);
308     EXPECT_EQ(encoding, fhbt::ScoEncoding::kBits16);
309     EXPECT_EQ(rate, fhbt::ScoSampleRate::kKhz8);
310   });
311 
312   int config_cb_count = 0;
313   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kCvsd,
314                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
315                              pw::bluetooth::Controller::ScoSampleRate::k8Khz,
316                              [&](pw::Status status) {
317                                config_cb_count++;
318                                EXPECT_EQ(status, PW_STATUS_OK);
319                              });
320   RunLoopUntilIdle();
321   EXPECT_EQ(config_cb_count, 1);
322 }
323 
TEST_F(FidlControllerTest,ConfigureScoWithFormatCvsdEncoding16BitsSampleRate16Khz)324 TEST_F(FidlControllerTest,
325        ConfigureScoWithFormatCvsdEncoding16BitsSampleRate16Khz) {
326   RETURN_IF_FATAL(InitializeController());
327   RunLoopUntilIdle();
328   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
329 
330   hci_server()->set_check_configure_sco([](fhbt::ScoCodingFormat format,
331                                            fhbt::ScoEncoding encoding,
332                                            fhbt::ScoSampleRate rate) {
333     EXPECT_EQ(format, fhbt::ScoCodingFormat::kCvsd);
334     EXPECT_EQ(encoding, fhbt::ScoEncoding::kBits16);
335     EXPECT_EQ(rate, fhbt::ScoSampleRate::kKhz16);
336   });
337 
338   int config_cb_count = 0;
339   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kCvsd,
340                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
341                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
342                              [&](pw::Status status) {
343                                config_cb_count++;
344                                EXPECT_EQ(status, PW_STATUS_OK);
345                              });
346   RunLoopUntilIdle();
347   EXPECT_EQ(config_cb_count, 1);
348 }
349 
TEST_F(FidlControllerTest,ConfigureScoWithFormatMsbcEncoding16BitsSampleRate16Khz)350 TEST_F(FidlControllerTest,
351        ConfigureScoWithFormatMsbcEncoding16BitsSampleRate16Khz) {
352   RETURN_IF_FATAL(InitializeController());
353   RunLoopUntilIdle();
354   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
355 
356   hci_server()->set_check_configure_sco([](fhbt::ScoCodingFormat format,
357                                            fhbt::ScoEncoding encoding,
358                                            fhbt::ScoSampleRate rate) {
359     EXPECT_EQ(format, fhbt::ScoCodingFormat::kMsbc);
360     EXPECT_EQ(encoding, fhbt::ScoEncoding::kBits16);
361     EXPECT_EQ(rate, fhbt::ScoSampleRate::kKhz16);
362   });
363 
364   int config_cb_count = 0;
365   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
366                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
367                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
368                              [&](pw::Status status) {
369                                config_cb_count++;
370                                EXPECT_EQ(status, PW_STATUS_OK);
371                              });
372   RunLoopUntilIdle();
373   EXPECT_EQ(config_cb_count, 1);
374 }
375 
TEST_F(FidlControllerTest,ConfigureAndResetScoTwice)376 TEST_F(FidlControllerTest, ConfigureAndResetScoTwice) {
377   RETURN_IF_FATAL(InitializeController());
378   RunLoopUntilIdle();
379   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
380 
381   int device_cb_count = 0;
382   hci_server()->set_reset_sco_callback(
383       [&device_cb_count]() { device_cb_count++; });
384 
385   int config_cb_count_0 = 0;
386   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
387                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
388                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
389                              [&](pw::Status status) {
390                                config_cb_count_0++;
391                                EXPECT_EQ(status, PW_STATUS_OK);
392                              });
393   EXPECT_EQ(config_cb_count_0, 1);
394 
395   int reset_cb_count_0 = 0;
396   controller()->ResetSco([&](pw::Status status) {
397     reset_cb_count_0++;
398     EXPECT_EQ(status, PW_STATUS_OK);
399   });
400 
401   EXPECT_EQ(device_cb_count, 0);
402   EXPECT_EQ(reset_cb_count_0, 0);
403   RunLoopUntilIdle();
404   EXPECT_EQ(device_cb_count, 1);
405   EXPECT_EQ(reset_cb_count_0, 1);
406 
407   int config_cb_count_1 = 0;
408   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
409                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
410                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
411                              [&](pw::Status status) {
412                                config_cb_count_1++;
413                                EXPECT_EQ(status, PW_STATUS_OK) << status.str();
414                              });
415   EXPECT_EQ(config_cb_count_1, 1);
416 
417   int reset_cb_count_1 = 0;
418   controller()->ResetSco([&](pw::Status status) {
419     reset_cb_count_1++;
420     EXPECT_EQ(status, PW_STATUS_OK);
421   });
422 
423   EXPECT_EQ(reset_cb_count_1, 0);
424   RunLoopUntilIdle();
425   EXPECT_EQ(device_cb_count, 2);
426   EXPECT_EQ(reset_cb_count_0, 1);
427   EXPECT_EQ(reset_cb_count_1, 1);
428 }
429 
TEST_F(FidlControllerTest,CloseUnbindsHciProtocol)430 TEST_F(FidlControllerTest, CloseUnbindsHciProtocol) {
431   RETURN_IF_FATAL(InitializeController());
432   RunLoopUntilIdle();
433   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
434 
435   std::optional<pw::Status> close_status;
436   controller()->Close([&](pw::Status status) { close_status = status; });
437   RunLoopUntilIdle();
438   ASSERT_TRUE(close_status.has_value());
439   EXPECT_EQ(close_status.value(), PW_STATUS_OK);
440   EXPECT_FALSE(hci_server()->bound());
441 }
442 
TEST_F(FidlControllerTest,HciServerClosesProtocol)443 TEST_F(FidlControllerTest, HciServerClosesProtocol) {
444   RETURN_IF_FATAL(InitializeController());
445   RunLoopUntilIdle();
446   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
447 
448   hci_server()->Unbind();
449   RunLoopUntilIdle();
450   ASSERT_THAT(controller_error(),
451               ::testing::Optional(pw::Status::Unavailable()));
452 }
453 
TEST_F(FidlControllerTest,VendorGetFeatures)454 TEST_F(FidlControllerTest, VendorGetFeatures) {
455   RETURN_IF_FATAL(InitializeController());
456   RunLoopUntilIdle();
457   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
458 
459   std::optional<FidlController::FeaturesBits> features;
460   controller()->GetFeatures(
461       [&](FidlController::FeaturesBits bits) { features = bits; });
462   RunLoopUntilIdle();
463   ASSERT_TRUE(features.has_value());
464   EXPECT_TRUE(*features & FidlController::FeaturesBits::kSetAclPriorityCommand);
465 
466   std::optional<pw::Status> close_status;
467   controller()->Close([&](pw::Status status) { close_status = status; });
468   ASSERT_TRUE(close_status.has_value());
469   EXPECT_EQ(close_status.value(), PW_STATUS_OK);
470 }
471 
TEST_F(FidlControllerTest,VendorEncodeSetAclPriorityCommandNormal)472 TEST_F(FidlControllerTest, VendorEncodeSetAclPriorityCommandNormal) {
473   RETURN_IF_FATAL(InitializeController());
474   RunLoopUntilIdle();
475   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
476 
477   pw::bluetooth::SetAclPriorityCommandParameters params;
478   params.connection_handle = kConnectionHandle;
479   params.priority = pw::bluetooth::AclPriority::kNormal;
480 
481   std::optional<DynamicByteBuffer> buffer;
482   controller()->EncodeVendorCommand(
483       params, [&](pw::Result<pw::span<const std::byte>> result) {
484         ASSERT_TRUE(result.ok());
485         buffer.emplace(
486             BufferView(result.value().data(), result.value().size()));
487       });
488   RunLoopUntilIdle();
489   ASSERT_TRUE(buffer);
490   EXPECT_THAT(*buffer, BufferEq(kSetAclPriorityNormalCommand));
491 }
492 
TEST_F(FidlControllerTest,VendorEncodeSetAclPriorityCommandSink)493 TEST_F(FidlControllerTest, VendorEncodeSetAclPriorityCommandSink) {
494   RETURN_IF_FATAL(InitializeController());
495   RunLoopUntilIdle();
496   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
497 
498   pw::bluetooth::SetAclPriorityCommandParameters params;
499   params.connection_handle = kConnectionHandle;
500   params.priority = pw::bluetooth::AclPriority::kSink;
501 
502   std::optional<DynamicByteBuffer> buffer;
503   controller()->EncodeVendorCommand(
504       params, [&](pw::Result<pw::span<const std::byte>> result) {
505         ASSERT_TRUE(result.ok());
506         buffer.emplace(
507             BufferView(result.value().data(), result.value().size()));
508       });
509   RunLoopUntilIdle();
510   ASSERT_TRUE(buffer);
511   EXPECT_THAT(*buffer, BufferEq(kSetAclPrioritySinkCommand));
512 }
513 
TEST_F(FidlControllerTest,VendorEncodeSetAclPriorityCommandSource)514 TEST_F(FidlControllerTest, VendorEncodeSetAclPriorityCommandSource) {
515   RETURN_IF_FATAL(InitializeController());
516   RunLoopUntilIdle();
517   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
518 
519   pw::bluetooth::SetAclPriorityCommandParameters params;
520   params.connection_handle = kConnectionHandle;
521   params.priority = pw::bluetooth::AclPriority::kSource;
522 
523   std::optional<DynamicByteBuffer> buffer;
524   controller()->EncodeVendorCommand(
525       params, [&](pw::Result<pw::span<const std::byte>> result) {
526         ASSERT_TRUE(result.ok());
527         buffer.emplace(
528             BufferView(result.value().data(), result.value().size()));
529       });
530   RunLoopUntilIdle();
531   ASSERT_TRUE(buffer);
532   EXPECT_THAT(*buffer, BufferEq(kSetAclPrioritySourceCommand));
533 }
534 
TEST_F(FidlControllerTest,VendorServerClosesChannelBeforeOpenHci)535 TEST_F(FidlControllerTest, VendorServerClosesChannelBeforeOpenHci) {
536   RETURN_IF_FATAL(InitializeController());
537   ASSERT_THAT(complete_status(), std::nullopt);
538   ASSERT_THAT(controller_error(), std::nullopt);
539 
540   vendor_server()->Unbind();
541   RunLoopUntilIdle();
542   ASSERT_THAT(complete_status(),
543               ::testing::Optional(pw::Status::Unavailable()));
544   ASSERT_THAT(controller_error(), std::nullopt);
545 }
546 
TEST_F(FidlControllerTest,VendorServerClosesProtocolBeforeInitialize)547 TEST_F(FidlControllerTest, VendorServerClosesProtocolBeforeInitialize) {
548   vendor_server()->Unbind();
549   RunLoopUntilIdle();
550 
551   RETURN_IF_FATAL(InitializeController());
552   RunLoopUntilIdle();
553   ASSERT_THAT(complete_status(),
554               ::testing::Optional(pw::Status::Unavailable()));
555   ASSERT_THAT(controller_error(), std::nullopt);
556 }
557 
TEST_F(FidlControllerTest,VendorOpenHciError)558 TEST_F(FidlControllerTest, VendorOpenHciError) {
559   // Make OpenHci() return error during controller initialization
560   vendor_server()->set_open_hci_error(true);
561 
562   RETURN_IF_FATAL(InitializeController());
563   RunLoopUntilIdle();
564   ASSERT_THAT(complete_status(), ::testing::Optional(pw::Status::Internal()));
565   ASSERT_THAT(controller_error(), std::nullopt);
566 }
567 
TEST_F(FidlControllerTest,VendorServerClosesProtocol)568 TEST_F(FidlControllerTest, VendorServerClosesProtocol) {
569   RETURN_IF_FATAL(InitializeController());
570   RunLoopUntilIdle();
571   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
572 
573   vendor_server()->Unbind();
574   RunLoopUntilIdle();
575   ASSERT_THAT(controller_error(),
576               ::testing::Optional(pw::Status::Unavailable()));
577 }
578 
579 // Attempting to send a command once the HciTransport protocol has been closed
580 // from the server end may trigger the driver to terminate. Verify that a clean
581 // shutdown will still occur.
TEST_F(FidlControllerTest,EventClosesDriver)582 TEST_F(FidlControllerTest, EventClosesDriver) {
583   RETURN_IF_FATAL(InitializeController());
584   RunLoopUntilIdle();
585   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
586 
587   const StaticByteBuffer kCommandPacket(0x00, 0x01, 0x02, 0x03);
588   const StaticByteBuffer kEventPacket(0x04, 0x05, 0x06, 0x07);
589   controller()->SetEventFunction([&](pw::span<const std::byte> /* buffer */) {
590     hci_server()->Unbind();
591     controller()->SendCommand(kCommandPacket.subspan());
592   });
593   hci_server()->SendEvent(kEventPacket.view());
594   RunLoopUntilIdle();
595 }
596 
TEST_F(FidlControllerTest,ScoServerClosesProtocolUnexpectedly)597 TEST_F(FidlControllerTest, ScoServerClosesProtocolUnexpectedly) {
598   RETURN_IF_FATAL(InitializeController());
599   RunLoopUntilIdle();
600   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
601 
602   int config_cb_count = 0;
603   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
604                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
605                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
606                              [&](pw::Status status) {
607                                config_cb_count++;
608                                EXPECT_EQ(status, PW_STATUS_OK);
609                              });
610   RunLoopUntilIdle();
611   EXPECT_EQ(config_cb_count, 1);
612 
613   EXPECT_TRUE(hci_server()->UnbindSco());
614   RunLoopUntilIdle();
615   EXPECT_THAT(controller_error(), ::testing::Optional(pw::Status::Unknown()));
616 }
617 
TEST_F(FidlControllerTest,ConfigureScoAlreadyConfigured)618 TEST_F(FidlControllerTest, ConfigureScoAlreadyConfigured) {
619   RETURN_IF_FATAL(InitializeController());
620   RunLoopUntilIdle();
621   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
622 
623   int config_cb_count_0 = 0;
624   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
625                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
626                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
627                              [&](pw::Status status) {
628                                config_cb_count_0++;
629                                EXPECT_EQ(status, PW_STATUS_OK);
630                              });
631   int config_cb_count_1 = 0;
632   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
633                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
634                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
635                              [&](pw::Status status) {
636                                config_cb_count_1++;
637                                EXPECT_EQ(status, PW_STATUS_ALREADY_EXISTS);
638                              });
639   EXPECT_EQ(config_cb_count_0, 1);
640   EXPECT_EQ(config_cb_count_1, 1);
641   RunLoopUntilIdle();
642   EXPECT_EQ(config_cb_count_0, 1);
643   EXPECT_EQ(config_cb_count_1, 1);
644 }
645 
TEST_F(FidlControllerTest,ResetScoWhenNotConfiguredFails)646 TEST_F(FidlControllerTest, ResetScoWhenNotConfiguredFails) {
647   RETURN_IF_FATAL(InitializeController());
648   RunLoopUntilIdle();
649   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
650 
651   int device_cb_count = 0;
652   hci_server()->set_reset_sco_callback(
653       [&device_cb_count]() { device_cb_count++; });
654 
655   int reset_cb_count = 0;
656   controller()->ResetSco([&](pw::Status status) {
657     reset_cb_count++;
658     EXPECT_EQ(status, PW_STATUS_FAILED_PRECONDITION);
659   });
660 
661   EXPECT_EQ(device_cb_count, 0);
662   EXPECT_EQ(reset_cb_count, 1);
663   RunLoopUntilIdle();
664   EXPECT_EQ(device_cb_count, 0);
665   EXPECT_EQ(reset_cb_count, 1);
666 }
667 
TEST_F(FidlControllerTest,ResetScoAlreadyPending)668 TEST_F(FidlControllerTest, ResetScoAlreadyPending) {
669   RETURN_IF_FATAL(InitializeController());
670   RunLoopUntilIdle();
671   ASSERT_THAT(complete_status(), ::testing::Optional(PW_STATUS_OK));
672 
673   int device_cb_count = 0;
674   hci_server()->set_reset_sco_callback(
675       [&device_cb_count]() { device_cb_count++; });
676 
677   int config_cb_count_0 = 0;
678   controller()->ConfigureSco(pw::bluetooth::Controller::ScoCodingFormat::kMsbc,
679                              pw::bluetooth::Controller::ScoEncoding::k16Bits,
680                              pw::bluetooth::Controller::ScoSampleRate::k16Khz,
681                              [&](pw::Status status) {
682                                config_cb_count_0++;
683                                EXPECT_EQ(status, PW_STATUS_OK);
684                              });
685   EXPECT_EQ(config_cb_count_0, 1);
686 
687   int reset_cb_count_0 = 0;
688   controller()->ResetSco([&](pw::Status status) {
689     reset_cb_count_0++;
690     EXPECT_EQ(status, PW_STATUS_OK);
691   });
692   int reset_cb_count_1 = 0;
693   controller()->ResetSco([&](pw::Status status) {
694     reset_cb_count_1++;
695     EXPECT_EQ(status, PW_STATUS_ALREADY_EXISTS);
696   });
697 
698   EXPECT_EQ(device_cb_count, 0);
699   EXPECT_EQ(reset_cb_count_0, 0);
700   EXPECT_EQ(reset_cb_count_1, 1);
701   RunLoopUntilIdle();
702   EXPECT_EQ(device_cb_count, 1);
703   EXPECT_EQ(reset_cb_count_0, 1);
704   EXPECT_EQ(reset_cb_count_1, 1);
705 }
706 
707 }  // namespace bt::controllers
708