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