1 /*
2 * Copyright 2020 HIMSA II K/S - www.himsa.com.
3 * Represented by EHIMA - www.ehima.com
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20
21 #include "btm_iso_api.h"
22 #include "hci/controller_interface_mock.h"
23 #include "hci/hci_packets.h"
24 #include "hci/include/hci_layer.h"
25 #include "mock_hcic_layer.h"
26 #include "osi/include/allocator.h"
27 #include "stack/btm/btm_dev.h"
28 #include "stack/include/bt_hdr.h"
29 #include "stack/include/bt_types.h"
30 #include "stack/include/hci_error_code.h"
31 #include "stack/include/hcidefs.h"
32 #include "test/mock/mock_main_shim_entry.h"
33 #include "test/mock/mock_main_shim_hci_layer.h"
34
35 using bluetooth::hci::IsoManager;
36 using testing::_;
37 using testing::AnyNumber;
38 using testing::AtLeast;
39 using testing::Eq;
40 using testing::Matcher;
41 using testing::Return;
42 using testing::SaveArg;
43 using testing::StrictMock;
44 using testing::Test;
45
46 // for function pointer testing purpose
47 bool IsIsoActive = false;
48
btm_find_dev_by_handle(uint16_t)49 tBTM_SEC_DEV_REC* btm_find_dev_by_handle(uint16_t /* handle */) {
50 return nullptr;
51 }
BTM_LogHistory(const std::string &,const RawAddress &,const std::string &,const std::string &)52 void BTM_LogHistory(const std::string& /* tag */,
53 const RawAddress& /* bd_addr */,
54 const std::string& /* msg */,
55 const std::string& /* extra */) {}
56
57 namespace bluetooth::shim {
58 class IsoInterface {
59 public:
60 virtual void HciSend(BT_HDR* packet) = 0;
61 virtual ~IsoInterface() = default;
62 };
63
64 class MockIsoInterface : public IsoInterface {
65 public:
66 MOCK_METHOD((void), HciSend, (BT_HDR * p_msg), (override));
67 };
68
69 static MockIsoInterface* iso_interface = nullptr;
SetMockIsoInterface(MockIsoInterface * interface)70 static void SetMockIsoInterface(MockIsoInterface* interface) {
71 iso_interface = interface;
72 }
73
set_data_cb(base::Callback<void (const base::Location &,BT_HDR *)>)74 static void set_data_cb(
75 base::Callback<void(const base::Location&, BT_HDR*)> /* send_data_cb */) {
76 FAIL() << __func__ << " should never be called";
77 }
78
transmit_command(const BT_HDR *,command_complete_cb,command_status_cb,void *)79 static void transmit_command(const BT_HDR* /* command */,
80 command_complete_cb /* complete_callback */,
81 command_status_cb /* status_cb */,
82 void* /* context */) {
83 FAIL() << __func__ << " should never be called";
84 }
85
transmit_downward(void * data,uint16_t)86 static void transmit_downward(void* data, uint16_t /* iso_Data_size */) {
87 iso_interface->HciSend((BT_HDR*)data);
88 osi_free(data);
89 }
90
91 static hci_t interface = {.set_data_cb = set_data_cb,
92 .transmit_command = transmit_command,
93 .transmit_downward = transmit_downward};
94
95 } // namespace bluetooth::shim
96
97 namespace {
98 class MockCigCallbacks : public bluetooth::hci::iso_manager::CigCallbacks {
99 public:
100 MockCigCallbacks() = default;
101 MockCigCallbacks(const MockCigCallbacks&) = delete;
102 MockCigCallbacks& operator=(const MockCigCallbacks&) = delete;
103
104 ~MockCigCallbacks() override = default;
105
106 MOCK_METHOD((void), OnSetupIsoDataPath,
107 (uint8_t status, uint16_t conn_handle, uint8_t cig_id),
108 (override));
109 MOCK_METHOD((void), OnRemoveIsoDataPath,
110 (uint8_t status, uint16_t conn_handle, uint8_t cig_id),
111 (override));
112 MOCK_METHOD((void), OnIsoLinkQualityRead,
113 (uint8_t conn_handle, uint8_t cig_id, uint32_t txUnackedPackets,
114 uint32_t txFlushedPackets, uint32_t txLastSubeventPackets,
115 uint32_t retransmittedPackets, uint32_t crcErrorPackets,
116 uint32_t rxUnreceivedPackets, uint32_t duplicatePackets),
117 (override));
118
119 MOCK_METHOD((void), OnCisEvent, (uint8_t event, void* data), (override));
120 MOCK_METHOD((void), OnCigEvent, (uint8_t event, void* data), (override));
121 };
122
123 class MockBigCallbacks : public bluetooth::hci::iso_manager::BigCallbacks {
124 public:
125 MockBigCallbacks() = default;
126 MockBigCallbacks(const MockBigCallbacks&) = delete;
127 MockBigCallbacks& operator=(const MockBigCallbacks&) = delete;
128
129 ~MockBigCallbacks() override = default;
130
131 MOCK_METHOD((void), OnSetupIsoDataPath,
132 (uint8_t status, uint16_t conn_handle, uint8_t big_id),
133 (override));
134 MOCK_METHOD((void), OnRemoveIsoDataPath,
135 (uint8_t status, uint16_t conn_handle, uint8_t big_id),
136 (override));
137
138 MOCK_METHOD((void), OnBigEvent, (uint8_t event, void* data), (override));
139 };
140 } // namespace
141
142 class IsoManagerTest : public Test {
143 protected:
SetUp()144 void SetUp() override {
145 bluetooth::shim::SetMockIsoInterface(&iso_interface_);
146 hcic::SetMockHcicInterface(&hcic_interface_);
147 bluetooth::shim::testing::hci_layer_set_interface(
148 &bluetooth::shim::interface);
149 bluetooth::hci::testing::mock_controller_ = &controller_;
150
151 big_callbacks_.reset(new MockBigCallbacks());
152 cig_callbacks_.reset(new MockCigCallbacks());
153 IsIsoActive = false;
154
155 iso_sizes_.total_num_le_packets_ = 6;
156 iso_sizes_.le_data_packet_length_ = 1024;
157 ON_CALL(controller_, GetControllerIsoBufferSize())
158 .WillByDefault(Return(iso_sizes_));
159
160 InitIsoManager();
161 }
162
TearDown()163 void TearDown() override {
164 CleanupIsoManager();
165
166 big_callbacks_.reset();
167 cig_callbacks_.reset();
168
169 bluetooth::shim::SetMockIsoInterface(nullptr);
170 hcic::SetMockHcicInterface(nullptr);
171 bluetooth::shim::testing::hci_layer_set_interface(nullptr);
172 bluetooth::hci::testing::mock_controller_ = nullptr;
173 }
174
InitIsoManager()175 virtual void InitIsoManager() {
176 manager_instance_ = IsoManager::GetInstance();
177 manager_instance_->Start();
178 manager_instance_->RegisterCigCallbacks(cig_callbacks_.get());
179 manager_instance_->RegisterBigCallbacks(big_callbacks_.get());
180 manager_instance_->RegisterOnIsoTrafficActiveCallback(iso_active_callback);
181
182 // Default mock SetCigParams action
183 volatile_test_cig_create_cmpl_evt_ = kDefaultCigParamsEvt;
184 ON_CALL(hcic_interface_, SetCigParams)
185 .WillByDefault([this](auto cig_id, auto,
186 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
187 uint8_t hci_mock_rsp_buffer
188 [3 + sizeof(uint16_t) * this->volatile_test_cig_create_cmpl_evt_
189 .conn_handles.size()];
190 uint8_t* p = hci_mock_rsp_buffer;
191
192 UINT8_TO_STREAM(p, this->volatile_test_cig_create_cmpl_evt_.status);
193 UINT8_TO_STREAM(p, cig_id);
194 UINT8_TO_STREAM(
195 p, this->volatile_test_cig_create_cmpl_evt_.conn_handles.size());
196 for (auto handle :
197 this->volatile_test_cig_create_cmpl_evt_.conn_handles) {
198 UINT16_TO_STREAM(p, handle);
199 }
200
201 std::move(cb).Run(
202 hci_mock_rsp_buffer,
203 3 + sizeof(uint16_t) * this->volatile_test_cig_create_cmpl_evt_
204 .conn_handles.size());
205 return 0;
206 });
207
208 // Default mock CreateCis action
209 ON_CALL(hcic_interface_, CreateCis)
210 .WillByDefault(
211 [](uint8_t num_cis, const EXT_CIS_CREATE_CFG* cis_cfg,
212 base::OnceCallback<void(uint8_t*, uint16_t)> /* cb */) {
213 for (const EXT_CIS_CREATE_CFG* cis = cis_cfg; num_cis != 0;
214 num_cis--, cis++) {
215 std::vector<uint8_t> buf(28);
216 uint8_t* p = buf.data();
217 UINT8_TO_STREAM(p, HCI_SUCCESS);
218 UINT16_TO_STREAM(p, cis->cis_conn_handle);
219 UINT24_TO_STREAM(p, 0xEA); // CIG sync delay
220 UINT24_TO_STREAM(p, 0xEB); // CIS sync delay
221 UINT24_TO_STREAM(p, 0xEC); // transport latency mtos
222 UINT24_TO_STREAM(p, 0xED); // transport latency stom
223 UINT8_TO_STREAM(p, 0x01); // phy mtos
224 UINT8_TO_STREAM(p, 0x02); // phy stom
225 UINT8_TO_STREAM(p, 0x01); // nse
226 UINT8_TO_STREAM(p, 0x02); // bn mtos
227 UINT8_TO_STREAM(p, 0x03); // bn stom
228 UINT8_TO_STREAM(p, 0x04); // ft mtos
229 UINT8_TO_STREAM(p, 0x05); // ft stom
230 UINT16_TO_STREAM(p, 0x00FA); // Max PDU mtos
231 UINT16_TO_STREAM(p, 0x00FB); // Max PDU stom
232 UINT16_TO_STREAM(p, 0x0C60); // ISO interval
233
234 IsoManager::GetInstance()->HandleHciEvent(
235 HCI_BLE_CIS_EST_EVT, buf.data(), buf.size());
236 }
237 });
238
239 // Default mock disconnect action
240 ON_CALL(hcic_interface_, Disconnect)
241 .WillByDefault([](uint16_t handle, uint8_t reason) {
242 IsoManager::GetInstance()->HandleDisconnect(handle, reason);
243 });
244
245 // Default mock CreateBig HCI action
246 volatile_test_big_params_evt_ = kDefaultBigParamsEvt;
247 ON_CALL(hcic_interface_, CreateBig)
248 .WillByDefault(
249 [this](auto big_handle,
250 bluetooth::hci::iso_manager::big_create_params big_params) {
251 std::vector<uint8_t> buf(big_params.num_bis * sizeof(uint16_t) +
252 18);
253 uint8_t* p = buf.data();
254 UINT8_TO_STREAM(p, HCI_SUCCESS);
255 UINT8_TO_STREAM(p, big_handle);
256
257 ASSERT_TRUE(big_params.num_bis <=
258 volatile_test_big_params_evt_.conn_handles.size());
259
260 UINT24_TO_STREAM(p, volatile_test_big_params_evt_.big_sync_delay);
261 UINT24_TO_STREAM(
262 p, volatile_test_big_params_evt_.transport_latency_big);
263 UINT8_TO_STREAM(p, big_params.phy);
264 UINT8_TO_STREAM(p, volatile_test_big_params_evt_.nse);
265 UINT8_TO_STREAM(p, volatile_test_big_params_evt_.bn);
266 UINT8_TO_STREAM(p, volatile_test_big_params_evt_.pto);
267 UINT8_TO_STREAM(p, volatile_test_big_params_evt_.irc);
268 UINT16_TO_STREAM(p, volatile_test_big_params_evt_.max_pdu);
269 UINT16_TO_STREAM(p, volatile_test_big_params_evt_.iso_interval);
270
271 UINT8_TO_STREAM(p, big_params.num_bis);
272 for (auto i = 0; i < big_params.num_bis; ++i) {
273 UINT16_TO_STREAM(p,
274 volatile_test_big_params_evt_.conn_handles[i]);
275 }
276
277 IsoManager::GetInstance()->HandleHciEvent(
278 HCI_BLE_CREATE_BIG_CPL_EVT, buf.data(), buf.size());
279 });
280
281 // Default mock TerminateBig HCI action
282 ON_CALL(hcic_interface_, TerminateBig)
283 .WillByDefault([](auto big_handle, uint8_t reason) {
284 std::vector<uint8_t> buf(2);
285 uint8_t* p = buf.data();
286 UINT8_TO_STREAM(p, big_handle);
287 UINT8_TO_STREAM(p, reason);
288
289 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
290 buf.data(), buf.size());
291 });
292
293 // Default mock SetupIsoDataPath HCI action
294 ON_CALL(hcic_interface_, SetupIsoDataPath)
295 .WillByDefault(
296 [](uint16_t iso_handle, uint8_t /* data_path_dir */,
297 uint8_t /* data_path_id */, uint8_t /* codec_id_format */,
298 uint16_t /* codec_id_company */, uint16_t /* codec_id_vendor */,
299 uint32_t /* controller_delay */,
300 std::vector<uint8_t> /* codec_conf */,
301 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
302 std::vector<uint8_t> buf(3);
303 uint8_t* p = buf.data();
304 UINT8_TO_STREAM(p, HCI_SUCCESS);
305 UINT16_TO_STREAM(p, iso_handle);
306
307 std::move(cb).Run(buf.data(), buf.size());
308 });
309
310 // Default mock RemoveIsoDataPath HCI action
311 ON_CALL(hcic_interface_, RemoveIsoDataPath)
312 .WillByDefault([](uint16_t iso_handle, uint8_t /* data_path_dir */,
313 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
314 std::vector<uint8_t> buf(3);
315 uint8_t* p = buf.data();
316 UINT8_TO_STREAM(p, HCI_SUCCESS);
317 UINT16_TO_STREAM(p, iso_handle);
318
319 std::move(cb).Run(buf.data(), buf.size());
320 });
321 }
322
CleanupIsoManager()323 virtual void CleanupIsoManager() {
324 manager_instance_->Stop();
325 manager_instance_ = nullptr;
326 }
327
328 static const bluetooth::hci::iso_manager::big_create_params kDefaultBigParams;
329 static const bluetooth::hci::iso_manager::cig_create_params kDefaultCigParams;
330 static const bluetooth::hci::iso_manager::cig_create_params
331 kDefaultCigParams2;
332 static const bluetooth::hci::iso_manager::cig_create_cmpl_evt
333 kDefaultCigParamsEvt;
334 static const bluetooth::hci::iso_manager::big_create_cmpl_evt
335 kDefaultBigParamsEvt;
336 static const bluetooth::hci::iso_manager::iso_data_path_params
337 kDefaultIsoDataPathParams;
338
339 bluetooth::hci::iso_manager::cig_create_cmpl_evt
340 volatile_test_cig_create_cmpl_evt_;
341 bluetooth::hci::iso_manager::big_create_cmpl_evt
342 volatile_test_big_params_evt_;
343
344 IsoManager* manager_instance_;
345 bluetooth::shim::MockIsoInterface iso_interface_;
346 hcic::MockHcicInterface hcic_interface_;
347 bluetooth::hci::testing::MockControllerInterface controller_;
348 bluetooth::hci::LeBufferSize iso_sizes_;
349
350 std::unique_ptr<MockBigCallbacks> big_callbacks_;
351 std::unique_ptr<MockCigCallbacks> cig_callbacks_;
__anon7ba1c2620902(bool active) 352 void (*iso_active_callback)(bool) = [](bool active) { IsIsoActive = active; };
353 };
354
355 const bluetooth::hci::iso_manager::cig_create_cmpl_evt
356 IsoManagerTest::kDefaultCigParamsEvt = {
357 .status = 0x00,
358 .cig_id = 128,
359 .conn_handles = std::vector<uint16_t>({0x0EFF, 0x00FF}),
360 };
361
362 const bluetooth::hci::iso_manager::big_create_cmpl_evt
363 IsoManagerTest::kDefaultBigParamsEvt = {
364 .status = 0x00,
365 .big_id = 0,
366 .big_sync_delay = 0x0080de,
367 .transport_latency_big = 0x00cefe,
368 .phy = 0x02,
369 .nse = 4,
370 .bn = 1,
371 .pto = 0,
372 .irc = 4,
373 .max_pdu = 108,
374 .iso_interval = 6,
375 .conn_handles = std::vector<uint16_t>({0x0EFE, 0x0E00}),
376 };
377
378 const bluetooth::hci::iso_manager::iso_data_path_params
379 IsoManagerTest::kDefaultIsoDataPathParams = {
380 .data_path_dir = bluetooth::hci::iso_manager::kIsoDataPathDirectionOut,
381 .data_path_id = bluetooth::hci::iso_manager::kIsoDataPathHci,
382 .codec_id_format = 0x06,
383 .codec_id_company = 0,
384 .codec_id_vendor = 0,
385 .controller_delay = 0,
386 .codec_conf = {0x02, 0x01, 0x02},
387 };
388
389 const bluetooth::hci::iso_manager::big_create_params
390 IsoManagerTest::kDefaultBigParams = {
391 .adv_handle = 0x00,
392 .num_bis = 2,
393 .sdu_itv = 0x002710,
394 .max_sdu_size = 108,
395 .max_transport_latency = 0x3c,
396 .rtn = 3,
397 .phy = 0x02,
398 .packing = 0x00,
399 .framing = 0x00,
400 .enc = 0,
401 .enc_code = std::array<uint8_t, 16>({0}),
402 };
403
404 const bluetooth::hci::iso_manager::cig_create_params
405 IsoManagerTest::kDefaultCigParams = {
406 .sdu_itv_mtos = 0x00002710,
407 .sdu_itv_stom = 0x00002711,
408 .sca = bluetooth::hci::iso_manager::kIsoSca0To20Ppm,
409 .packing = 0x00,
410 .framing = 0x01,
411 .max_trans_lat_stom = 0x000A,
412 .max_trans_lat_mtos = 0x0009,
413 .cis_cfgs =
414 {
415 // CIS #1
416 {
417 .cis_id = 1,
418 .max_sdu_size_mtos = 0x0028,
419 .max_sdu_size_stom = 0x0027,
420 .phy_mtos = 0x04,
421 .phy_stom = 0x03,
422 .rtn_mtos = 0x02,
423 .rtn_stom = 0x01,
424 },
425 // CIS #2
426 {
427 .cis_id = 2,
428 .max_sdu_size_mtos = 0x0029,
429 .max_sdu_size_stom = 0x002A,
430 .phy_mtos = 0x09,
431 .phy_stom = 0x08,
432 .rtn_mtos = 0x07,
433 .rtn_stom = 0x06,
434 },
435 },
436 };
437
438 const bluetooth::hci::iso_manager::cig_create_params
439 IsoManagerTest::kDefaultCigParams2 = {
440 .sdu_itv_mtos = 0x00002709,
441 .sdu_itv_stom = 0x00002700,
442 .sca = bluetooth::hci::iso_manager::kIsoSca0To20Ppm,
443 .packing = 0x01,
444 .framing = 0x00,
445 .max_trans_lat_stom = 0x000B,
446 .max_trans_lat_mtos = 0x0006,
447 .cis_cfgs =
448 {
449 // CIS #1
450 {
451 .cis_id = 1,
452 .max_sdu_size_mtos = 0x0022,
453 .max_sdu_size_stom = 0x0022,
454 .phy_mtos = 0x01,
455 .phy_stom = 0x02,
456 .rtn_mtos = 0x02,
457 .rtn_stom = 0x01,
458 },
459 // CIS #2
460 {
461 .cis_id = 2,
462 .max_sdu_size_mtos = 0x002A,
463 .max_sdu_size_stom = 0x002B,
464 .phy_mtos = 0x06,
465 .phy_stom = 0x06,
466 .rtn_mtos = 0x07,
467 .rtn_stom = 0x07,
468 },
469 },
470 };
471
472 class IsoManagerDeathTest : public IsoManagerTest {};
473
474 class IsoManagerDeathTestNoInit : public IsoManagerTest {
475 protected:
InitIsoManager()476 void InitIsoManager() override { /* DO NOTHING */
477 }
478
CleanupIsoManager()479 void CleanupIsoManager() override { /* DO NOTHING */
480 }
481 };
482
483 class IsoManagerDeathTestNoCleanup : public IsoManagerTest {
484 protected:
CleanupIsoManager()485 void CleanupIsoManager() override { /* DO NOTHING */
486 }
487 };
488
operator ==(const EXT_CIS_CFG & x,const EXT_CIS_CFG & y)489 bool operator==(const EXT_CIS_CFG& x, const EXT_CIS_CFG& y) {
490 return ((x.cis_id == y.cis_id) &&
491 (x.max_sdu_size_mtos == y.max_sdu_size_mtos) &&
492 (x.max_sdu_size_stom == y.max_sdu_size_stom) &&
493 (x.phy_mtos == y.phy_mtos) && (x.phy_stom == y.phy_stom) &&
494 (x.rtn_mtos == y.rtn_mtos) && (x.rtn_stom == y.rtn_stom));
495 }
496
operator ==(const struct bluetooth::hci::iso_manager::cig_create_params & x,const struct bluetooth::hci::iso_manager::cig_create_params & y)497 bool operator==(
498 const struct bluetooth::hci::iso_manager::cig_create_params& x,
499 const struct bluetooth::hci::iso_manager::cig_create_params& y) {
500 return ((x.sdu_itv_mtos == y.sdu_itv_mtos) &&
501 (x.sdu_itv_stom == y.sdu_itv_stom) && (x.sca == y.sca) &&
502 (x.packing == y.packing) && (x.framing == y.framing) &&
503 (x.max_trans_lat_stom == y.max_trans_lat_stom) &&
504 (x.max_trans_lat_mtos == y.max_trans_lat_mtos) &&
505 std::is_permutation(x.cis_cfgs.begin(), x.cis_cfgs.end(),
506 y.cis_cfgs.begin()));
507 }
508
operator ==(const struct bluetooth::hci::iso_manager::big_create_params & x,const struct bluetooth::hci::iso_manager::big_create_params & y)509 bool operator==(
510 const struct bluetooth::hci::iso_manager::big_create_params& x,
511 const struct bluetooth::hci::iso_manager::big_create_params& y) {
512 return ((x.adv_handle == y.adv_handle) && (x.num_bis == y.num_bis) &&
513 (x.sdu_itv == y.sdu_itv) && (x.max_sdu_size == y.max_sdu_size) &&
514 (x.max_transport_latency == y.max_transport_latency) &&
515 (x.rtn == y.rtn) && (x.phy == y.phy) && (x.packing == y.packing) &&
516 (x.framing == y.framing) && (x.enc == y.enc) &&
517 (x.enc_code == y.enc_code));
518 }
519
520 namespace iso_matchers {
521 MATCHER_P(Eq, value, "") { return (arg == value); }
522 MATCHER_P2(EqPointedArray, value, len, "") {
523 return (!std::memcmp(arg, value, len));
524 }
525 } // namespace iso_matchers
526
TEST_F(IsoManagerTest,SingletonAccess)527 TEST_F(IsoManagerTest, SingletonAccess) {
528 auto* iso_mgr = IsoManager::GetInstance();
529 ASSERT_EQ(manager_instance_, iso_mgr);
530 }
531
TEST_F(IsoManagerTest,RegisterCallbacks)532 TEST_F(IsoManagerTest, RegisterCallbacks) {
533 auto* iso_mgr = IsoManager::GetInstance();
534 ASSERT_EQ(manager_instance_, iso_mgr);
535
536 iso_mgr->RegisterBigCallbacks(big_callbacks_.get());
537 iso_mgr->RegisterCigCallbacks(cig_callbacks_.get());
538 iso_mgr->RegisterOnIsoTrafficActiveCallback(iso_active_callback);
539 }
540
TEST_F(IsoManagerDeathTestNoInit,RegisterNullBigCallbacks)541 TEST_F(IsoManagerDeathTestNoInit, RegisterNullBigCallbacks) {
542 IsoManager::GetInstance()->Start();
543
544 ASSERT_EXIT(IsoManager::GetInstance()->RegisterBigCallbacks(nullptr),
545 ::testing::KilledBySignal(SIGABRT), "Invalid BIG callbacks");
546
547 // Manual cleanup as IsoManagerDeathTest has no 'generic' cleanup
548 IsoManager::GetInstance()->Stop();
549 }
550
TEST_F(IsoManagerDeathTestNoInit,RegisterNullCigCallbacks)551 TEST_F(IsoManagerDeathTestNoInit, RegisterNullCigCallbacks) {
552 IsoManager::GetInstance()->Start();
553
554 ASSERT_EXIT(IsoManager::GetInstance()->RegisterCigCallbacks(nullptr),
555 ::testing::KilledBySignal(SIGABRT), "Invalid CIG callbacks");
556
557 // Manual cleanup as IsoManagerDeathTest has no 'generic' cleanup
558 IsoManager::GetInstance()->Stop();
559 }
560
561 // Verify hci layer being called by the Iso Manager
TEST_F(IsoManagerTest,CreateCigHciCall)562 TEST_F(IsoManagerTest, CreateCigHciCall) {
563 for (uint8_t i = 220; i != 60; ++i) {
564 EXPECT_CALL(hcic_interface_,
565 SetCigParams(i, iso_matchers::Eq(kDefaultCigParams), _))
566 .Times(1)
567 .RetiresOnSaturation();
568 IsoManager::GetInstance()->CreateCig(i, kDefaultCigParams);
569 }
570 }
571
572 // Check handling create cig request twice with the same CIG id
TEST_F(IsoManagerDeathTest,CreateSameCigTwice)573 TEST_F(IsoManagerDeathTest, CreateSameCigTwice) {
574 bluetooth::hci::iso_manager::cig_create_cmpl_evt evt;
575 evt.status = 0x01;
576 EXPECT_CALL(
577 *cig_callbacks_,
578 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnCreateCmpl, _))
579 .WillOnce([&evt](uint8_t /* type */, void* data) {
580 evt = *static_cast<bluetooth::hci::iso_manager::cig_create_cmpl_evt*>(
581 data);
582 return 0;
583 });
584
585 volatile_test_cig_create_cmpl_evt_.cig_id = 127;
586 IsoManager::GetInstance()->CreateCig(
587 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
588 ASSERT_EQ(evt.status, HCI_SUCCESS);
589
590 // Second call with the same CIG ID should fail
591 ASSERT_EXIT(IsoManager::GetInstance()->CreateCig(
592 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams),
593 ::testing::KilledBySignal(SIGABRT), "already exists");
594 }
595
596 // Check for handling invalid length response from the faulty controller
TEST_F(IsoManagerDeathTest,CreateCigCallbackInvalidRspPacket)597 TEST_F(IsoManagerDeathTest, CreateCigCallbackInvalidRspPacket) {
598 uint8_t hci_mock_rsp_buffer[] = {0x00, 0x00};
599 ON_CALL(hcic_interface_, SetCigParams)
600 .WillByDefault(
601 [&hci_mock_rsp_buffer](
602 auto, auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
603 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
604 return 0;
605 });
606
607 ASSERT_EXIT(IsoManager::GetInstance()->CreateCig(128, kDefaultCigParams),
608 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
609 }
610
611 // Check for handling invalid length response from the faulty controller
TEST_F(IsoManagerDeathTest,CreateCigCallbackInvalidRspPacket2)612 TEST_F(IsoManagerDeathTest, CreateCigCallbackInvalidRspPacket2) {
613 uint8_t hci_mock_rsp_buffer[] = {0x00, 0x00, 0x02, 0x01, 0x00};
614 ON_CALL(hcic_interface_, SetCigParams)
615 .WillByDefault(
616 [&hci_mock_rsp_buffer](
617 auto, auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
618 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
619 return 0;
620 });
621
622 ASSERT_EXIT(IsoManager::GetInstance()->CreateCig(128, kDefaultCigParams),
623 ::testing::KilledBySignal(SIGABRT), "Invalid CIS count");
624 }
625
626 // Check if IsoManager properly handles error responses from HCI layer
TEST_F(IsoManagerTest,CreateCigCallbackInvalidStatus)627 TEST_F(IsoManagerTest, CreateCigCallbackInvalidStatus) {
628 uint8_t rsp_cig_id = 128;
629 uint8_t rsp_status = 0x01;
630 uint8_t rsp_cis_cnt = 3;
631 uint8_t hci_mock_rsp_buffer[] = {rsp_status, rsp_cig_id, rsp_cis_cnt};
632
633 ON_CALL(hcic_interface_, SetCigParams)
634 .WillByDefault(
635 [&hci_mock_rsp_buffer](
636 auto, auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
637 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
638 return 0;
639 });
640
641 bluetooth::hci::iso_manager::cig_create_cmpl_evt evt;
642 EXPECT_CALL(
643 *cig_callbacks_,
644 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnCreateCmpl, _))
645 .WillOnce([&evt](uint8_t /* type */, void* data) {
646 evt = *static_cast<bluetooth::hci::iso_manager::cig_create_cmpl_evt*>(
647 data);
648 return 0;
649 });
650
651 IsoManager::GetInstance()->CreateCig(rsp_cig_id, kDefaultCigParams);
652 ASSERT_EQ(evt.cig_id, rsp_cig_id);
653 ASSERT_EQ(evt.status, rsp_status);
654 ASSERT_TRUE(evt.conn_handles.empty());
655 }
656
657 // Check valid callback response
TEST_F(IsoManagerTest,CreateCigCallbackValid)658 TEST_F(IsoManagerTest, CreateCigCallbackValid) {
659 bluetooth::hci::iso_manager::cig_create_cmpl_evt evt;
660 EXPECT_CALL(
661 *cig_callbacks_,
662 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnCreateCmpl, _))
663 .WillOnce([&evt](uint8_t /* type */, void* data) {
664 evt = *static_cast<bluetooth::hci::iso_manager::cig_create_cmpl_evt*>(
665 data);
666 return 0;
667 });
668
669 IsoManager::GetInstance()->CreateCig(
670 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
671 ASSERT_EQ(evt.cig_id, volatile_test_cig_create_cmpl_evt_.cig_id);
672 ASSERT_EQ(evt.status, volatile_test_cig_create_cmpl_evt_.status);
673 ASSERT_EQ(evt.conn_handles.size(), 2u);
674 ASSERT_TRUE(
675 std::is_permutation(evt.conn_handles.begin(), evt.conn_handles.end(),
676 std::vector<uint16_t>({0x0EFF, 0x00FF}).begin()));
677 }
678
TEST_F(IsoManagerTest,CreateCigLateArrivingCallback)679 TEST_F(IsoManagerTest, CreateCigLateArrivingCallback) {
680 // Catch the callback
681 base::OnceCallback<void(uint8_t*, uint16_t)> iso_cb;
682 ON_CALL(hcic_interface_, SetCigParams)
683 .WillByDefault([&](auto /* cig_id */, auto,
684 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
685 iso_cb = std::move(cb);
686 });
687
688 IsoManager::GetInstance()->CreateCig(
689 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
690
691 // Stop the IsoManager before calling the callback
692 IsoManager::GetInstance()->Stop();
693
694 // Call the callback and expect no call
695 EXPECT_CALL(*cig_callbacks_, OnCigEvent(_, _)).Times(0);
696 ASSERT_FALSE(iso_cb.is_null());
697
698 uint8_t hci_mock_rsp_buffer[3 + sizeof(uint16_t) *
699 volatile_test_cig_create_cmpl_evt_
700 .conn_handles.size()];
701 uint8_t* p = hci_mock_rsp_buffer;
702 UINT8_TO_STREAM(p, volatile_test_cig_create_cmpl_evt_.status);
703 UINT8_TO_STREAM(p, volatile_test_cig_create_cmpl_evt_.cig_id);
704 UINT8_TO_STREAM(p, volatile_test_cig_create_cmpl_evt_.conn_handles.size());
705 for (auto handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
706 UINT16_TO_STREAM(p, handle);
707 }
708 std::move(iso_cb).Run(
709 hci_mock_rsp_buffer,
710 3 + sizeof(uint16_t) *
711 volatile_test_cig_create_cmpl_evt_.conn_handles.size());
712 }
713
714 // Check if CIG reconfigure triggers HCI layer call
TEST_F(IsoManagerTest,ReconfigureCigHciCall)715 TEST_F(IsoManagerTest, ReconfigureCigHciCall) {
716 IsoManager::GetInstance()->CreateCig(
717 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
718
719 EXPECT_CALL(hcic_interface_,
720 SetCigParams(volatile_test_cig_create_cmpl_evt_.cig_id,
721 iso_matchers::Eq(kDefaultCigParams), _))
722 .Times(1);
723 IsoManager::GetInstance()->ReconfigureCig(
724 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
725 }
726
727 // Verify handlidng invalid call - reconfiguring invalid CIG
TEST_F(IsoManagerDeathTest,ReconfigureCigWithNoSuchCig)728 TEST_F(IsoManagerDeathTest, ReconfigureCigWithNoSuchCig) {
729 ASSERT_EXIT(IsoManager::GetInstance()->ReconfigureCig(128, kDefaultCigParams),
730 ::testing::KilledBySignal(SIGABRT), "No such cig");
731 }
732
TEST_F(IsoManagerDeathTest,ReconfigureCigInvalidRspPacket)733 TEST_F(IsoManagerDeathTest, ReconfigureCigInvalidRspPacket) {
734 uint8_t hci_mock_rsp_buffer[] = {0x00, 0x00};
735
736 IsoManager::GetInstance()->CreateCig(
737 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
738
739 ON_CALL(hcic_interface_, SetCigParams)
740 .WillByDefault(
741 [&hci_mock_rsp_buffer](
742 auto, auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
743 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
744 return 0;
745 });
746 ASSERT_EXIT(IsoManager::GetInstance()->ReconfigureCig(
747 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams),
748 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
749 }
750
TEST_F(IsoManagerDeathTest,ReconfigureCigInvalidRspPacket2)751 TEST_F(IsoManagerDeathTest, ReconfigureCigInvalidRspPacket2) {
752 uint8_t hci_mock_rsp_buffer[] = {0x00, 0x00, 0x02, 0x01, 0x00};
753
754 IsoManager::GetInstance()->CreateCig(
755 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
756
757 ON_CALL(hcic_interface_, SetCigParams)
758 .WillByDefault(
759 [&hci_mock_rsp_buffer](
760 auto, auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
761 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
762 return 0;
763 });
764 ASSERT_EXIT(
765 IsoManager::GetInstance()->ReconfigureCig(
766 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams2),
767 ::testing::KilledBySignal(SIGABRT), "Invalid CIS count");
768 }
769
TEST_F(IsoManagerTest,ReconfigureCigInvalidStatus)770 TEST_F(IsoManagerTest, ReconfigureCigInvalidStatus) {
771 uint8_t rsp_cig_id = 128;
772 uint8_t rsp_status = 0x01;
773 uint8_t rsp_cis_cnt = 3;
774 uint8_t hci_mock_rsp_buffer[] = {rsp_status, rsp_cig_id, rsp_cis_cnt};
775
776 IsoManager::GetInstance()->CreateCig(rsp_cig_id, kDefaultCigParams);
777
778 // Set-up the invalid response
779 ON_CALL(hcic_interface_, SetCigParams)
780 .WillByDefault(
781 [&hci_mock_rsp_buffer](
782 auto, auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
783 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
784 return 0;
785 });
786
787 bluetooth::hci::iso_manager::cig_create_cmpl_evt evt;
788 EXPECT_CALL(
789 *cig_callbacks_,
790 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnReconfigureCmpl, _))
791 .WillOnce([&evt](uint8_t /* type */, void* data) {
792 evt = *static_cast<bluetooth::hci::iso_manager::cig_create_cmpl_evt*>(
793 data);
794 return 0;
795 });
796 IsoManager::GetInstance()->ReconfigureCig(rsp_cig_id, kDefaultCigParams2);
797
798 ASSERT_EQ(evt.cig_id, rsp_cig_id);
799 ASSERT_EQ(evt.status, rsp_status);
800 ASSERT_TRUE(evt.conn_handles.empty());
801 }
802
TEST_F(IsoManagerTest,ReconfigureCigValid)803 TEST_F(IsoManagerTest, ReconfigureCigValid) {
804 IsoManager::GetInstance()->CreateCig(
805 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
806
807 bluetooth::hci::iso_manager::cig_create_cmpl_evt evt;
808 EXPECT_CALL(
809 *cig_callbacks_,
810 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnReconfigureCmpl, _))
811 .WillOnce([&evt](uint8_t /* type */, void* data) {
812 evt = *static_cast<bluetooth::hci::iso_manager::cig_create_cmpl_evt*>(
813 data);
814 return 0;
815 });
816
817 // Verify valid reconfiguration request
818 IsoManager::GetInstance()->ReconfigureCig(
819 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams2);
820 ASSERT_EQ(evt.cig_id, volatile_test_cig_create_cmpl_evt_.cig_id);
821 ASSERT_EQ(evt.status, volatile_test_cig_create_cmpl_evt_.status);
822 ASSERT_TRUE(std::is_permutation(
823 evt.conn_handles.begin(), evt.conn_handles.end(),
824 volatile_test_cig_create_cmpl_evt_.conn_handles.begin()));
825 }
826
TEST_F(IsoManagerTest,ReconfigureCigLateArrivingCallback)827 TEST_F(IsoManagerTest, ReconfigureCigLateArrivingCallback) {
828 IsoManager::GetInstance()->CreateCig(
829 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
830
831 // Catch the callback
832 base::OnceCallback<void(uint8_t*, uint16_t)> iso_cb;
833 ON_CALL(hcic_interface_, SetCigParams)
834 .WillByDefault([&](auto /* cig_id */, auto,
835 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
836 iso_cb = std::move(cb);
837 });
838 IsoManager::GetInstance()->ReconfigureCig(
839 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams2);
840
841 // Stop the IsoManager before calling the callback
842 IsoManager::GetInstance()->Stop();
843
844 // Call the callback and expect no call
845 EXPECT_CALL(*cig_callbacks_, OnCigEvent(_, _)).Times(0);
846 ASSERT_FALSE(iso_cb.is_null());
847
848 uint8_t hci_mock_rsp_buffer[3 + sizeof(uint16_t) *
849 volatile_test_cig_create_cmpl_evt_
850 .conn_handles.size()];
851 uint8_t* p = hci_mock_rsp_buffer;
852 UINT8_TO_STREAM(p, volatile_test_cig_create_cmpl_evt_.status);
853 UINT8_TO_STREAM(p, volatile_test_cig_create_cmpl_evt_.cig_id);
854 UINT8_TO_STREAM(p, volatile_test_cig_create_cmpl_evt_.conn_handles.size());
855 for (auto handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
856 UINT16_TO_STREAM(p, handle);
857 }
858 std::move(iso_cb).Run(
859 hci_mock_rsp_buffer,
860 3 + sizeof(uint16_t) *
861 volatile_test_cig_create_cmpl_evt_.conn_handles.size());
862 }
863
TEST_F(IsoManagerTest,RemoveCigHciCall)864 TEST_F(IsoManagerTest, RemoveCigHciCall) {
865 IsoManager::GetInstance()->CreateCig(
866 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
867
868 EXPECT_CALL(hcic_interface_,
869 RemoveCig(volatile_test_cig_create_cmpl_evt_.cig_id, _))
870 .Times(1);
871 IsoManager::GetInstance()->RemoveCig(
872 volatile_test_cig_create_cmpl_evt_.cig_id);
873 }
874
TEST_F(IsoManagerDeathTest,RemoveCigWithNoSuchCig)875 TEST_F(IsoManagerDeathTest, RemoveCigWithNoSuchCig) {
876 ASSERT_EXIT(IsoManager::GetInstance()->RemoveCig(
877 volatile_test_cig_create_cmpl_evt_.cig_id),
878 ::testing::KilledBySignal(SIGABRT), "No such cig");
879 }
880
TEST_F(IsoManagerDeathTest,RemoveCigForceNoSuchCig)881 TEST_F(IsoManagerDeathTest, RemoveCigForceNoSuchCig) {
882 EXPECT_CALL(hcic_interface_,
883 RemoveCig(volatile_test_cig_create_cmpl_evt_.cig_id, _))
884 .Times(1);
885 IsoManager::GetInstance()->RemoveCig(
886 volatile_test_cig_create_cmpl_evt_.cig_id, true);
887 }
888
TEST_F(IsoManagerDeathTest,RemoveSameCigTwice)889 TEST_F(IsoManagerDeathTest, RemoveSameCigTwice) {
890 IsoManager::GetInstance()->CreateCig(
891 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
892
893 ON_CALL(hcic_interface_, RemoveCig)
894 .WillByDefault(
895 [this](auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
896 uint8_t hci_mock_rsp_buffer[2];
897 uint8_t* p = hci_mock_rsp_buffer;
898
899 UINT8_TO_STREAM(p, HCI_SUCCESS);
900 UINT8_TO_STREAM(p, this->volatile_test_cig_create_cmpl_evt_.cig_id);
901
902 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
903 return 0;
904 });
905
906 IsoManager::GetInstance()->RemoveCig(
907 volatile_test_cig_create_cmpl_evt_.cig_id);
908
909 ASSERT_EXIT(IsoManager::GetInstance()->RemoveCig(
910 volatile_test_cig_create_cmpl_evt_.cig_id),
911 ::testing::KilledBySignal(SIGABRT), "No such cig");
912 }
913
TEST_F(IsoManagerDeathTest,RemoveCigInvalidRspPacket)914 TEST_F(IsoManagerDeathTest, RemoveCigInvalidRspPacket) {
915 IsoManager::GetInstance()->CreateCig(
916 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
917
918 ON_CALL(hcic_interface_, RemoveCig)
919 .WillByDefault([](auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
920 uint8_t hci_mock_rsp_buffer[] = {0x00}; // status byte only
921
922 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
923 return 0;
924 });
925 ASSERT_EXIT(IsoManager::GetInstance()->RemoveCig(
926 volatile_test_cig_create_cmpl_evt_.cig_id),
927 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
928 }
929
TEST_F(IsoManagerTest,RemoveCigInvalidStatus)930 TEST_F(IsoManagerTest, RemoveCigInvalidStatus) {
931 uint8_t rsp_status = 0x02;
932 uint8_t hci_mock_rsp_buffer[] = {rsp_status,
933 volatile_test_cig_create_cmpl_evt_.cig_id};
934
935 IsoManager::GetInstance()->CreateCig(
936 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
937
938 ON_CALL(hcic_interface_, RemoveCig)
939 .WillByDefault(
940 [&hci_mock_rsp_buffer](
941 auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
942 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
943 return 0;
944 });
945
946 bluetooth::hci::iso_manager::cig_remove_cmpl_evt evt;
947 ON_CALL(*cig_callbacks_,
948 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl, _))
949 .WillByDefault([&evt](uint8_t /* type */, void* data) {
950 evt = *static_cast<bluetooth::hci::iso_manager::cig_remove_cmpl_evt*>(
951 data);
952 return 0;
953 });
954
955 IsoManager::GetInstance()->RemoveCig(
956 volatile_test_cig_create_cmpl_evt_.cig_id);
957 ASSERT_EQ(evt.cig_id, volatile_test_cig_create_cmpl_evt_.cig_id);
958 ASSERT_EQ(evt.status, rsp_status);
959 }
960
TEST_F(IsoManagerTest,RemoveCigValid)961 TEST_F(IsoManagerTest, RemoveCigValid) {
962 uint8_t hci_mock_rsp_buffer[] = {HCI_SUCCESS,
963 volatile_test_cig_create_cmpl_evt_.cig_id};
964
965 ASSERT_EQ(IsIsoActive, false);
966 IsoManager::GetInstance()->CreateCig(
967 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
968 ASSERT_EQ(IsIsoActive, true);
969
970 ON_CALL(hcic_interface_, RemoveCig)
971 .WillByDefault(
972 [&hci_mock_rsp_buffer](
973 auto, base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
974 std::move(cb).Run(hci_mock_rsp_buffer, sizeof(hci_mock_rsp_buffer));
975 return 0;
976 });
977
978 bluetooth::hci::iso_manager::cig_remove_cmpl_evt evt;
979 EXPECT_CALL(
980 *cig_callbacks_,
981 OnCigEvent(bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl, _))
982 .WillOnce([&evt](uint8_t /* type */, void* data) {
983 evt = *static_cast<bluetooth::hci::iso_manager::cig_remove_cmpl_evt*>(
984 data);
985 return 0;
986 });
987
988 IsoManager::GetInstance()->RemoveCig(
989 volatile_test_cig_create_cmpl_evt_.cig_id);
990 ASSERT_EQ(evt.cig_id, volatile_test_cig_create_cmpl_evt_.cig_id);
991 ASSERT_EQ(evt.status, HCI_SUCCESS);
992 ASSERT_EQ(IsIsoActive, false);
993 }
994
TEST_F(IsoManagerTest,EstablishCisHciCall)995 TEST_F(IsoManagerTest, EstablishCisHciCall) {
996 IsoManager::GetInstance()->CreateCig(
997 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
998
999 bluetooth::hci::iso_manager::cis_establish_params params;
1000 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1001 params.conn_pairs.push_back({handle, 1});
1002 }
1003
1004 EXPECT_CALL(hcic_interface_,
1005 CreateCis(2,
1006 iso_matchers::EqPointedArray(
1007 params.conn_pairs.data(),
1008 params.conn_pairs.size() *
1009 sizeof(params.conn_pairs.data()[0])),
1010 _))
1011 .Times(1);
1012 IsoManager::GetInstance()->EstablishCis(params);
1013 }
1014
TEST_F(IsoManagerDeathTest,EstablishCisWithNoSuchCis)1015 TEST_F(IsoManagerDeathTest, EstablishCisWithNoSuchCis) {
1016 bluetooth::hci::iso_manager::cis_establish_params params;
1017 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1018 params.conn_pairs.push_back({handle, 1});
1019 }
1020
1021 ASSERT_EXIT(
1022 IsoManager::GetInstance()->IsoManager::GetInstance()->EstablishCis(
1023 params),
1024 ::testing::KilledBySignal(SIGABRT), "No such cis");
1025 }
1026
TEST_F(IsoManagerDeathTest,ConnectSameCisTwice)1027 TEST_F(IsoManagerDeathTest, ConnectSameCisTwice) {
1028 IsoManager::GetInstance()->CreateCig(
1029 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1030
1031 bluetooth::hci::iso_manager::cis_establish_params params;
1032 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1033 params.conn_pairs.push_back({handle, 1});
1034 }
1035 IsoManager::GetInstance()->EstablishCis(params);
1036
1037 ASSERT_EXIT(
1038 IsoManager::GetInstance()->IsoManager::GetInstance()->EstablishCis(
1039 params),
1040 ::testing::KilledBySignal(SIGABRT), "already connected or connecting");
1041 }
1042
TEST_F(IsoManagerDeathTest,EstablishCisInvalidResponsePacket)1043 TEST_F(IsoManagerDeathTest, EstablishCisInvalidResponsePacket) {
1044 IsoManager::GetInstance()->CreateCig(
1045 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1046
1047 ON_CALL(hcic_interface_, CreateCis)
1048 .WillByDefault(
1049 [this](uint8_t /* num_cis */, const EXT_CIS_CREATE_CFG* /* cis_cfg */,
1050 base::OnceCallback<void(uint8_t*, uint16_t)> /* cb */) {
1051 for (auto& handle :
1052 volatile_test_cig_create_cmpl_evt_.conn_handles) {
1053 std::vector<uint8_t> buf(27);
1054 uint8_t* p = buf.data();
1055 UINT8_TO_STREAM(p, HCI_SUCCESS);
1056 UINT16_TO_STREAM(p, handle);
1057 UINT24_TO_STREAM(p, 0xEA); // CIG sync delay
1058 UINT24_TO_STREAM(p, 0xEB); // CIS sync delay
1059 UINT24_TO_STREAM(p, 0xEC); // transport latency mtos
1060 UINT24_TO_STREAM(p, 0xED); // transport latency stom
1061 UINT8_TO_STREAM(p, 0x01); // phy mtos
1062 UINT8_TO_STREAM(p, 0x02); // phy stom
1063 UINT8_TO_STREAM(p, 0x01); // nse
1064 UINT8_TO_STREAM(p, 0x02); // bn mtos
1065 UINT8_TO_STREAM(p, 0x03); // bn stom
1066 UINT8_TO_STREAM(p, 0x04); // ft mtos
1067 UINT8_TO_STREAM(p, 0x05); // ft stom
1068 UINT16_TO_STREAM(p, 0x00FA); // Max PDU mtos
1069 UINT16_TO_STREAM(p, 0x00FB); // Max PDU stom
1070
1071 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_CIS_EST_EVT,
1072 buf.data(), buf.size());
1073 }
1074 });
1075
1076 bluetooth::hci::iso_manager::cis_establish_params params;
1077 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1078 params.conn_pairs.push_back({handle, 1});
1079 }
1080
1081 ASSERT_EXIT(
1082 IsoManager::GetInstance()->IsoManager::GetInstance()->EstablishCis(
1083 params),
1084 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
1085 }
1086
TEST_F(IsoManagerTest,EstablishCisInvalidCommandStatus)1087 TEST_F(IsoManagerTest, EstablishCisInvalidCommandStatus) {
1088 IsoManager::GetInstance()->CreateCig(
1089 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1090 uint16_t invalid_status = 0x0001;
1091
1092 ON_CALL(hcic_interface_, CreateCis)
1093 .WillByDefault([invalid_status](
1094 uint8_t /* num_cis */,
1095 const EXT_CIS_CREATE_CFG* /* cis_cfg */,
1096 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
1097 std::move(cb).Run((uint8_t*)&invalid_status, sizeof(invalid_status));
1098 return 0;
1099 });
1100
1101 EXPECT_CALL(
1102 *cig_callbacks_,
1103 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl, _))
1104 .Times(kDefaultCigParams.cis_cfgs.size())
1105 .WillRepeatedly([this, invalid_status](uint8_t /* type */, void* data) {
1106 bluetooth::hci::iso_manager::cis_establish_cmpl_evt* evt =
1107 static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(
1108 data);
1109
1110 ASSERT_EQ(evt->status, invalid_status);
1111 ASSERT_TRUE(
1112 std::find(volatile_test_cig_create_cmpl_evt_.conn_handles.begin(),
1113 volatile_test_cig_create_cmpl_evt_.conn_handles.end(),
1114 evt->cis_conn_hdl) !=
1115 volatile_test_cig_create_cmpl_evt_.conn_handles.end());
1116 });
1117
1118 // Establish all CISes
1119 bluetooth::hci::iso_manager::cis_establish_params params;
1120 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1121 params.conn_pairs.push_back({handle, 1});
1122 }
1123 IsoManager::GetInstance()->EstablishCis(params);
1124 }
1125
TEST_F(IsoManagerTest,EstablishCisInvalidStatus)1126 TEST_F(IsoManagerTest, EstablishCisInvalidStatus) {
1127 uint8_t cig_id = volatile_test_cig_create_cmpl_evt_.cig_id;
1128 IsoManager::GetInstance()->CreateCig(cig_id, kDefaultCigParams);
1129 uint8_t invalid_status = 0x01;
1130
1131 ON_CALL(hcic_interface_, CreateCis)
1132 .WillByDefault(
1133 [this, invalid_status](
1134 uint8_t /* num_cis */, const EXT_CIS_CREATE_CFG* /* cis_cfg */,
1135 base::OnceCallback<void(uint8_t*, uint16_t)> /* cb */) {
1136 for (auto& handle :
1137 volatile_test_cig_create_cmpl_evt_.conn_handles) {
1138 std::vector<uint8_t> buf(28);
1139 uint8_t* p = buf.data();
1140 UINT8_TO_STREAM(p, invalid_status);
1141 UINT16_TO_STREAM(p, handle);
1142 UINT24_TO_STREAM(p, 0xEA); // CIG sync delay
1143 UINT24_TO_STREAM(p, 0xEB); // CIS sync delay
1144 UINT24_TO_STREAM(p, 0xEC); // transport latency mtos
1145 UINT24_TO_STREAM(p, 0xED); // transport latency stom
1146 UINT8_TO_STREAM(p, 0x01); // phy mtos
1147 UINT8_TO_STREAM(p, 0x02); // phy stom
1148 UINT8_TO_STREAM(p, 0x01); // nse
1149 UINT8_TO_STREAM(p, 0x02); // bn mtos
1150 UINT8_TO_STREAM(p, 0x03); // bn stom
1151 UINT8_TO_STREAM(p, 0x04); // ft mtos
1152 UINT8_TO_STREAM(p, 0x05); // ft stom
1153 UINT16_TO_STREAM(p, 0x00FA); // Max PDU mtos
1154 UINT16_TO_STREAM(p, 0x00FB); // Max PDU stom
1155 UINT16_TO_STREAM(p, 0x0C60); // ISO interval
1156
1157 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_CIS_EST_EVT,
1158 buf.data(), buf.size());
1159 }
1160 });
1161
1162 EXPECT_CALL(
1163 *cig_callbacks_,
1164 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl, _))
1165 .Times(kDefaultCigParams.cis_cfgs.size())
1166 .WillRepeatedly([this, invalid_status, cig_id](uint8_t /* type */,
1167 void* data) {
1168 bluetooth::hci::iso_manager::cis_establish_cmpl_evt* evt =
1169 static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(
1170 data);
1171
1172 ASSERT_EQ(evt->status, invalid_status);
1173 ASSERT_EQ(evt->cig_id, cig_id);
1174 ASSERT_TRUE(
1175 std::find(volatile_test_cig_create_cmpl_evt_.conn_handles.begin(),
1176 volatile_test_cig_create_cmpl_evt_.conn_handles.end(),
1177 evt->cis_conn_hdl) !=
1178 volatile_test_cig_create_cmpl_evt_.conn_handles.end());
1179 });
1180
1181 // Establish all CISes before setting up their data paths
1182 bluetooth::hci::iso_manager::cis_establish_params params;
1183 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1184 params.conn_pairs.push_back({handle, 1});
1185 }
1186 IsoManager::GetInstance()->EstablishCis(params);
1187 }
1188
TEST_F(IsoManagerTest,EstablishCisValid)1189 TEST_F(IsoManagerTest, EstablishCisValid) {
1190 IsoManager::GetInstance()->CreateCig(
1191 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1192
1193 EXPECT_CALL(
1194 *cig_callbacks_,
1195 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl, _))
1196 .Times(kDefaultCigParams.cis_cfgs.size())
1197 .WillRepeatedly([this](uint8_t /* type */, void* data) {
1198 bluetooth::hci::iso_manager::cis_establish_cmpl_evt* evt =
1199 static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(
1200 data);
1201
1202 ASSERT_EQ(evt->status, HCI_SUCCESS);
1203 ASSERT_TRUE(
1204 std::find(volatile_test_cig_create_cmpl_evt_.conn_handles.begin(),
1205 volatile_test_cig_create_cmpl_evt_.conn_handles.end(),
1206 evt->cis_conn_hdl) !=
1207 volatile_test_cig_create_cmpl_evt_.conn_handles.end());
1208 });
1209
1210 // Establish all CISes before setting up their data paths
1211 bluetooth::hci::iso_manager::cis_establish_params params;
1212 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1213 params.conn_pairs.push_back({handle, 1});
1214 }
1215 IsoManager::GetInstance()->EstablishCis(params);
1216 }
1217
TEST_F(IsoManagerTest,EstablishCisLateArrivingCallback)1218 TEST_F(IsoManagerTest, EstablishCisLateArrivingCallback) {
1219 IsoManager::GetInstance()->CreateCig(
1220 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1221
1222 // Catch the callback
1223 base::OnceCallback<void(uint8_t*, uint16_t)> iso_cb;
1224 EXT_CIS_CREATE_CFG cis_create_cfg;
1225 uint8_t cis_num = 0;
1226 ON_CALL(hcic_interface_, CreateCis)
1227 .WillByDefault([&](uint8_t num_cis, const EXT_CIS_CREATE_CFG* cis_cfg,
1228 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
1229 cis_create_cfg = *cis_cfg;
1230 cis_num = num_cis;
1231 iso_cb = std::move(cb);
1232 });
1233
1234 // Establish all CISes before setting up their data paths
1235 bluetooth::hci::iso_manager::cis_establish_params params;
1236 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1237 params.conn_pairs.push_back({handle, 1});
1238 }
1239 IsoManager::GetInstance()->EstablishCis(params);
1240
1241 // Stop the IsoManager before calling the callback
1242 IsoManager::GetInstance()->Stop();
1243
1244 // Call the callback and expect no call
1245 EXPECT_CALL(
1246 *cig_callbacks_,
1247 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl, _))
1248 .Times(0);
1249 ASSERT_FALSE(iso_cb.is_null());
1250
1251 // Command complete with error will trigger the callback without
1252 // injecting any additional HCI events
1253 std::vector<uint8_t> buf(1);
1254 uint8_t* p = buf.data();
1255 UINT8_TO_STREAM(p, 0x01); // status
1256 std::move(iso_cb).Run(buf.data(), buf.size());
1257 }
1258
TEST_F(IsoManagerTest,ReconnectCisValid)1259 TEST_F(IsoManagerTest, ReconnectCisValid) {
1260 IsoManager::GetInstance()->CreateCig(
1261 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1262
1263 // Establish all CISes before setting up their data paths
1264 bluetooth::hci::iso_manager::cis_establish_params params;
1265 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1266 params.conn_pairs.push_back({handle, 1});
1267 }
1268 IsoManager::GetInstance()->EstablishCis(params);
1269
1270 // trigger HCI disconnection event
1271 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1272 IsoManager::GetInstance()->HandleDisconnect(handle, 0x16);
1273 }
1274
1275 EXPECT_CALL(
1276 *cig_callbacks_,
1277 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl, _))
1278 .Times(kDefaultCigParams.cis_cfgs.size())
1279 .WillRepeatedly([this](uint8_t /* type */, void* data) {
1280 bluetooth::hci::iso_manager::cis_establish_cmpl_evt* evt =
1281 static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(
1282 data);
1283
1284 ASSERT_EQ(evt->status, HCI_SUCCESS);
1285 ASSERT_TRUE(
1286 std::find(volatile_test_cig_create_cmpl_evt_.conn_handles.begin(),
1287 volatile_test_cig_create_cmpl_evt_.conn_handles.end(),
1288 evt->cis_conn_hdl) !=
1289 volatile_test_cig_create_cmpl_evt_.conn_handles.end());
1290 });
1291 IsoManager::GetInstance()->EstablishCis(params);
1292 }
1293
TEST_F(IsoManagerTest,DisconnectCisHciCall)1294 TEST_F(IsoManagerTest, DisconnectCisHciCall) {
1295 IsoManager::GetInstance()->CreateCig(
1296 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1297
1298 // Establish all CISes before setting up their data paths
1299 bluetooth::hci::iso_manager::cis_establish_params params;
1300 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1301 params.conn_pairs.push_back({handle, 1});
1302 }
1303 IsoManager::GetInstance()->EstablishCis(params);
1304
1305 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1306 EXPECT_CALL(hcic_interface_, Disconnect(handle, 0x16))
1307 .Times(1)
1308 .RetiresOnSaturation();
1309 IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(handle,
1310 0x16);
1311 }
1312 }
1313
TEST_F(IsoManagerDeathTest,DisconnectCisWithNoSuchCis)1314 TEST_F(IsoManagerDeathTest, DisconnectCisWithNoSuchCis) {
1315 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1316 ASSERT_EXIT(
1317 IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(
1318 handle, 0x16),
1319 ::testing::KilledBySignal(SIGABRT), "No such cis");
1320 }
1321 }
1322
TEST_F(IsoManagerDeathTest,DisconnectSameCisTwice)1323 TEST_F(IsoManagerDeathTest, DisconnectSameCisTwice) {
1324 IsoManager::GetInstance()->CreateCig(
1325 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1326
1327 // Establish all CISes before setting up their data paths
1328 bluetooth::hci::iso_manager::cis_establish_params params;
1329 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1330 params.conn_pairs.push_back({handle, 1});
1331 }
1332 IsoManager::GetInstance()->EstablishCis(params);
1333
1334 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1335 IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(handle,
1336 0x16);
1337 }
1338
1339 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1340 ASSERT_EXIT(
1341 IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(
1342 handle, 0x16),
1343 ::testing::KilledBySignal(SIGABRT), "Not connected");
1344 }
1345 }
1346
TEST_F(IsoManagerTest,DisconnectCisValid)1347 TEST_F(IsoManagerTest, DisconnectCisValid) {
1348 IsoManager::GetInstance()->CreateCig(
1349 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1350
1351 // Establish all CISes before setting up their data paths
1352 bluetooth::hci::iso_manager::cis_establish_params params;
1353 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1354 params.conn_pairs.push_back({handle, 1});
1355 }
1356 IsoManager::GetInstance()->EstablishCis(params);
1357
1358 uint8_t disconnect_reason = 0x16;
1359 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1360 EXPECT_CALL(*cig_callbacks_, OnCisEvent)
1361 .WillOnce([this, handle, disconnect_reason](uint8_t event_code,
1362 void* data) {
1363 ASSERT_EQ(event_code,
1364 bluetooth::hci::iso_manager::kIsoEventCisDisconnected);
1365 auto* event =
1366 static_cast<bluetooth::hci::iso_manager::cis_disconnected_evt*>(
1367 data);
1368 ASSERT_EQ(event->reason, disconnect_reason);
1369 ASSERT_EQ(event->cig_id, volatile_test_cig_create_cmpl_evt_.cig_id);
1370 ASSERT_EQ(event->cis_conn_hdl, handle);
1371 })
1372 .RetiresOnSaturation();
1373 IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(
1374 handle, disconnect_reason);
1375 }
1376 }
1377
1378 // Check if we properly ignore not ISO related disconnect events
TEST_F(IsoManagerDeathTest,DisconnectCisInvalidResponse)1379 TEST_F(IsoManagerDeathTest, DisconnectCisInvalidResponse) {
1380 IsoManager::GetInstance()->CreateCig(
1381 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1382
1383 bluetooth::hci::iso_manager::cis_establish_params params;
1384 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1385 params.conn_pairs.push_back({handle, 1});
1386 }
1387 IsoManager::GetInstance()->EstablishCis(params);
1388
1389 // Make the HCI layer send invalid handles in disconnect event
1390 ON_CALL(hcic_interface_, Disconnect)
1391 .WillByDefault([](uint16_t handle, uint8_t reason) {
1392 IsoManager::GetInstance()->HandleDisconnect(handle + 1, reason);
1393 });
1394
1395 // We don't expect any calls as these are not ISO handles
1396 ON_CALL(*cig_callbacks_,
1397 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDisconnected, _))
1398 .WillByDefault(
1399 [](uint8_t /* event_code */, void* /* data */) { FAIL(); });
1400
1401 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1402 IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(handle,
1403 0x16);
1404 }
1405 }
1406
TEST_F(IsoManagerTest,CreateBigHciCall)1407 TEST_F(IsoManagerTest, CreateBigHciCall) {
1408 for (uint8_t i = 220; i != 60; ++i) {
1409 EXPECT_CALL(hcic_interface_,
1410 CreateBig(i, iso_matchers::Eq(kDefaultBigParams)))
1411 .Times(1)
1412 .RetiresOnSaturation();
1413 IsoManager::GetInstance()->CreateBig(i, kDefaultBigParams);
1414 }
1415 }
1416
TEST_F(IsoManagerTest,CreateBigValid)1417 TEST_F(IsoManagerTest, CreateBigValid) {
1418 bluetooth::hci::iso_manager::big_create_cmpl_evt evt;
1419 evt.status = 0x01;
1420 EXPECT_CALL(
1421 *big_callbacks_,
1422 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnCreateCmpl, _))
1423 .WillOnce([&evt](uint8_t /* type */, void* data) {
1424 evt = *static_cast<bluetooth::hci::iso_manager::big_create_cmpl_evt*>(
1425 data);
1426 return 0;
1427 });
1428
1429 IsoManager::GetInstance()->CreateBig(0x01, kDefaultBigParams);
1430 ASSERT_EQ(evt.status, HCI_SUCCESS);
1431 }
1432
TEST_F(IsoManagerDeathTest,CreateBigInvalidResponsePacket)1433 TEST_F(IsoManagerDeathTest, CreateBigInvalidResponsePacket) {
1434 ON_CALL(hcic_interface_, CreateBig)
1435 .WillByDefault(
1436 [](auto big_handle,
1437 bluetooth::hci::iso_manager::big_create_params big_params) {
1438 std::vector<uint8_t> buf(18);
1439 uint8_t* p = buf.data();
1440 UINT8_TO_STREAM(p, 0x00);
1441 UINT8_TO_STREAM(p, big_handle);
1442
1443 UINT24_TO_STREAM(p, 0x0080de); // big_sync_delay
1444 UINT24_TO_STREAM(p, 0x00cefe); // transport_latency_big
1445 UINT8_TO_STREAM(p, big_params.phy); // phy
1446 UINT8_TO_STREAM(p, 4); // nse
1447 UINT8_TO_STREAM(p, 1); // bn
1448 UINT8_TO_STREAM(p, 0); // pto
1449 UINT8_TO_STREAM(p, 4); // irc
1450 UINT16_TO_STREAM(p, 108); // max_pdu
1451 UINT16_TO_STREAM(p, 6); // iso_interval
1452 UINT8_TO_STREAM(p, 0); // num BISes
1453
1454 IsoManager::GetInstance()->HandleHciEvent(
1455 HCI_BLE_CREATE_BIG_CPL_EVT, buf.data(), buf.size());
1456 });
1457
1458 ASSERT_EXIT(IsoManager::GetInstance()->CreateBig(0x01, kDefaultBigParams),
1459 ::testing::KilledBySignal(SIGABRT), "Bis count is 0");
1460 }
1461
TEST_F(IsoManagerDeathTest,CreateBigInvalidResponsePacket2)1462 TEST_F(IsoManagerDeathTest, CreateBigInvalidResponsePacket2) {
1463 ON_CALL(hcic_interface_, CreateBig)
1464 .WillByDefault(
1465 [](auto big_handle,
1466 bluetooth::hci::iso_manager::big_create_params big_params) {
1467 std::vector<uint8_t> buf(18);
1468 uint8_t* p = buf.data();
1469 UINT8_TO_STREAM(p, 0x00);
1470 UINT8_TO_STREAM(p, big_handle);
1471
1472 UINT24_TO_STREAM(p, 0x0080de); // big_sync_delay
1473 UINT24_TO_STREAM(p, 0x00cefe); // transport_latency_big
1474 UINT8_TO_STREAM(p, big_params.phy); // phy
1475 UINT8_TO_STREAM(p, 4); // nse
1476 UINT8_TO_STREAM(p, 1); // bn
1477 UINT8_TO_STREAM(p, 0); // pto
1478 UINT8_TO_STREAM(p, 4); // irc
1479 UINT16_TO_STREAM(p, 108); // max_pdu
1480 UINT16_TO_STREAM(p, 6); // iso_interval
1481 UINT8_TO_STREAM(p, big_params.num_bis);
1482
1483 IsoManager::GetInstance()->HandleHciEvent(
1484 HCI_BLE_CREATE_BIG_CPL_EVT, buf.data(), buf.size());
1485 });
1486
1487 ASSERT_EXIT(IsoManager::GetInstance()->CreateBig(0x01, kDefaultBigParams),
1488 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
1489 }
1490
TEST_F(IsoManagerTest,CreateBigInvalidStatus)1491 TEST_F(IsoManagerTest, CreateBigInvalidStatus) {
1492 bluetooth::hci::iso_manager::big_create_cmpl_evt evt;
1493 evt.status = 0x00;
1494 EXPECT_CALL(
1495 *big_callbacks_,
1496 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnCreateCmpl, _))
1497 .WillOnce([&evt](uint8_t /* type */, void* data) {
1498 evt = *static_cast<bluetooth::hci::iso_manager::big_create_cmpl_evt*>(
1499 data);
1500 return 0;
1501 });
1502
1503 ON_CALL(hcic_interface_, CreateBig)
1504 .WillByDefault(
1505 [](auto big_handle,
1506 bluetooth::hci::iso_manager::big_create_params big_params) {
1507 std::vector<uint8_t> buf(big_params.num_bis * sizeof(uint16_t) +
1508 18);
1509 uint8_t* p = buf.data();
1510 UINT8_TO_STREAM(p, 0x01);
1511 UINT8_TO_STREAM(p, big_handle);
1512
1513 UINT24_TO_STREAM(p, 0x0080de); // big_sync_delay
1514 UINT24_TO_STREAM(p, 0x00cefe); // transport_latency_big
1515 UINT8_TO_STREAM(p, big_params.phy); // phy
1516 UINT8_TO_STREAM(p, 4); // nse
1517 UINT8_TO_STREAM(p, 1); // bn
1518 UINT8_TO_STREAM(p, 0); // pto
1519 UINT8_TO_STREAM(p, 4); // irc
1520 UINT16_TO_STREAM(p, 108); // max_pdu
1521 UINT16_TO_STREAM(p, 6); // iso_interval
1522
1523 UINT8_TO_STREAM(p, big_params.num_bis);
1524 static uint8_t conn_hdl = 0x01;
1525 for (auto i = 0; i < big_params.num_bis; ++i) {
1526 UINT16_TO_STREAM(p, conn_hdl++);
1527 }
1528
1529 IsoManager::GetInstance()->HandleHciEvent(
1530 HCI_BLE_CREATE_BIG_CPL_EVT, buf.data(), buf.size());
1531 });
1532
1533 IsoManager::GetInstance()->CreateBig(0x01, kDefaultBigParams);
1534 ASSERT_EQ(evt.status, 0x01);
1535 ASSERT_EQ(evt.big_id, 0x01);
1536 ASSERT_EQ(evt.conn_handles.size(), kDefaultBigParams.num_bis);
1537 }
1538
TEST_F(IsoManagerDeathTest,CreateSameBigTwice)1539 TEST_F(IsoManagerDeathTest, CreateSameBigTwice) {
1540 bluetooth::hci::iso_manager::big_create_cmpl_evt evt;
1541 evt.status = 0x01;
1542 EXPECT_CALL(
1543 *big_callbacks_,
1544 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnCreateCmpl, _))
1545 .WillOnce([&evt](uint8_t /* type */, void* data) {
1546 evt = *static_cast<bluetooth::hci::iso_manager::big_create_cmpl_evt*>(
1547 data);
1548 return 0;
1549 });
1550
1551 IsoManager::GetInstance()->CreateBig(0x01, kDefaultBigParams);
1552 ASSERT_EQ(evt.status, HCI_SUCCESS);
1553 ASSERT_EQ(evt.big_id, 0x01);
1554 ASSERT_EQ(evt.conn_handles.size(), kDefaultBigParams.num_bis);
1555 }
1556
TEST_F(IsoManagerTest,TerminateBigHciCall)1557 TEST_F(IsoManagerTest, TerminateBigHciCall) {
1558 const uint8_t big_id = 0x22;
1559 const uint8_t reason = 0x16; // Terminated by local host
1560
1561 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1562 EXPECT_CALL(hcic_interface_, TerminateBig(big_id, reason)).Times(1);
1563 IsoManager::GetInstance()->TerminateBig(big_id, reason);
1564 }
1565
TEST_F(IsoManagerDeathTest,TerminateSameBigTwice)1566 TEST_F(IsoManagerDeathTest, TerminateSameBigTwice) {
1567 const uint8_t big_id = 0x22;
1568 const uint8_t reason = 0x16; // Terminated by local host
1569
1570 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1571 EXPECT_CALL(
1572 *big_callbacks_,
1573 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnTerminateCmpl, _));
1574
1575 IsoManager::GetInstance()->TerminateBig(big_id, reason);
1576 ASSERT_EXIT(IsoManager::GetInstance()->TerminateBig(big_id, reason),
1577 ::testing::KilledBySignal(SIGABRT), "No such big");
1578 }
1579
TEST_F(IsoManagerDeathTest,TerminateBigNoSuchBig)1580 TEST_F(IsoManagerDeathTest, TerminateBigNoSuchBig) {
1581 const uint8_t big_id = 0x01;
1582 const uint8_t reason = 0x16; // Terminated by local host
1583
1584 EXPECT_CALL(
1585 *big_callbacks_,
1586 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnCreateCmpl, _));
1587 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1588
1589 ASSERT_EXIT(IsoManager::GetInstance()->TerminateBig(big_id + 1, reason),
1590 ::testing::KilledBySignal(SIGABRT), "No such big");
1591 }
1592
TEST_F(IsoManagerDeathTest,TerminateBigInvalidResponsePacket)1593 TEST_F(IsoManagerDeathTest, TerminateBigInvalidResponsePacket) {
1594 ON_CALL(hcic_interface_, TerminateBig)
1595 .WillByDefault([](auto /* big_handle */, uint8_t reason) {
1596 std::vector<uint8_t> buf(1);
1597 uint8_t* p = buf.data();
1598 UINT8_TO_STREAM(p, reason);
1599
1600 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
1601 buf.data(), buf.size());
1602 });
1603
1604 const uint8_t big_id = 0x22;
1605 const uint8_t reason = 0x16; // Terminated by local host
1606
1607 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1608 ASSERT_EXIT(IsoManager::GetInstance()->TerminateBig(big_id, reason),
1609 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
1610 }
1611
TEST_F(IsoManagerDeathTest,TerminateBigInvalidResponsePacket2)1612 TEST_F(IsoManagerDeathTest, TerminateBigInvalidResponsePacket2) {
1613 const uint8_t big_id = 0x22;
1614 const uint8_t reason = 0x16; // Terminated by local host
1615
1616 ON_CALL(hcic_interface_, TerminateBig)
1617 .WillByDefault([](auto /* big_handle */, uint8_t reason) {
1618 std::vector<uint8_t> buf(3);
1619 uint8_t* p = buf.data();
1620 UINT8_TO_STREAM(p, reason);
1621
1622 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
1623 buf.data(), buf.size());
1624 });
1625
1626 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1627 ASSERT_EXIT(IsoManager::GetInstance()->TerminateBig(big_id, reason),
1628 ::testing::KilledBySignal(SIGABRT), "Invalid packet length");
1629 }
1630
TEST_F(IsoManagerTest,TerminateBigInvalidResponseBigId)1631 TEST_F(IsoManagerTest, TerminateBigInvalidResponseBigId) {
1632 const uint8_t big_id = 0x22;
1633 const uint8_t reason = 0x16; // Terminated by local host
1634
1635 ON_CALL(hcic_interface_, TerminateBig)
1636 .WillByDefault([](auto big_handle, uint8_t reason) {
1637 std::vector<uint8_t> buf(2);
1638 uint8_t* p = buf.data();
1639 UINT8_TO_STREAM(p, reason);
1640 UINT8_TO_STREAM(p, big_handle + 1);
1641
1642 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
1643 buf.data(), buf.size());
1644 });
1645
1646 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1647 ASSERT_EXIT(IsoManager::GetInstance()->TerminateBig(big_id, reason),
1648 ::testing::KilledBySignal(SIGABRT), "No such big");
1649 }
1650
TEST_F(IsoManagerTest,TerminateBigValid)1651 TEST_F(IsoManagerTest, TerminateBigValid) {
1652 const uint8_t big_id = 0x22;
1653 const uint8_t reason = 0x16; // Terminated by local host
1654 bluetooth::hci::iso_manager::big_terminate_cmpl_evt evt;
1655 ASSERT_EQ(IsIsoActive, false);
1656
1657 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
1658 ASSERT_EQ(IsIsoActive, true);
1659
1660 EXPECT_CALL(
1661 *big_callbacks_,
1662 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnTerminateCmpl, _))
1663 .WillOnce([&evt](uint8_t /* type */, void* data) {
1664 evt =
1665 *static_cast<bluetooth::hci::iso_manager::big_terminate_cmpl_evt*>(
1666 data);
1667 return 0;
1668 });
1669
1670 IsoManager::GetInstance()->TerminateBig(big_id, reason);
1671 ASSERT_EQ(evt.big_id, big_id);
1672 ASSERT_EQ(evt.reason, reason);
1673 ASSERT_EQ(IsIsoActive, false);
1674 }
1675
TEST_F(IsoManagerTest,SetupIsoDataPathValid)1676 TEST_F(IsoManagerTest, SetupIsoDataPathValid) {
1677 IsoManager::GetInstance()->CreateCig(
1678 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1679 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1680 kDefaultBigParams);
1681
1682 // Establish all CISes before setting up their data paths
1683 bluetooth::hci::iso_manager::cis_establish_params params;
1684 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1685 params.conn_pairs.push_back({handle, 1});
1686 }
1687 IsoManager::GetInstance()->EstablishCis(params);
1688
1689 bluetooth::hci::iso_manager::iso_data_path_params path_params =
1690 kDefaultIsoDataPathParams;
1691
1692 // Setup data paths for all CISes
1693 path_params.data_path_dir =
1694 bluetooth::hci::iso_manager::kIsoDataPathDirectionIn;
1695 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1696 EXPECT_CALL(*cig_callbacks_,
1697 OnSetupIsoDataPath(HCI_SUCCESS, handle,
1698 volatile_test_cig_create_cmpl_evt_.cig_id))
1699 .Times(1)
1700 .RetiresOnSaturation();
1701
1702 path_params.data_path_dir =
1703 (bluetooth::hci::iso_manager::kIsoDataPathDirectionIn + handle) % 2;
1704
1705 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1706 }
1707
1708 // Setup data paths for all BISes
1709 path_params.data_path_dir =
1710 bluetooth::hci::iso_manager::kIsoDataPathDirectionOut;
1711 for (auto& handle : volatile_test_big_params_evt_.conn_handles) {
1712 std::cerr << "setting up BIS data path on conn_hdl: " << int{handle};
1713 EXPECT_CALL(*big_callbacks_,
1714 OnSetupIsoDataPath(HCI_SUCCESS, handle,
1715 volatile_test_big_params_evt_.big_id))
1716 .Times(1)
1717 .RetiresOnSaturation();
1718
1719 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1720 }
1721 }
1722
TEST_F(IsoManagerTest,SetupIsoDataPathTwice)1723 TEST_F(IsoManagerTest, SetupIsoDataPathTwice) {
1724 IsoManager::GetInstance()->CreateCig(
1725 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1726
1727 // Establish CISes
1728 bluetooth::hci::iso_manager::cis_establish_params params;
1729 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1730 params.conn_pairs.push_back({handle, 1});
1731 }
1732 IsoManager::GetInstance()->EstablishCis(params);
1733
1734 // Setup data paths for all CISes twice
1735 bluetooth::hci::iso_manager::iso_data_path_params path_params =
1736 kDefaultIsoDataPathParams;
1737 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1738 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1739 // Should be possible to reconfigure
1740 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1741 }
1742
1743 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1744 kDefaultBigParams);
1745 // Setup data paths for all BISes twice
1746 for (auto& handle : volatile_test_big_params_evt_.conn_handles) {
1747 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1748 // Should be possible to reconfigure
1749 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1750 }
1751 }
1752
TEST_F(IsoManagerTest,SetupIsoDataPathInvalidStatus)1753 TEST_F(IsoManagerTest, SetupIsoDataPathInvalidStatus) {
1754 IsoManager::GetInstance()->CreateCig(
1755 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1756 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1757 kDefaultBigParams);
1758
1759 // Establish all CISes before setting up their data paths
1760 bluetooth::hci::iso_manager::cis_establish_params params;
1761 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1762 params.conn_pairs.push_back({handle, 1});
1763 }
1764 IsoManager::GetInstance()->EstablishCis(params);
1765
1766 bluetooth::hci::iso_manager::iso_data_path_params path_params =
1767 kDefaultIsoDataPathParams;
1768
1769 uint8_t setup_datapath_rsp_status = HCI_SUCCESS;
1770 ON_CALL(hcic_interface_, SetupIsoDataPath)
1771 .WillByDefault([&setup_datapath_rsp_status](
1772 uint16_t iso_handle, uint8_t, uint8_t, uint8_t,
1773 uint16_t, uint16_t, uint32_t, std::vector<uint8_t>,
1774 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
1775 std::vector<uint8_t> buf(3);
1776 uint8_t* p = buf.data();
1777 UINT8_TO_STREAM(p, setup_datapath_rsp_status);
1778 UINT16_TO_STREAM(p, iso_handle);
1779
1780 std::move(cb).Run(buf.data(), buf.size());
1781 });
1782
1783 // Try to setup data paths for all CISes
1784 path_params.data_path_dir =
1785 bluetooth::hci::iso_manager::kIsoDataPathDirectionIn;
1786 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1787 // Mock the response with status != HCI_SUCCESS
1788 EXPECT_CALL(*cig_callbacks_,
1789 OnSetupIsoDataPath(0x11, handle,
1790 volatile_test_cig_create_cmpl_evt_.cig_id))
1791 .Times(1)
1792 .RetiresOnSaturation();
1793 setup_datapath_rsp_status = 0x11;
1794 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1795
1796 // It should be possible to retry on the same handle after the first
1797 // failure
1798 EXPECT_CALL(*cig_callbacks_,
1799 OnSetupIsoDataPath(HCI_SUCCESS, handle,
1800 volatile_test_cig_create_cmpl_evt_.cig_id))
1801 .Times(1)
1802 .RetiresOnSaturation();
1803 setup_datapath_rsp_status = HCI_SUCCESS;
1804 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1805 }
1806
1807 // Try to setup data paths for all BISes
1808 path_params.data_path_dir =
1809 bluetooth::hci::iso_manager::kIsoDataPathDirectionOut;
1810 for (auto& handle : volatile_test_big_params_evt_.conn_handles) {
1811 EXPECT_CALL(
1812 *big_callbacks_,
1813 OnSetupIsoDataPath(0x11, handle, volatile_test_big_params_evt_.big_id))
1814 .Times(1)
1815 .RetiresOnSaturation();
1816 setup_datapath_rsp_status = 0x11;
1817 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1818
1819 EXPECT_CALL(*big_callbacks_,
1820 OnSetupIsoDataPath(HCI_SUCCESS, handle,
1821 volatile_test_big_params_evt_.big_id))
1822 .Times(1)
1823 .RetiresOnSaturation();
1824 setup_datapath_rsp_status = HCI_SUCCESS;
1825 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1826 }
1827 }
1828
TEST_F(IsoManagerTest,SetupIsoDataPathLateArrivingCallback)1829 TEST_F(IsoManagerTest, SetupIsoDataPathLateArrivingCallback) {
1830 IsoManager::GetInstance()->CreateCig(
1831 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1832 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1833 kDefaultBigParams);
1834
1835 // Establish all CISes before setting up their data paths
1836 bluetooth::hci::iso_manager::cis_establish_params params;
1837 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1838 params.conn_pairs.push_back({handle, 1});
1839 }
1840 IsoManager::GetInstance()->EstablishCis(params);
1841
1842 bluetooth::hci::iso_manager::iso_data_path_params path_params =
1843 kDefaultIsoDataPathParams;
1844
1845 // Catch the callback
1846 base::OnceCallback<void(uint8_t*, uint16_t)> iso_cb;
1847 ON_CALL(hcic_interface_, SetupIsoDataPath)
1848 .WillByDefault(
1849 [&iso_cb](uint16_t /* iso_handle */, uint8_t /* data_path_dir */,
1850 uint8_t /* data_path_id */, uint8_t /* codec_id_format */,
1851 uint16_t /* codec_id_company */,
1852 uint16_t /* codec_id_vendor */,
1853 uint32_t /* controller_delay */,
1854 std::vector<uint8_t> /* codec_conf */,
1855 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
1856 iso_cb = std::move(cb);
1857 });
1858 // Setup and remove data paths for all CISes
1859 path_params.data_path_dir =
1860 bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput;
1861 auto& handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
1862 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1863
1864 // Stop the IsoManager before calling the callback
1865 IsoManager::GetInstance()->Stop();
1866
1867 // Call the callback and expect no call
1868 EXPECT_CALL(*cig_callbacks_, OnSetupIsoDataPath(_, handle, _)).Times(0);
1869 ASSERT_FALSE(iso_cb.is_null());
1870
1871 std::vector<uint8_t> buf(3);
1872 uint8_t* p = buf.data();
1873 UINT8_TO_STREAM(p, HCI_SUCCESS);
1874 UINT16_TO_STREAM(p, handle);
1875 std::move(iso_cb).Run(buf.data(), buf.size());
1876 }
1877
TEST_F(IsoManagerTest,RemoveIsoDataPathValid)1878 TEST_F(IsoManagerTest, RemoveIsoDataPathValid) {
1879 IsoManager::GetInstance()->CreateCig(
1880 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1881 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1882 kDefaultBigParams);
1883
1884 // Establish all CISes before setting up their data paths
1885 bluetooth::hci::iso_manager::cis_establish_params params;
1886 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1887 params.conn_pairs.push_back({handle, 1});
1888 }
1889 IsoManager::GetInstance()->EstablishCis(params);
1890
1891 bluetooth::hci::iso_manager::iso_data_path_params path_params =
1892 kDefaultIsoDataPathParams;
1893
1894 // Setup and remove data paths for all CISes
1895 path_params.data_path_dir =
1896 bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput;
1897 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
1898 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1899
1900 EXPECT_CALL(*cig_callbacks_,
1901 OnRemoveIsoDataPath(HCI_SUCCESS, handle,
1902 volatile_test_cig_create_cmpl_evt_.cig_id))
1903 .Times(1)
1904 .RetiresOnSaturation();
1905 IsoManager::GetInstance()->RemoveIsoDataPath(handle,
1906 path_params.data_path_dir);
1907 }
1908
1909 // Setup and remove data paths for all BISes
1910 path_params.data_path_dir =
1911 bluetooth::hci::iso_manager::kIsoDataPathDirectionOut;
1912 for (auto& handle : volatile_test_big_params_evt_.conn_handles) {
1913 std::cerr << "setting up BIS data path on conn_hdl: " << int{handle};
1914 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
1915
1916 EXPECT_CALL(*big_callbacks_,
1917 OnRemoveIsoDataPath(HCI_SUCCESS, handle,
1918 volatile_test_big_params_evt_.big_id))
1919 .Times(1)
1920 .RetiresOnSaturation();
1921 IsoManager::GetInstance()->RemoveIsoDataPath(handle,
1922 path_params.data_path_dir);
1923 }
1924 }
1925
TEST_F(IsoManagerDeathTest,RemoveIsoDataPathNoSuchPath)1926 TEST_F(IsoManagerDeathTest, RemoveIsoDataPathNoSuchPath) {
1927 // Check on CIS
1928 IsoManager::GetInstance()->CreateCig(
1929 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1930 uint16_t iso_handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
1931 ASSERT_EXIT(
1932 IsoManager::GetInstance()->RemoveIsoDataPath(
1933 iso_handle, bluetooth::hci::iso_manager::kIsoDataPathDirectionOut),
1934 ::testing::KilledBySignal(SIGABRT), "path not set");
1935
1936 IsoManager::GetInstance()->EstablishCis({.conn_pairs = {{iso_handle, 1}}});
1937 ASSERT_EXIT(
1938 IsoManager::GetInstance()->RemoveIsoDataPath(
1939 iso_handle, bluetooth::hci::iso_manager::kIsoDataPathDirectionOut),
1940 ::testing::KilledBySignal(SIGABRT), "path not set");
1941
1942 // Check on BIS
1943 iso_handle = volatile_test_big_params_evt_.conn_handles[0];
1944 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1945 kDefaultBigParams);
1946 ASSERT_EXIT(
1947 IsoManager::GetInstance()->RemoveIsoDataPath(
1948 iso_handle, bluetooth::hci::iso_manager::kIsoDataPathDirectionOut),
1949 ::testing::KilledBySignal(SIGABRT), "path not set");
1950 }
1951
TEST_F(IsoManagerDeathTest,RemoveIsoDataPathTwice)1952 TEST_F(IsoManagerDeathTest, RemoveIsoDataPathTwice) {
1953 // Check on CIS
1954 IsoManager::GetInstance()->CreateCig(
1955 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
1956 uint16_t iso_handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
1957 IsoManager::GetInstance()->EstablishCis({.conn_pairs = {{iso_handle, 1}}});
1958 IsoManager::GetInstance()->SetupIsoDataPath(iso_handle,
1959 kDefaultIsoDataPathParams);
1960 IsoManager::GetInstance()->RemoveIsoDataPath(
1961 iso_handle, kDefaultIsoDataPathParams.data_path_dir);
1962 ASSERT_EXIT(
1963 IsoManager::GetInstance()->RemoveIsoDataPath(
1964 iso_handle, bluetooth::hci::iso_manager::kIsoDataPathDirectionOut),
1965 ::testing::KilledBySignal(SIGABRT), "path not set");
1966
1967 // Check on BIS
1968 iso_handle = volatile_test_big_params_evt_.conn_handles[0];
1969 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
1970 kDefaultBigParams);
1971 IsoManager::GetInstance()->SetupIsoDataPath(iso_handle,
1972 kDefaultIsoDataPathParams);
1973 IsoManager::GetInstance()->RemoveIsoDataPath(
1974 iso_handle, kDefaultIsoDataPathParams.data_path_dir);
1975 ASSERT_EXIT(
1976 IsoManager::GetInstance()->RemoveIsoDataPath(
1977 iso_handle, bluetooth::hci::iso_manager::kIsoDataPathDirectionOut),
1978 ::testing::KilledBySignal(SIGABRT), "path not set");
1979 }
1980
1981 // Check if HCI status other than HCI_SUCCESS is being propagated to the caller
TEST_F(IsoManagerTest,RemoveIsoDataPathInvalidStatus)1982 TEST_F(IsoManagerTest, RemoveIsoDataPathInvalidStatus) {
1983 // Mock invalid status response
1984 uint8_t remove_datapath_rsp_status = 0x12;
1985 ON_CALL(hcic_interface_, RemoveIsoDataPath)
1986 .WillByDefault([&remove_datapath_rsp_status](
1987 uint16_t iso_handle, uint8_t /* data_path_dir */,
1988 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
1989 std::vector<uint8_t> buf(3);
1990 uint8_t* p = buf.data();
1991 UINT8_TO_STREAM(p, remove_datapath_rsp_status);
1992 UINT16_TO_STREAM(p, iso_handle);
1993
1994 std::move(cb).Run(buf.data(), buf.size());
1995 });
1996
1997 // Check on CIS
1998 IsoManager::GetInstance()->CreateCig(
1999 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2000 uint16_t iso_handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2001 IsoManager::GetInstance()->EstablishCis({.conn_pairs = {{iso_handle, 1}}});
2002 IsoManager::GetInstance()->SetupIsoDataPath(iso_handle,
2003 kDefaultIsoDataPathParams);
2004
2005 EXPECT_CALL(*cig_callbacks_,
2006 OnRemoveIsoDataPath(remove_datapath_rsp_status, iso_handle,
2007 volatile_test_cig_create_cmpl_evt_.cig_id))
2008 .Times(1);
2009 IsoManager::GetInstance()->RemoveIsoDataPath(
2010 iso_handle, kDefaultIsoDataPathParams.data_path_dir);
2011
2012 // Check on BIS
2013 iso_handle = volatile_test_big_params_evt_.conn_handles[0];
2014 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
2015 kDefaultBigParams);
2016 IsoManager::GetInstance()->SetupIsoDataPath(iso_handle,
2017 kDefaultIsoDataPathParams);
2018
2019 EXPECT_CALL(*big_callbacks_,
2020 OnRemoveIsoDataPath(remove_datapath_rsp_status, iso_handle,
2021 volatile_test_big_params_evt_.big_id))
2022 .Times(1);
2023 IsoManager::GetInstance()->RemoveIsoDataPath(
2024 iso_handle, kDefaultIsoDataPathParams.data_path_dir);
2025 }
2026
TEST_F(IsoManagerTest,RemoveIsoDataPathLateArrivingCallback)2027 TEST_F(IsoManagerTest, RemoveIsoDataPathLateArrivingCallback) {
2028 IsoManager::GetInstance()->CreateCig(
2029 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2030 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
2031 kDefaultBigParams);
2032
2033 // Establish all CISes before setting up their data paths
2034 bluetooth::hci::iso_manager::cis_establish_params params;
2035 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2036 params.conn_pairs.push_back({handle, 1});
2037 }
2038 IsoManager::GetInstance()->EstablishCis(params);
2039
2040 bluetooth::hci::iso_manager::iso_data_path_params path_params =
2041 kDefaultIsoDataPathParams;
2042
2043 // Setup and remove data paths for all CISes
2044 path_params.data_path_dir =
2045 bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput;
2046 auto& handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2047 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
2048
2049 // Catch the callback
2050 base::OnceCallback<void(uint8_t*, uint16_t)> iso_cb;
2051 ON_CALL(hcic_interface_, RemoveIsoDataPath)
2052 .WillByDefault(
2053 [&iso_cb](uint16_t /* iso_handle */, uint8_t /* data_path_dir */,
2054 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
2055 iso_cb = std::move(cb);
2056 });
2057 IsoManager::GetInstance()->RemoveIsoDataPath(handle,
2058 path_params.data_path_dir);
2059
2060 // Stop the IsoManager before calling the callback
2061 IsoManager::GetInstance()->Stop();
2062
2063 // Call the callback and expect no call
2064 EXPECT_CALL(*cig_callbacks_,
2065 OnRemoveIsoDataPath(HCI_SUCCESS, handle,
2066 volatile_test_cig_create_cmpl_evt_.cig_id))
2067 .Times(0);
2068 ASSERT_FALSE(iso_cb.is_null());
2069
2070 std::vector<uint8_t> buf(3);
2071 uint8_t* p = buf.data();
2072 UINT8_TO_STREAM(p, HCI_SUCCESS);
2073 UINT16_TO_STREAM(p, handle);
2074 std::move(iso_cb).Run(buf.data(), buf.size());
2075 }
2076
TEST_F(IsoManagerTest,SendIsoDataWithNoCigConnected)2077 TEST_F(IsoManagerTest, SendIsoDataWithNoCigConnected) {
2078 std::vector<uint8_t> data_vec(108, 0);
2079 IsoManager::GetInstance()->CreateCig(
2080 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2081
2082 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2083 IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(),
2084 data_vec.size());
2085 EXPECT_CALL(iso_interface_, HciSend).Times(0);
2086 }
2087
TEST_F(IsoManagerTest,SendIsoDataCigValid)2088 TEST_F(IsoManagerTest, SendIsoDataCigValid) {
2089 IsoManager::GetInstance()->CreateCig(
2090 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2091
2092 bluetooth::hci::iso_manager::cis_establish_params params;
2093 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2094 params.conn_pairs.push_back({handle, 1});
2095 }
2096 IsoManager::GetInstance()->EstablishCis(params);
2097
2098 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2099 bluetooth::hci::iso_manager::iso_data_path_params path_params =
2100 kDefaultIsoDataPathParams;
2101 path_params.data_path_dir =
2102 bluetooth::hci::iso_manager::kIsoDataPathDirectionOut;
2103 IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
2104
2105 for (uint8_t num_pkts = 2; num_pkts != 0; num_pkts--) {
2106 constexpr uint8_t data_len = 108;
2107
2108 EXPECT_CALL(iso_interface_, HciSend)
2109 .WillOnce([handle, data_len](BT_HDR* p_msg) {
2110 uint8_t* p = p_msg->data;
2111 uint16_t msg_handle;
2112 uint16_t iso_load_len;
2113
2114 ASSERT_NE(p_msg, nullptr);
2115 ASSERT_EQ(p_msg->len, data_len + ((p_msg->layer_specific &
2116 BT_ISO_HDR_CONTAINS_TS)
2117 ? 12
2118 : 8));
2119
2120 // Verify packet internals
2121 STREAM_TO_UINT16(msg_handle, p);
2122 ASSERT_EQ(msg_handle, handle);
2123
2124 STREAM_TO_UINT16(iso_load_len, p);
2125 ASSERT_EQ(
2126 iso_load_len,
2127 data_len +
2128 ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) ? 8 : 4));
2129
2130 if (p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) {
2131 STREAM_SKIP_UINT16(p); // skip ts LSB halfword
2132 STREAM_SKIP_UINT16(p); // skip ts MSB halfword
2133 }
2134 STREAM_SKIP_UINT16(p); // skip seq_nb
2135
2136 uint16_t msg_data_len;
2137 STREAM_TO_UINT16(msg_data_len, p);
2138 ASSERT_EQ(msg_data_len, data_len);
2139 })
2140 .RetiresOnSaturation();
2141
2142 std::vector<uint8_t> data_vec(data_len, 0);
2143 IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(),
2144 data_vec.size());
2145 }
2146 }
2147 }
2148
TEST_F(IsoManagerTest,SendIsoDataBigValid)2149 TEST_F(IsoManagerTest, SendIsoDataBigValid) {
2150 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
2151 kDefaultBigParams);
2152
2153 for (auto& handle : volatile_test_big_params_evt_.conn_handles) {
2154 IsoManager::GetInstance()->SetupIsoDataPath(handle,
2155 kDefaultIsoDataPathParams);
2156 for (uint8_t num_pkts = 2; num_pkts != 0; num_pkts--) {
2157 constexpr uint8_t data_len = 108;
2158
2159 EXPECT_CALL(iso_interface_, HciSend)
2160 .WillOnce([handle, data_len](BT_HDR* p_msg) {
2161 uint8_t* p = p_msg->data;
2162 uint16_t msg_handle;
2163 uint16_t iso_load_len;
2164
2165 ASSERT_NE(p_msg, nullptr);
2166 ASSERT_EQ(p_msg->len, data_len + ((p_msg->layer_specific &
2167 BT_ISO_HDR_CONTAINS_TS)
2168 ? 12
2169 : 8));
2170
2171 // Verify packet internals
2172 STREAM_TO_UINT16(msg_handle, p);
2173 ASSERT_EQ(msg_handle, handle);
2174
2175 STREAM_TO_UINT16(iso_load_len, p);
2176 ASSERT_EQ(
2177 iso_load_len,
2178 data_len +
2179 ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) ? 8 : 4));
2180
2181 uint16_t msg_data_len;
2182 uint16_t msg_dummy;
2183 if (p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) {
2184 STREAM_TO_UINT16(msg_dummy, p); // skip ts LSB halfword
2185 STREAM_TO_UINT16(msg_dummy, p); // skip ts MSB halfword
2186 }
2187 STREAM_TO_UINT16(msg_dummy, p); // skip seq_nb
2188
2189 STREAM_TO_UINT16(msg_data_len, p);
2190 ASSERT_EQ(msg_data_len, data_len);
2191 })
2192 .RetiresOnSaturation();
2193
2194 std::vector<uint8_t> data_vec(data_len, 0);
2195 IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(),
2196 data_vec.size());
2197 }
2198 }
2199 }
2200
TEST_F(IsoManagerTest,SendIsoDataNoCredits)2201 TEST_F(IsoManagerTest, SendIsoDataNoCredits) {
2202 uint8_t num_buffers =
2203 controller_.GetControllerIsoBufferSize().total_num_le_packets_;
2204 std::vector<uint8_t> data_vec(108, 0);
2205
2206 // Check on CIG
2207 IsoManager::GetInstance()->CreateCig(
2208 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2209
2210 bluetooth::hci::iso_manager::cis_establish_params params;
2211 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2212 params.conn_pairs.push_back({handle, 1});
2213 }
2214 IsoManager::GetInstance()->EstablishCis(params);
2215
2216 IsoManager::GetInstance()->SetupIsoDataPath(
2217 volatile_test_cig_create_cmpl_evt_.conn_handles[0],
2218 kDefaultIsoDataPathParams);
2219
2220 /* Try sending twice as much data as we can ignoring the credit limits and
2221 * expect the redundant packets to be ignored and not propagated down to the
2222 * HCI.
2223 */
2224 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2225 for (uint8_t i = 0; i < (2 * num_buffers); i++) {
2226 IsoManager::GetInstance()->SendIsoData(
2227 volatile_test_cig_create_cmpl_evt_.conn_handles[0], data_vec.data(),
2228 data_vec.size());
2229 }
2230
2231 // Return all credits for this one handle
2232 IsoManager::GetInstance()->HandleNumComplDataPkts(
2233 volatile_test_cig_create_cmpl_evt_.conn_handles[0], num_buffers);
2234
2235 // Check on BIG
2236 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
2237 kDefaultBigParams);
2238 IsoManager::GetInstance()->SetupIsoDataPath(
2239 volatile_test_big_params_evt_.conn_handles[0], kDefaultIsoDataPathParams);
2240
2241 /* Try sending twice as much data as we can ignoring the credit limits and
2242 * expect the redundant packets to be ignored and not propagated down to the
2243 * HCI.
2244 */
2245 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers);
2246 for (uint8_t i = 0; i < (2 * num_buffers); i++) {
2247 IsoManager::GetInstance()->SendIsoData(
2248 volatile_test_big_params_evt_.conn_handles[0], data_vec.data(),
2249 data_vec.size());
2250 }
2251 }
2252
TEST_F(IsoManagerTest,SendIsoDataCreditsReturned)2253 TEST_F(IsoManagerTest, SendIsoDataCreditsReturned) {
2254 uint8_t num_buffers =
2255 controller_.GetControllerIsoBufferSize().total_num_le_packets_;
2256 std::vector<uint8_t> data_vec(108, 0);
2257
2258 // Check on CIG
2259 IsoManager::GetInstance()->CreateCig(
2260 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2261
2262 bluetooth::hci::iso_manager::cis_establish_params params;
2263 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2264 params.conn_pairs.push_back({handle, 1});
2265 }
2266 IsoManager::GetInstance()->EstablishCis(params);
2267
2268 IsoManager::GetInstance()->SetupIsoDataPath(
2269 volatile_test_cig_create_cmpl_evt_.conn_handles[0],
2270 kDefaultIsoDataPathParams);
2271
2272 /* Try sending twice as much data as we can, ignoring the credits limit and
2273 * expect the redundant packets to be ignored and not propagated down to the
2274 * HCI.
2275 */
2276 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2277 for (uint8_t i = 0; i < (2 * num_buffers); i++) {
2278 IsoManager::GetInstance()->SendIsoData(
2279 volatile_test_cig_create_cmpl_evt_.conn_handles[0], data_vec.data(),
2280 data_vec.size());
2281 }
2282
2283 // Return all credits for this one handle
2284 IsoManager::GetInstance()->HandleNumComplDataPkts(
2285 volatile_test_cig_create_cmpl_evt_.conn_handles[0], num_buffers);
2286
2287 // Expect some more events go down the HCI
2288 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2289 for (uint8_t i = 0; i < (2 * num_buffers); i++) {
2290 IsoManager::GetInstance()->SendIsoData(
2291 volatile_test_cig_create_cmpl_evt_.conn_handles[0], data_vec.data(),
2292 data_vec.size());
2293 }
2294
2295 // Return all credits for this one handle
2296 IsoManager::GetInstance()->HandleNumComplDataPkts(
2297 volatile_test_cig_create_cmpl_evt_.conn_handles[0], num_buffers);
2298
2299 // Check on BIG
2300 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
2301 kDefaultBigParams);
2302 IsoManager::GetInstance()->SetupIsoDataPath(
2303 volatile_test_big_params_evt_.conn_handles[0], kDefaultIsoDataPathParams);
2304
2305 /* Try sending twice as much data as we can, ignoring the credits limit and
2306 * expect the redundant packets to be ignored and not propagated down to the
2307 * HCI.
2308 */
2309 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2310 for (uint8_t i = 0; i < (2 * num_buffers); i++) {
2311 IsoManager::GetInstance()->SendIsoData(
2312 volatile_test_big_params_evt_.conn_handles[0], data_vec.data(),
2313 data_vec.size());
2314 }
2315
2316 // Return all credits for this one handle
2317 IsoManager::GetInstance()->HandleNumComplDataPkts(
2318 volatile_test_big_params_evt_.conn_handles[0], num_buffers);
2319
2320 // Expect some more events go down the HCI
2321 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2322 for (uint8_t i = 0; i < (2 * num_buffers); i++) {
2323 IsoManager::GetInstance()->SendIsoData(
2324 volatile_test_big_params_evt_.conn_handles[0], data_vec.data(),
2325 data_vec.size());
2326 }
2327 }
2328
TEST_F(IsoManagerTest,SendIsoDataCreditsReturnedByDisconnection)2329 TEST_F(IsoManagerTest, SendIsoDataCreditsReturnedByDisconnection) {
2330 uint8_t num_buffers =
2331 controller_.GetControllerIsoBufferSize().total_num_le_packets_;
2332 std::vector<uint8_t> data_vec(108, 0);
2333
2334 // Check on CIG
2335 IsoManager::GetInstance()->CreateCig(
2336 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2337
2338 bluetooth::hci::iso_manager::cis_establish_params params;
2339 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2340 params.conn_pairs.push_back({handle, 1});
2341 }
2342 IsoManager::GetInstance()->EstablishCis(params);
2343
2344 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2345 IsoManager::GetInstance()->SetupIsoDataPath(handle,
2346 kDefaultIsoDataPathParams);
2347 }
2348
2349 /* Sending lot of ISO data to first ISO and getting all the credits */
2350 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2351 for (uint8_t i = 0; i < num_buffers; i++) {
2352 IsoManager::GetInstance()->SendIsoData(
2353 volatile_test_cig_create_cmpl_evt_.conn_handles[0], data_vec.data(),
2354 data_vec.size());
2355 }
2356
2357 /* Return all credits by disconnecting CIS */
2358 IsoManager::GetInstance()->HandleDisconnect(
2359 volatile_test_cig_create_cmpl_evt_.conn_handles[0], 16);
2360
2361 /* Try to send ISO data on the second ISO. Expect credits being available.*/
2362 EXPECT_CALL(iso_interface_, HciSend).Times(num_buffers).RetiresOnSaturation();
2363 for (uint8_t i = 0; i < num_buffers; i++) {
2364 IsoManager::GetInstance()->SendIsoData(
2365 volatile_test_cig_create_cmpl_evt_.conn_handles[1], data_vec.data(),
2366 data_vec.size());
2367 }
2368 }
2369
TEST_F(IsoManagerDeathTest,SendIsoDataWithNoDataPath)2370 TEST_F(IsoManagerDeathTest, SendIsoDataWithNoDataPath) {
2371 std::vector<uint8_t> data_vec(108, 0);
2372
2373 // Check on CIG
2374 IsoManager::GetInstance()->CreateCig(
2375 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2376
2377 bluetooth::hci::iso_manager::cis_establish_params params;
2378 for (auto& conn_handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2379 params.conn_pairs.push_back({conn_handle, 1});
2380 }
2381 IsoManager::GetInstance()->EstablishCis(params);
2382
2383 EXPECT_CALL(iso_interface_, HciSend).Times(0);
2384 IsoManager::GetInstance()->SendIsoData(
2385 volatile_test_cig_create_cmpl_evt_.conn_handles[0], data_vec.data(),
2386 data_vec.size());
2387
2388 // Check on BIG
2389 IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id,
2390 kDefaultBigParams);
2391
2392 EXPECT_CALL(iso_interface_, HciSend).Times(0);
2393 IsoManager::GetInstance()->SendIsoData(
2394 volatile_test_big_params_evt_.conn_handles[0], data_vec.data(),
2395 data_vec.size());
2396 }
2397
TEST_F(IsoManagerDeathTest,SendIsoDataWithNoCigBigHandle)2398 TEST_F(IsoManagerDeathTest, SendIsoDataWithNoCigBigHandle) {
2399 std::vector<uint8_t> data_vec(108, 0);
2400 ASSERT_EXIT(IsoManager::GetInstance()->SendIsoData(134, data_vec.data(),
2401 data_vec.size()),
2402 ::testing::KilledBySignal(SIGABRT), "No such iso");
2403 }
2404
TEST_F(IsoManagerTest,HandleDisconnectNoSuchHandle)2405 TEST_F(IsoManagerTest, HandleDisconnectNoSuchHandle) {
2406 // Don't expect any callbacks when connection handle is not for ISO.
2407 EXPECT_CALL(*cig_callbacks_, OnCigEvent).Times(0);
2408 EXPECT_CALL(*cig_callbacks_, OnCisEvent).Times(0);
2409 EXPECT_CALL(*big_callbacks_, OnBigEvent).Times(0);
2410
2411 IsoManager::GetInstance()->HandleDisconnect(123, 16);
2412 }
2413
TEST_F(IsoManagerTest,HandleDisconnectValidCig)2414 TEST_F(IsoManagerTest, HandleDisconnectValidCig) {
2415 IsoManager::GetInstance()->CreateCig(
2416 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2417
2418 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2419 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2420
2421 EXPECT_CALL(*big_callbacks_, OnBigEvent).Times(0);
2422 EXPECT_CALL(*cig_callbacks_, OnCigEvent).Times(0);
2423 EXPECT_CALL(*cig_callbacks_, OnCisEvent).Times(0);
2424
2425 // Expect disconnect event exactly once
2426 EXPECT_CALL(*cig_callbacks_, OnCisEvent)
2427 .WillOnce([this, handle](uint8_t event_code, void* data) {
2428 ASSERT_EQ(event_code,
2429 bluetooth::hci::iso_manager::kIsoEventCisDisconnected);
2430 auto* event =
2431 static_cast<bluetooth::hci::iso_manager::cis_disconnected_evt*>(
2432 data);
2433 ASSERT_EQ(event->reason, 16);
2434 ASSERT_EQ(event->cig_id, volatile_test_cig_create_cmpl_evt_.cig_id);
2435 ASSERT_EQ(event->cis_conn_hdl, handle);
2436 });
2437
2438 IsoManager::GetInstance()->HandleDisconnect(handle, 16);
2439 }
2440
TEST_F(IsoManagerTest,HandleDisconnectDisconnectedCig)2441 TEST_F(IsoManagerTest, HandleDisconnectDisconnectedCig) {
2442 IsoManager::GetInstance()->CreateCig(
2443 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2444
2445 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2446 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2447
2448 EXPECT_CALL(*big_callbacks_, OnBigEvent).Times(0);
2449 EXPECT_CALL(*cig_callbacks_, OnCigEvent).Times(0);
2450 EXPECT_CALL(*cig_callbacks_, OnCisEvent).Times(0);
2451
2452 // Expect disconnect event exactly once
2453 EXPECT_CALL(
2454 *cig_callbacks_,
2455 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDisconnected, _))
2456 .Times(1)
2457 .RetiresOnSaturation();
2458 IsoManager::GetInstance()->HandleDisconnect(handle, 16);
2459
2460 // This one was once connected - expect no events
2461 IsoManager::GetInstance()->HandleDisconnect(handle, 16);
2462
2463 // This one was never connected - expect no events
2464 handle = volatile_test_cig_create_cmpl_evt_.conn_handles[1];
2465 IsoManager::GetInstance()->HandleDisconnect(handle, 16);
2466 }
2467
TEST_F(IsoManagerTest,HandleDisconnectLateArrivingCallback)2468 TEST_F(IsoManagerTest, HandleDisconnectLateArrivingCallback) {
2469 IsoManager::GetInstance()->CreateCig(
2470 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2471
2472 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2473 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2474
2475 EXPECT_CALL(*big_callbacks_, OnBigEvent).Times(0);
2476 EXPECT_CALL(*cig_callbacks_, OnCigEvent).Times(0);
2477 EXPECT_CALL(*cig_callbacks_, OnCisEvent).Times(0);
2478
2479 // Expect disconnect event exactly once
2480 EXPECT_CALL(
2481 *cig_callbacks_,
2482 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDisconnected, _))
2483 .Times(0);
2484
2485 // Expect no callback on late arriving event
2486 IsoManager::GetInstance()->Stop();
2487 IsoManager::GetInstance()->HandleDisconnect(handle, 16);
2488 }
2489
TEST_F(IsoManagerTest,HandleIsoData)2490 TEST_F(IsoManagerTest, HandleIsoData) {
2491 IsoManager::GetInstance()->CreateCig(
2492 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2493
2494 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2495 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2496
2497 EXPECT_CALL(
2498 *cig_callbacks_,
2499 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, _))
2500 .Times(1);
2501
2502 std::vector<uint8_t> dummy_msg(18);
2503 uint8_t* p = dummy_msg.data();
2504 UINT16_TO_STREAM(p, BT_EVT_TO_BTU_HCI_ISO);
2505 UINT16_TO_STREAM(p, 10); // .len
2506 UINT16_TO_STREAM(p, 0); // .offset
2507 UINT16_TO_STREAM(p, 0); // .layer_specific
2508 UINT16_TO_STREAM(p, handle);
2509 IsoManager::GetInstance()->HandleIsoData(dummy_msg.data());
2510 }
2511
2512 /* This test case simulates HCI thread scheduling events on the main thread,
2513 * without knowing the we are already shutting down the stack and Iso Manager
2514 * is already stopped.
2515 */
TEST_F(IsoManagerDeathTestNoCleanup,HandleLateArivingEventHandleIsoData)2516 TEST_F(IsoManagerDeathTestNoCleanup, HandleLateArivingEventHandleIsoData) {
2517 IsoManager::GetInstance()->CreateCig(
2518 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2519
2520 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2521 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2522
2523 // Stop iso manager before trying to call the HCI callbacks
2524 IsoManager::GetInstance()->Stop();
2525
2526 EXPECT_CALL(
2527 *cig_callbacks_,
2528 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, _))
2529 .Times(0);
2530
2531 // Expect no assert on this call - should be gracefully ignored
2532 std::vector<uint8_t> dummy_msg(18);
2533 uint8_t* p = dummy_msg.data();
2534 UINT16_TO_STREAM(p, BT_EVT_TO_BTU_HCI_ISO);
2535 UINT16_TO_STREAM(p, 10); // .len
2536 UINT16_TO_STREAM(p, 0); // .offset
2537 UINT16_TO_STREAM(p, 0); // .layer_specific
2538 UINT16_TO_STREAM(p, handle);
2539 IsoManager::GetInstance()->HandleIsoData(dummy_msg.data());
2540 }
2541
2542 /* This test case simulates HCI thread scheduling events on the main thread,
2543 * without knowing the we are already shutting down the stack and Iso Manager
2544 * is already stopped.
2545 */
TEST_F(IsoManagerDeathTestNoCleanup,HandleLateArivingEventHandleDisconnect)2546 TEST_F(IsoManagerDeathTestNoCleanup, HandleLateArivingEventHandleDisconnect) {
2547 IsoManager::GetInstance()->CreateCig(
2548 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2549
2550 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2551 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2552
2553 // Stop iso manager before trying to call the HCI callbacks
2554 IsoManager::GetInstance()->Stop();
2555
2556 // Expect no event when callback is being called on a stopped iso manager
2557 EXPECT_CALL(*cig_callbacks_, OnCisEvent).Times(0);
2558 // Expect no assert on this call - should be gracefully ignored
2559 IsoManager::GetInstance()->HandleDisconnect(handle, 16);
2560 }
2561
2562 /* This test case simulates HCI thread scheduling events on the main thread,
2563 * without knowing the we are already shutting down the stack and Iso Manager
2564 * is already stopped.
2565 */
TEST_F(IsoManagerDeathTestNoCleanup,HandleLateArivingEventHandleNumComplDataPkts)2566 TEST_F(IsoManagerDeathTestNoCleanup,
2567 HandleLateArivingEventHandleNumComplDataPkts) {
2568 uint8_t num_buffers =
2569 controller_.GetControllerIsoBufferSize().total_num_le_packets_;
2570
2571 IsoManager::GetInstance()->CreateCig(
2572 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2573
2574 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2575 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2576
2577 // Stop iso manager before trying to call the HCI callbacks
2578 IsoManager::GetInstance()->Stop();
2579
2580 // Expect no assert on this call - should be gracefully ignored
2581 IsoManager::GetInstance()->HandleNumComplDataPkts(handle, num_buffers);
2582 }
2583
2584 /* This test case simulates HCI thread scheduling events on the main thread,
2585 * without knowing the we are already shutting down the stack and Iso Manager
2586 * is already stopped.
2587 */
TEST_F(IsoManagerDeathTestNoCleanup,HandleLateArivingEventHandleHciEvent)2588 TEST_F(IsoManagerDeathTestNoCleanup, HandleLateArivingEventHandleHciEvent) {
2589 const uint8_t big_id = 0x22;
2590
2591 IsoManager::GetInstance()->CreateBig(big_id, kDefaultBigParams);
2592
2593 // Stop iso manager before trying to call the HCI callbacks
2594 IsoManager::GetInstance()->Stop();
2595 EXPECT_CALL(
2596 *big_callbacks_,
2597 OnBigEvent(bluetooth::hci::iso_manager::kIsoEventBigOnTerminateCmpl, _))
2598 .Times(0);
2599
2600 // Expect no assert on this call - should be gracefully ignored
2601 std::vector<uint8_t> buf(2);
2602 uint8_t* p = buf.data();
2603 UINT8_TO_STREAM(p, big_id);
2604 UINT8_TO_STREAM(p, 16); // Terminated by local host
2605 IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
2606 buf.data(), buf.size());
2607 }
2608
TEST_F(IsoManagerTest,HandleIsoDataSameSeqNb)2609 TEST_F(IsoManagerTest, HandleIsoDataSameSeqNb) {
2610 IsoManager::GetInstance()->CreateCig(
2611 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2612
2613 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2614 IsoManager::GetInstance()->EstablishCis({{{handle, 1}}});
2615
2616 EXPECT_CALL(
2617 *cig_callbacks_,
2618 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, _))
2619 .Times(2);
2620
2621 std::vector<uint8_t> dummy_msg(18);
2622 uint8_t* p = dummy_msg.data();
2623 UINT16_TO_STREAM(p, BT_EVT_TO_BTU_HCI_ISO);
2624 UINT16_TO_STREAM(p, 10); // .len
2625 UINT16_TO_STREAM(p, 0); // .offset
2626 UINT16_TO_STREAM(p, 0); // .layer_specific
2627 UINT16_TO_STREAM(p, handle);
2628
2629 IsoManager::GetInstance()->HandleIsoData(dummy_msg.data());
2630 IsoManager::GetInstance()->HandleIsoData(dummy_msg.data());
2631 }
2632
TEST_F(IsoManagerTest,ReadIsoLinkQualityLateArrivingCallback)2633 TEST_F(IsoManagerTest, ReadIsoLinkQualityLateArrivingCallback) {
2634 IsoManager::GetInstance()->CreateCig(
2635 volatile_test_cig_create_cmpl_evt_.cig_id, kDefaultCigParams);
2636
2637 EXPECT_CALL(
2638 *cig_callbacks_,
2639 OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl, _))
2640 .Times(kDefaultCigParams.cis_cfgs.size())
2641 .WillRepeatedly([this](uint8_t /* type */, void* data) {
2642 bluetooth::hci::iso_manager::cis_establish_cmpl_evt* evt =
2643 static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(
2644 data);
2645
2646 ASSERT_EQ(evt->status, HCI_SUCCESS);
2647 ASSERT_TRUE(
2648 std::find(volatile_test_cig_create_cmpl_evt_.conn_handles.begin(),
2649 volatile_test_cig_create_cmpl_evt_.conn_handles.end(),
2650 evt->cis_conn_hdl) !=
2651 volatile_test_cig_create_cmpl_evt_.conn_handles.end());
2652 });
2653
2654 // Establish all CISes
2655 bluetooth::hci::iso_manager::cis_establish_params params;
2656 for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
2657 params.conn_pairs.push_back({handle, 1});
2658 }
2659 IsoManager::GetInstance()->EstablishCis(params);
2660
2661 // Catch the callback
2662 base::OnceCallback<void(uint8_t*, uint16_t)> iso_cb;
2663 ON_CALL(hcic_interface_, ReadIsoLinkQuality)
2664 .WillByDefault(
2665 [&iso_cb](uint16_t /* iso_handle */,
2666 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
2667 iso_cb = std::move(cb);
2668 });
2669 auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
2670 IsoManager::GetInstance()->ReadIsoLinkQuality(handle);
2671
2672 // Stop the IsoManager before calling the callback
2673 IsoManager::GetInstance()->Stop();
2674
2675 // Call the callback and expect no call
2676 EXPECT_CALL(*cig_callbacks_,
2677 OnIsoLinkQualityRead(handle, _, _, _, _, _, _, _, _))
2678 .Times(0);
2679 ASSERT_FALSE(iso_cb.is_null());
2680
2681 std::vector<uint8_t> buf(31);
2682 uint8_t* p = buf.data();
2683 UINT8_TO_STREAM(p, HCI_SUCCESS);
2684 UINT16_TO_STREAM(p, handle);
2685 UINT32_TO_STREAM(p, 0);
2686 UINT32_TO_STREAM(p, 0);
2687 UINT32_TO_STREAM(p, 0);
2688 UINT32_TO_STREAM(p, 0);
2689 UINT32_TO_STREAM(p, 0);
2690 UINT32_TO_STREAM(p, 0);
2691 UINT32_TO_STREAM(p, 0);
2692 std::move(iso_cb).Run(buf.data(), buf.size());
2693 }
2694