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