1 /*
2  * Copyright 2021 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 "state_machine.h"
19 
20 #include <com_android_bluetooth_flags.h>
21 #include <flag_macros.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include <future>
26 
27 #include "../le_audio_types.h"
28 #include "broadcast_configuration_provider.h"
29 #include "btm_iso_api.h"
30 #include "stack/include/btm_ble_api_types.h"
31 #include "state_machine.h"
32 #include "test/common/mock_functions.h"
33 #include "test/mock/mock_main_shim_le_advertising_manager.h"
34 #include "test/mock/mock_stack_btm_iso.h"
35 
36 #define TEST_BT com::android::bluetooth::flags
37 
38 // TODO(b/369381361) Enfore -Wmissing-prototypes
39 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
40 
41 using namespace bluetooth::hci::iso_manager;
42 
43 using bluetooth::hci::IsoManager;
44 using bluetooth::le_audio::BasicAudioAnnouncementData;
45 using testing::_;
46 using testing::Mock;
47 using testing::Return;
48 using testing::SaveArg;
49 using testing::Test;
50 
51 // Disables most likely false-positives from base::SplitString()
__asan_default_options()52 extern "C" const char* __asan_default_options() { return "detect_container_overflow=0"; }
53 
btsnd_hcic_ble_rand(base::Callback<void (BT_OCTET8)>)54 void btsnd_hcic_ble_rand(base::Callback<void(BT_OCTET8)> /*cb*/) {}
55 
56 namespace bluetooth::le_audio {
57 namespace broadcaster {
58 namespace {
59 // bit 0: encrypted, bit 1: standard quality present
60 static const uint8_t test_public_broadcast_features = 0x3;
61 static const std::string test_broadcast_name = "Test";
62 static const std::vector<uint8_t> default_public_metadata = {
63         5, bluetooth::le_audio::types::kLeAudioMetadataTypeProgramInfo, 0x1, 0x2, 0x3, 0x4};
64 
65 class MockBroadcastStatMachineCallbacks : public IBroadcastStateMachineCallbacks {
66 public:
67   MockBroadcastStatMachineCallbacks() = default;
68   MockBroadcastStatMachineCallbacks(const MockBroadcastStatMachineCallbacks&) = delete;
69   MockBroadcastStatMachineCallbacks& operator=(const MockBroadcastStatMachineCallbacks&) = delete;
70 
71   ~MockBroadcastStatMachineCallbacks() override = default;
72 
73   MOCK_METHOD((void), OnStateMachineCreateStatus, (uint32_t broadcast_id, bool initialized),
74               (override));
75   MOCK_METHOD((void), OnStateMachineDestroyed, (uint32_t broadcast_id), (override));
76   MOCK_METHOD((void), OnStateMachineEvent,
77               (uint32_t broadcast_id, BroadcastStateMachine::State state, const void* data),
78               (override));
79   MOCK_METHOD((void), OnOwnAddressResponse,
80               (uint32_t broadcast_id, uint8_t addr_type, RawAddress addr), (override));
81   MOCK_METHOD((void), OnBigCreated, (const std::vector<uint16_t>& conn_handle), (override));
82   MOCK_METHOD((void), OnAnnouncementUpdated, (uint32_t broadcast_id), (override));
83 };
84 
85 class MockBroadcastAdvertisingCallbacks : public AdvertisingCallbacks {
86 public:
87   MockBroadcastAdvertisingCallbacks() = default;
88   MockBroadcastAdvertisingCallbacks(const MockBroadcastAdvertisingCallbacks&) = delete;
89   MockBroadcastAdvertisingCallbacks& operator=(const MockBroadcastAdvertisingCallbacks&) = delete;
90 
91   ~MockBroadcastAdvertisingCallbacks() override = default;
92 
93   MOCK_METHOD((void), OnAdvertisingSetStarted,
94               (int reg_id, uint8_t advertiser_id, int8_t tx_power, uint8_t status), (override));
95   MOCK_METHOD((void), OnAdvertisingEnabled, (uint8_t advertiser_id, bool enable, uint8_t status),
96               (override));
97   MOCK_METHOD((void), OnAdvertisingDataSet, (uint8_t advertiser_id, uint8_t status), (override));
98   MOCK_METHOD((void), OnScanResponseDataSet, (uint8_t advertiser_id, uint8_t status), (override));
99   MOCK_METHOD((void), OnAdvertisingParametersUpdated,
100               (uint8_t advertiser_id, int8_t tx_power, uint8_t status), (override));
101   MOCK_METHOD((void), OnPeriodicAdvertisingParametersUpdated,
102               (uint8_t advertiser_id, uint8_t status), (override));
103   MOCK_METHOD((void), OnPeriodicAdvertisingDataSet, (uint8_t advertiser_id, uint8_t status),
104               (override));
105   MOCK_METHOD((void), OnPeriodicAdvertisingEnabled,
106               (uint8_t advertiser_id, bool enable, uint8_t status), (override));
107   MOCK_METHOD((void), OnOwnAddressRead,
108               (uint8_t advertiser_id, uint8_t address_type, RawAddress address), (override));
109 };
110 
111 class StateMachineTest : public Test {
112 protected:
SetUp()113   void SetUp() override {
114     reset_mock_function_count_map();
115     MockBleAdvertisingManager::Initialize();
116 
117     mock_ble_advertising_manager_ = MockBleAdvertisingManager::Get();
118 
119     sm_callbacks_.reset(new MockBroadcastStatMachineCallbacks());
120     adv_callbacks_.reset(new MockBroadcastAdvertisingCallbacks());
121     BroadcastStateMachine::Initialize(sm_callbacks_.get(), adv_callbacks_.get());
122 
123     ON_CALL(*mock_ble_advertising_manager_, StartAdvertisingSet)
124             .WillByDefault([this](uint8_t /*client_id*/, int /*reg_id*/,
125                                   ::BleAdvertiserInterface::IdTxPowerStatusCallback /*register_cb*/,
126                                   ::AdvertiseParameters /*params*/,
127                                   std::vector<uint8_t> /*advertise_data*/,
128                                   std::vector<uint8_t> /*scan_response_data*/,
129                                   ::PeriodicAdvertisingParameters /*periodic_params*/,
130                                   std::vector<uint8_t> /*periodic_data*/, uint16_t /*duration*/,
131                                   uint8_t /*maxExtAdvEvents*/,
132                                   ::BleAdvertiserInterface::IdStatusCallback /*timeout_cb*/) {
133               static uint8_t advertiser_id = 1;
134               uint8_t tx_power = 32;
135               uint8_t status = 0;
136               this->adv_callbacks_->OnAdvertisingSetStarted(
137                       BroadcastStateMachine::kLeAudioBroadcastRegId, advertiser_id++, tx_power,
138                       status);
139             });
140 
141     ON_CALL(*mock_ble_advertising_manager_, Enable)
142             .WillByDefault([this](uint8_t advertiser_id, bool enable,
143                                   ::BleAdvertiserInterface::StatusCallback /*cb*/,
144                                   uint16_t /*duration*/, uint8_t /*maxExtAdvEvents*/,
145                                   ::BleAdvertiserInterface::StatusCallback /*timeout_cb*/) {
146               uint8_t status = 0;
147               this->adv_callbacks_->OnAdvertisingEnabled(advertiser_id, enable, status);
148             });
149 
150     ON_CALL(*mock_ble_advertising_manager_, GetOwnAddress)
151             .WillByDefault(
152                     [](uint8_t /*inst_id*/, ::BleAdvertiserInterface::GetAddressCallback cb) {
153                       uint8_t address_type = 0x02;
154                       RawAddress address;
155                       const uint8_t addr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
156                       address.FromOctets(addr);
157                       cb.Run(address_type, address);
158                     });
159 
160     ON_CALL(*mock_ble_advertising_manager_, SetData)
161             .WillByDefault([this](int advertiser_id, bool /*set_scan_rsp*/,
162                                   std::vector<uint8_t> /*data*/,
163                                   ::BleAdvertiserInterface::StatusCallback /*cb*/) {
164               uint8_t status = 0;
165               this->adv_callbacks_->OnAdvertisingDataSet(advertiser_id, status);
166             });
167 
168     ON_CALL(*mock_ble_advertising_manager_, SetPeriodicAdvertisingData)
169             .WillByDefault([this](int advertiser_id, std::vector<uint8_t> /*data*/,
170                                   ::BleAdvertiserInterface::StatusCallback /*cb*/) {
171               uint8_t status = 0;
172               this->adv_callbacks_->OnPeriodicAdvertisingDataSet(advertiser_id, status);
173             });
174 
175     ON_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus)
176             .WillByDefault([this](uint32_t broadcast_id, bool initialized) {
177               auto instance_it = std::find_if(
178                       pending_broadcasts_.begin(), pending_broadcasts_.end(),
179                       [broadcast_id](auto& up) { return up->GetBroadcastId() == broadcast_id; });
180               if (instance_it != pending_broadcasts_.end()) {
181                 if (initialized) {
182                   broadcasts_[broadcast_id] = std::move(*instance_it);
183                 }
184                 pending_broadcasts_.erase(instance_it);
185               }
186               instance_creation_promise_.set_value(broadcast_id);
187             });
188 
189     ON_CALL(*(sm_callbacks_.get()), OnStateMachineDestroyed)
190             .WillByDefault([this](uint32_t broadcast_id) {
191               if (broadcasts_.count(broadcast_id)) {
192                 instance_destruction_promise_.set_value(broadcast_id);
193               }
194             });
195 
196     ON_CALL(*(adv_callbacks_.get()), OnAdvertisingSetStarted)
197             .WillByDefault([this](int /*reg_id*/, uint8_t advertiser_id, int8_t tx_power,
198                                   uint8_t status) {
199               pending_broadcasts_.back()->OnCreateAnnouncement(advertiser_id, tx_power, status);
200             });
201 
202     ON_CALL(*(adv_callbacks_.get()), OnAdvertisingEnabled)
203             .WillByDefault([this](uint8_t advertiser_id, bool enable, uint8_t status) {
204               auto const& iter = std::find_if(
205                       broadcasts_.cbegin(), broadcasts_.cend(), [advertiser_id](auto const& sm) {
206                         return sm.second->GetAdvertisingSid() == advertiser_id;
207                       });
208               if (iter != broadcasts_.cend()) {
209                 iter->second->OnEnableAnnouncement(enable, status);
210               }
211             });
212 
213     ON_CALL(*(adv_callbacks_.get()), OnAdvertisingDataSet)
214             .WillByDefault([this](uint8_t advertiser_id, uint8_t status) {
215               auto const& iter = std::find_if(
216                       broadcasts_.cbegin(), broadcasts_.cend(), [advertiser_id](auto const& sm) {
217                         return sm.second->GetAdvertisingSid() == advertiser_id;
218                       });
219               if (iter != broadcasts_.cend()) {
220                 iter->second->OnUpdateAnnouncement(status);
221               }
222             });
223 
224     ON_CALL(*(adv_callbacks_.get()), OnPeriodicAdvertisingDataSet)
225             .WillByDefault([this](uint8_t advertiser_id, uint8_t status) {
226               auto const& iter = std::find_if(
227                       broadcasts_.cbegin(), broadcasts_.cend(), [advertiser_id](auto const& sm) {
228                         return sm.second->GetAdvertisingSid() == advertiser_id;
229                       });
230               if (iter != broadcasts_.cend()) {
231                 iter->second->OnUpdateAnnouncement(status);
232               }
233             });
234 
235     ConfigureIsoManagerMock();
236   }
237 
ConfigureIsoManagerMock()238   void ConfigureIsoManagerMock() {
239     iso_manager_ = IsoManager::GetInstance();
240     ASSERT_NE(iso_manager_, nullptr);
241     iso_manager_->Start();
242 
243     mock_iso_manager_ = MockIsoManager::GetInstance();
244     ASSERT_NE(mock_iso_manager_, nullptr);
245 
246     ON_CALL(*mock_iso_manager_, CreateBig)
247             .WillByDefault([this](uint8_t big_id, big_create_params p) {
248               auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
249                                       [big_id](auto const& entry) {
250                                         return entry.second->GetAdvertisingSid() == big_id;
251                                       });
252               if (bit == broadcasts_.end()) {
253                 return;
254               }
255 
256               big_create_cmpl_evt evt;
257               evt.big_id = big_id;
258 
259               // For test convenience lets encode big_id into conn_hdl MSB.
260               // NOTE: In current implementation big_id is equal to advertising SID.
261               //       This is an important detail exploited by the IsoManager mock
262               static uint8_t conn_lsb = 1;
263               uint16_t conn_msb = ((uint16_t)big_id) << 8;
264               for (auto i = 0; i < p.num_bis; ++i) {
265                 evt.conn_handles.push_back(conn_msb | conn_lsb++);
266               }
267 
268               bit->second->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT, &evt);
269             });
270 
271     ON_CALL(*mock_iso_manager_, SetupIsoDataPath)
272             .WillByDefault([this](uint16_t conn_handle, iso_data_path_params /*p*/) {
273               // Get the big_id encoded in conn_handle's MSB
274               uint8_t big_id = conn_handle >> 8;
275               auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
276                                       [big_id](auto const& entry) {
277                                         return entry.second->GetAdvertisingSid() == big_id;
278                                       });
279               if (bit == broadcasts_.end()) {
280                 return;
281               }
282               bit->second->OnSetupIsoDataPath(0, conn_handle);
283             });
284 
285     ON_CALL(*mock_iso_manager_, RemoveIsoDataPath)
286             .WillByDefault([this](uint16_t conn_handle, uint8_t /*iso_direction*/) {
287               // Get the big_id encoded in conn_handle's MSB
288               uint8_t big_id = conn_handle >> 8;
289               auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
290                                       [big_id](auto const& entry) {
291                                         return entry.second->GetAdvertisingSid() == big_id;
292                                       });
293               if (bit == broadcasts_.end()) {
294                 return;
295               }
296               bit->second->OnRemoveIsoDataPath(0, conn_handle);
297             });
298 
299     ON_CALL(*mock_iso_manager_, TerminateBig).WillByDefault([this](uint8_t big_id, uint8_t reason) {
300       // Get the big_id encoded in conn_handle's MSB
301       auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(), [big_id](auto const& entry) {
302         return entry.second->GetAdvertisingSid() == big_id;
303       });
304       if (bit == broadcasts_.end()) {
305         return;
306       }
307 
308       big_terminate_cmpl_evt evt;
309       evt.big_id = big_id;
310       evt.reason = reason;
311 
312       bit->second->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT, &evt);
313     });
314   }
315 
TearDown()316   void TearDown() override {
317     com::android::bluetooth::flags::provider_->reset_flags();
318     iso_manager_->Stop();
319     mock_iso_manager_ = nullptr;
320     Mock::VerifyAndClearExpectations(sm_callbacks_.get());
321     Mock::VerifyAndClearExpectations(adv_callbacks_.get());
322 
323     pending_broadcasts_.clear();
324     broadcasts_.clear();
325     sm_callbacks_.reset();
326     adv_callbacks_.reset();
327 
328     MockBleAdvertisingManager::CleanUp();
329     mock_ble_advertising_manager_ = nullptr;
330   }
331 
InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType context=bluetooth::le_audio::types::LeAudioContextType::UNSPECIFIED)332   uint32_t InstantiateStateMachine(
333           bluetooth::le_audio::types::LeAudioContextType context =
334                   bluetooth::le_audio::types::LeAudioContextType::UNSPECIFIED) {
335     // We will get the state machine create status update in an async callback
336     // so let's wait for it here.
337     instance_creation_promise_ = std::promise<uint32_t>();
338     std::future<uint32_t> instance_future = instance_creation_promise_.get_future();
339 
340     static uint8_t broadcast_id_lsb = 1;
341 
342     const std::vector<std::pair<types::LeAudioContextType, uint8_t>>& subgroup_quality = {
343             {context, 1}};
344     auto config = GetBroadcastConfig(subgroup_quality);
345     auto broadcast_id = broadcast_id_lsb++;
346     pending_broadcasts_.push_back(BroadcastStateMachine::CreateInstance({
347             .is_public = true,
348             .broadcast_id = broadcast_id,
349             .broadcast_name = test_broadcast_name,
350             .config = config,
351             // .announcement = ,
352             // .broadcast_code = ,
353     }));
354     pending_broadcasts_.back()->Initialize();
355     return instance_future.get();
356   }
357 
358   MockBleAdvertisingManager* mock_ble_advertising_manager_;
359   IsoManager* iso_manager_;
360   MockIsoManager* mock_iso_manager_;
361 
362   std::map<uint32_t, std::unique_ptr<BroadcastStateMachine>> broadcasts_;
363   std::vector<std::unique_ptr<BroadcastStateMachine>> pending_broadcasts_;
364   std::unique_ptr<MockBroadcastStatMachineCallbacks> sm_callbacks_;
365   std::unique_ptr<MockBroadcastAdvertisingCallbacks> adv_callbacks_;
366   std::promise<uint32_t> instance_creation_promise_;
367   std::promise<uint8_t> instance_destruction_promise_;
368 };
369 
TEST_F(StateMachineTest,CreateInstanceFailed)370 TEST_F(StateMachineTest, CreateInstanceFailed) {
371   EXPECT_CALL(*mock_ble_advertising_manager_, StartAdvertisingSet)
372           .WillOnce([this](uint8_t /*client_id*/, int /*reg_id*/,
373                            ::BleAdvertiserInterface::IdTxPowerStatusCallback /*register_cb*/,
374                            ::AdvertiseParameters /*params*/,
375                            std::vector<uint8_t> /*advertise_data*/,
376                            std::vector<uint8_t> /*scan_response_data*/,
377                            ::PeriodicAdvertisingParameters /*periodic_params*/,
378                            std::vector<uint8_t> /*periodic_data*/, uint16_t /*duration*/,
379                            uint8_t /*maxExtAdvEvents*/,
380                            ::BleAdvertiserInterface::IdStatusCallback /*timeout_cb*/) {
381             uint8_t advertiser_id = 1;
382             uint8_t tx_power = 0;
383             uint8_t status = 1;
384             this->adv_callbacks_->OnAdvertisingSetStarted(
385                     BroadcastStateMachine::kLeAudioBroadcastRegId, advertiser_id, tx_power, status);
386           });
387 
388   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, false)).Times(1);
389 
390   auto broadcast_id = InstantiateStateMachine();
391   ASSERT_NE(broadcast_id, BroadcastStateMachine::kAdvSidUndefined);
392   ASSERT_TRUE(pending_broadcasts_.empty());
393   ASSERT_TRUE(broadcasts_.empty());
394 }
395 
TEST_F(StateMachineTest,CreateInstanceSuccess)396 TEST_F(StateMachineTest, CreateInstanceSuccess) {
397   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
398 
399   auto broadcast_id = InstantiateStateMachine();
400   ASSERT_NE(broadcast_id, BroadcastStateMachine::kAdvSidUndefined);
401   ASSERT_TRUE(pending_broadcasts_.empty());
402   ASSERT_FALSE(broadcasts_.empty());
403   ASSERT_EQ(broadcasts_[broadcast_id]->GetBroadcastId(), broadcast_id);
404   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
405 }
406 
TEST_F(StateMachineTest,DestroyInstanceSuccess)407 TEST_F(StateMachineTest, DestroyInstanceSuccess) {
408   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
409 
410   auto broadcast_id = InstantiateStateMachine();
411   ASSERT_NE(broadcast_id, BroadcastStateMachine::kAdvSidUndefined);
412   ASSERT_FALSE(broadcasts_.empty());
413 
414   instance_destruction_promise_ = std::promise<uint8_t>();
415   std::future<uint8_t> instance_future = instance_destruction_promise_.get_future();
416 
417   broadcasts_.clear();
418   EXPECT_EQ(instance_future.get(), broadcast_id);
419 }
420 
TEST_F(StateMachineTest,GetAdvertisingAddress)421 TEST_F(StateMachineTest, GetAdvertisingAddress) {
422   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
423 
424   auto broadcast_id = InstantiateStateMachine();
425   EXPECT_CALL(*(sm_callbacks_.get()), OnOwnAddressResponse(broadcast_id, _, _)).Times(1);
426   broadcasts_[broadcast_id]->RequestOwnAddress();
427 }
428 
TEST_F(StateMachineTest,Mute)429 TEST_F(StateMachineTest, Mute) {
430   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
431 
432   auto broadcast_id = InstantiateStateMachine();
433   ASSERT_TRUE(pending_broadcasts_.empty());
434   ASSERT_FALSE(broadcasts_.empty());
435 
436   ASSERT_FALSE(broadcasts_[broadcast_id]->IsMuted());
437   broadcasts_[broadcast_id]->SetMuted(true);
438   ASSERT_TRUE(broadcasts_[broadcast_id]->IsMuted());
439   broadcasts_[broadcast_id]->SetMuted(false);
440   ASSERT_FALSE(broadcasts_[broadcast_id]->IsMuted());
441 }
442 
prepareAnnouncement(const BroadcastSubgroupCodecConfig & codec_config,std::map<uint8_t,std::vector<uint8_t>> metadata)443 static BasicAudioAnnouncementData prepareAnnouncement(
444         const BroadcastSubgroupCodecConfig& codec_config,
445         std::map<uint8_t, std::vector<uint8_t>> metadata) {
446   BasicAudioAnnouncementData announcement;
447 
448   announcement.presentation_delay_us = 40000;
449   auto const& codec_id = codec_config.GetLeAudioCodecId();
450   auto const subgroup_codec_spec = codec_config.GetCommonBisCodecSpecData();
451 
452   announcement.subgroup_configs = {{
453           .codec_config =
454                   {
455                           .codec_id = codec_id.coding_format,
456                           .vendor_company_id = codec_id.vendor_company_id,
457                           .vendor_codec_id = codec_id.vendor_codec_id,
458                           .codec_specific_params = subgroup_codec_spec.Values(),
459                   },
460           .metadata = std::move(metadata),
461           .bis_configs = {},
462   }};
463 
464   uint8_t bis_count = 0;
465   for (uint8_t bis_idx = 0; bis_idx < codec_config.GetAllBisConfigCount(); ++bis_idx) {
466     for (uint8_t bis_num = 0; bis_num < codec_config.GetNumBis(bis_idx); ++bis_num) {
467       ++bis_count;
468 
469       // Check for vendor byte array
470       bluetooth::le_audio::BasicAudioAnnouncementBisConfig bis_config;
471       auto vendor_config = codec_config.GetBisVendorCodecSpecData(bis_idx);
472       if (vendor_config) {
473         bis_config.vendor_codec_specific_params = vendor_config.value();
474       }
475 
476       // Check for non vendor LTVs
477       auto config_ltv = codec_config.GetBisCodecSpecData(bis_num, bis_idx);
478       if (config_ltv) {
479         bis_config.codec_specific_params = config_ltv->Values();
480       }
481 
482       // Internally BISes are indexed from 0 in each subgroup, but the BT spec
483       // requires the indices to be indexed from 1 in the entire BIG.
484       bis_config.bis_index = bis_count;
485       announcement.subgroup_configs[0].bis_configs.push_back(std::move(bis_config));
486     }
487   }
488 
489   return announcement;
490 }
491 
TEST_F(StateMachineTest,UpdateAnnouncement)492 TEST_F(StateMachineTest, UpdateAnnouncement) {
493   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
494 
495   auto broadcast_id = InstantiateStateMachine();
496   auto adv_sid = broadcasts_[broadcast_id]->GetAdvertisingSid();
497   std::vector<uint8_t> data;
498   EXPECT_CALL(*mock_ble_advertising_manager_, SetPeriodicAdvertisingData(adv_sid, _, _))
499           .Times(2)
500           .WillRepeatedly(SaveArg<1>(&data));
501 
502   std::map<uint8_t, std::vector<uint8_t>> metadata = {};
503   auto codec_config = lc3_mono_16_2;
504   auto announcement = prepareAnnouncement(codec_config, metadata);
505   broadcasts_[broadcast_id]->UpdateBroadcastAnnouncement(std::move(announcement));
506 
507   uint8_t first_len = data.size();
508   ASSERT_NE(first_len, 0);  // Non-zero length
509   ASSERT_EQ(data[1], BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE);
510   ASSERT_EQ(data[2], (kBasicAudioAnnouncementServiceUuid & 0x00FF));
511   ASSERT_EQ(data[3], ((kBasicAudioAnnouncementServiceUuid >> 8) & 0x00FF));
512   // The rest of the packet data is already covered by the announcement tests
513 
514   // Verify that changes in the announcement makes a difference
515   metadata = {{0x01, {0x03}}};
516   announcement = prepareAnnouncement(codec_config, metadata);
517   broadcasts_[broadcast_id]->UpdateBroadcastAnnouncement(std::move(announcement));
518   uint8_t second_len = data.size();
519 
520   // These should differ by the difference in metadata
521   ASSERT_EQ(first_len + types::LeAudioLtvMap(metadata).RawPacketSize(), second_len);
522 }
523 
TEST_F(StateMachineTest,UpdateBroadcastAnnouncementWithCallback)524 TEST_F(StateMachineTest, UpdateBroadcastAnnouncementWithCallback) {
525   com::android::bluetooth::flags::provider_->leaudio_broadcast_update_metadata_callback(true);
526 
527   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
528 
529   auto broadcast_id = InstantiateStateMachine();
530   auto adv_sid = broadcasts_[broadcast_id]->GetAdvertisingSid();
531 
532   EXPECT_CALL(*mock_ble_advertising_manager_, SetPeriodicAdvertisingData(adv_sid, _, _))
533           .Times(1)
534           .WillRepeatedly(testing::DoDefault());
535 
536   EXPECT_CALL(*(sm_callbacks_.get()), OnAnnouncementUpdated(broadcast_id)).Times(1);
537 
538   std::map<uint8_t, std::vector<uint8_t>> metadata = {};
539   auto codec_config = lc3_mono_16_2;
540   auto announcement = prepareAnnouncement(codec_config, metadata);
541   broadcasts_[broadcast_id]->UpdateBroadcastAnnouncement(announcement);
542 
543   ASSERT_EQ(announcement, broadcasts_[broadcast_id]->GetBroadcastAnnouncement());
544 }
545 
TEST_F(StateMachineTest,UpdatePublicBroadcastAnnouncementWithCallback)546 TEST_F(StateMachineTest, UpdatePublicBroadcastAnnouncementWithCallback) {
547   com::android::bluetooth::flags::provider_->leaudio_broadcast_update_metadata_callback(true);
548 
549   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
550 
551   auto broadcast_id = InstantiateStateMachine();
552   auto adv_sid = broadcasts_[broadcast_id]->GetAdvertisingSid();
553 
554   EXPECT_CALL(*mock_ble_advertising_manager_, SetData(adv_sid, _, _, _))
555           .Times(1)
556           .WillRepeatedly(testing::DoDefault());
557 
558   EXPECT_CALL(*(sm_callbacks_.get()), OnAnnouncementUpdated(broadcast_id)).Times(1);
559 
560   bool is_public_metadata_valid;
561   types::LeAudioLtvMap public_ltv = types::LeAudioLtvMap::Parse(
562           default_public_metadata.data(), default_public_metadata.size(), is_public_metadata_valid);
563   bluetooth::le_audio::PublicBroadcastAnnouncementData pb_announcement = {
564           .features = test_public_broadcast_features, .metadata = public_ltv.Values()};
565 
566   broadcasts_[broadcast_id]->UpdatePublicBroadcastAnnouncement(broadcast_id, test_broadcast_name,
567                                                                pb_announcement);
568 
569   ASSERT_EQ(pb_announcement, broadcasts_[broadcast_id]->GetPublicBroadcastAnnouncement());
570 }
571 
TEST_F(StateMachineTest,ProcessMessageStartWhenConfigured)572 TEST_F(StateMachineTest, ProcessMessageStartWhenConfigured) {
573   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
574 
575   auto sound_context = bluetooth::le_audio::types::LeAudioContextType::MEDIA;
576   uint8_t num_channels = 2;
577 
578   auto broadcast_id = InstantiateStateMachine(sound_context);
579   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
580 
581   uint8_t num_bises = 0;
582   EXPECT_CALL(*mock_iso_manager_, CreateBig)
583           .WillOnce([this, &num_bises](uint8_t big_id, big_create_params p) {
584             auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
585                                     [big_id](auto const& entry) {
586                                       return entry.second->GetAdvertisingSid() == big_id;
587                                     });
588             if (bit == broadcasts_.end()) {
589               return;
590             }
591 
592             num_bises = p.num_bis;
593 
594             big_create_cmpl_evt evt;
595             evt.big_id = big_id;
596 
597             // For test convenience lets encode big_id into conn_hdl's
598             // MSB
599             static uint8_t conn_lsb = 1;
600             uint16_t conn_msb = ((uint16_t)big_id) << 8;
601             for (auto i = 0; i < p.num_bis; ++i) {
602               evt.conn_handles.push_back(conn_msb | conn_lsb++);
603             }
604 
605             bit->second->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT, &evt);
606           });
607 
608   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(num_channels);
609   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
610   EXPECT_CALL(*(sm_callbacks_.get()),
611               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STREAMING, _))
612           .Times(1);
613   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
614 
615   // Verify the right number of BISes in the BIG being created
616   ASSERT_EQ(num_bises, num_channels);
617   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
618 }
619 
TEST_F(StateMachineTest,ProcessMessageStopWhenConfigured)620 TEST_F(StateMachineTest, ProcessMessageStopWhenConfigured) {
621   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
622 
623   auto broadcast_id =
624           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
625   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
626 
627   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
628   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
629   EXPECT_CALL(*(sm_callbacks_.get()),
630               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STOPPING, _))
631           .Times(1);
632   EXPECT_CALL(*(sm_callbacks_.get()),
633               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STOPPED, _))
634           .Times(1);
635   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
636 
637   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
638 }
639 
TEST_F(StateMachineTest,ProcessMessageSuspendWhenConfigured)640 TEST_F(StateMachineTest, ProcessMessageSuspendWhenConfigured) {
641   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
642 
643   auto broadcast_id =
644           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
645   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
646 
647   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
648   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
649   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
650   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
651   // There shall be no change in state
652   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
653 }
654 
TEST_F(StateMachineTest,ProcessMessageSuspendWhenConfiguredLateBigCreateCompleteEvent)655 TEST_F(StateMachineTest, ProcessMessageSuspendWhenConfiguredLateBigCreateCompleteEvent) {
656   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
657 
658   auto broadcast_id =
659           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
660   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
661 
662   /* Hold start process on BIG create */
663   EXPECT_CALL(*mock_iso_manager_, CreateBig(_, _)).WillOnce(Return());
664   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
665 
666   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::ENABLING);
667 
668   EXPECT_CALL(*mock_iso_manager_, TerminateBig(_, _)).Times(1);
669   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
670 
671   /* Inject late BIG create complete event */
672   big_create_cmpl_evt evt;
673   evt.big_id = broadcasts_[broadcast_id]->GetAdvertisingSid();
674   broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT, &evt);
675 
676   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
677   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
678   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
679   // There shall be no change in state
680   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
681 }
682 
TEST_F(StateMachineTest,ProcessMessageSuspendWhenConfiguredLateIsoDataPathSetUp)683 TEST_F(StateMachineTest, ProcessMessageSuspendWhenConfiguredLateIsoDataPathSetUp) {
684   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
685 
686   auto broadcast_id =
687           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
688   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
689 
690   /* Hold start process on Setup Iso Data Path BIG create */
691   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).WillOnce(Return());
692   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
693 
694   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::ENABLING);
695 
696   EXPECT_CALL(*mock_iso_manager_, TerminateBig(_, _)).Times(1);
697   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
698 
699   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
700   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
701   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
702   // There shall be no change in state
703   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
704 }
705 
TEST_F(StateMachineTest,ProcessMessageDoubleResumeWhenConfiguredLateBigCreateCompleteEvent)706 TEST_F(StateMachineTest, ProcessMessageDoubleResumeWhenConfiguredLateBigCreateCompleteEvent) {
707   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
708 
709   auto broadcast_id =
710           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
711   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
712 
713   /* Hold start process on BIG create */
714   EXPECT_CALL(*mock_iso_manager_, CreateBig(_, _)).WillOnce(Return());
715   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
716 
717   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::ENABLING);
718 
719   EXPECT_CALL(*mock_iso_manager_, TerminateBig(_, _)).Times(0);
720   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
721 
722   /* Broadcast is resumed again before getting BIG created event */
723   EXPECT_CALL(*(sm_callbacks_.get()),
724               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STREAMING, _))
725           .Times(1);
726   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
727 
728   /* Inject late BIG create complete event */
729   // For test convenience lets encode big_id into conn_hdl MSB.
730   // NOTE: In current implementation big_id is equal to advertising SID.
731   //       This is an important detail exploited by the IsoManager mock
732   static uint8_t conn_lsb = 1;
733   uint16_t conn_msb = ((uint16_t)broadcasts_[broadcast_id]->GetAdvertisingSid()) << 8;
734 
735   big_create_cmpl_evt evt;
736   evt.big_id = broadcasts_[broadcast_id]->GetAdvertisingSid();
737   evt.conn_handles.push_back(conn_msb | conn_lsb++);
738   broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT, &evt);
739 
740   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
741   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
742   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
743 
744   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
745 }
746 
TEST_F(StateMachineTest,ProcessMessageStartWhenStreaming)747 TEST_F(StateMachineTest, ProcessMessageStartWhenStreaming) {
748   auto broadcast_id =
749           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
750 
751   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
752   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
753 
754   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
755   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
756   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
757   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
758 
759   // There shall be no change in state
760   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
761 }
762 
TEST_F(StateMachineTest,ProcessMessageStopWhenStreaming)763 TEST_F(StateMachineTest, ProcessMessageStopWhenStreaming) {
764   auto broadcast_id =
765           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
766 
767   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
768   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
769 
770   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
771   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(2);
772   EXPECT_CALL(*(sm_callbacks_.get()),
773               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STOPPING, _))
774           .Times(1);
775   EXPECT_CALL(*(sm_callbacks_.get()),
776               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STOPPED, _))
777           .Times(1);
778   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
779 
780   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
781 }
782 
TEST_F(StateMachineTest,ProcessMessageSuspendWhenStreaming)783 TEST_F(StateMachineTest, ProcessMessageSuspendWhenStreaming) {
784   auto broadcast_id =
785           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
786 
787   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
788   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
789 
790   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
791   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(2);
792   EXPECT_CALL(*(sm_callbacks_.get()),
793               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::CONFIGURED, _))
794           .Times(1);
795   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
796 
797   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
798 }
799 
TEST_F(StateMachineTest,ProcessMessageStartWhenStopped)800 TEST_F(StateMachineTest, ProcessMessageStartWhenStopped) {
801   auto broadcast_id =
802           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
803 
804   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
805   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
806 
807   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(2);
808   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
809   EXPECT_CALL(*(sm_callbacks_.get()),
810               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::CONFIGURING, _))
811           .Times(1);
812   EXPECT_CALL(*(sm_callbacks_.get()),
813               OnStateMachineEvent(broadcast_id, BroadcastStateMachine::State::STREAMING, _))
814           .Times(1);
815   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
816 
817   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
818 }
819 
TEST_F(StateMachineTest,ProcessMessageStopWhenStopped)820 TEST_F(StateMachineTest, ProcessMessageStopWhenStopped) {
821   auto broadcast_id =
822           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
823 
824   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
825   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
826 
827   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
828   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
829   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
830   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
831 
832   // There shall be no change in state
833   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
834 }
835 
TEST_F(StateMachineTest,ProcessMessageSuspendWhenStopped)836 TEST_F(StateMachineTest, ProcessMessageSuspendWhenStopped) {
837   auto broadcast_id =
838           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
839 
840   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::STOP);
841   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
842 
843   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(0);
844   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath).Times(0);
845   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineEvent(broadcast_id, _, _)).Times(0);
846   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
847 
848   // There shall be no change in state
849   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STOPPED);
850 }
851 
TEST_F(StateMachineTest,OnSetupIsoDataPathError)852 TEST_F(StateMachineTest, OnSetupIsoDataPathError) {
853   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
854 
855   auto broadcast_id =
856           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
857   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
858 
859   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath)
860           .WillOnce([this](uint16_t conn_handle, iso_data_path_params /*p*/) {
861             // Get the big_id encoded in conn_handle's MSB
862             uint8_t big_id = conn_handle >> 8;
863             auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
864                                     [big_id](auto const& entry) {
865                                       return entry.second->GetAdvertisingSid() == big_id;
866                                     });
867             if (bit == broadcasts_.end()) {
868               return;
869             }
870             bit->second->OnSetupIsoDataPath(0, conn_handle);
871           })
872           .WillOnce([this](uint16_t conn_handle, iso_data_path_params /*p*/) {
873             // Get the big_id encoded in conn_handle's MSB
874             uint8_t big_id = conn_handle >> 8;
875             auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
876                                     [big_id](auto const& entry) {
877                                       return entry.second->GetAdvertisingSid() == big_id;
878                                     });
879             if (bit == broadcasts_.end()) {
880               return;
881             }
882             bit->second->OnSetupIsoDataPath(1, conn_handle);
883           })
884           .RetiresOnSaturation();
885   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
886 
887   // On datapath setup failure we should go back to configured with BIG being
888   // destroyed. Maybe it will work out next time for the new BIG.
889   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
890 
891   // And still be able to start again
892   ON_CALL(*mock_iso_manager_, SetupIsoDataPath)
893           .WillByDefault([this](uint16_t conn_handle, iso_data_path_params /*p*/) {
894             // Get the big_id encoded in conn_handle's MSB
895             uint8_t big_id = conn_handle >> 8;
896             auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
897                                     [big_id](auto const& entry) {
898                                       return entry.second->GetAdvertisingSid() == big_id;
899                                     });
900             if (bit == broadcasts_.end()) {
901               return;
902             }
903             bit->second->OnSetupIsoDataPath(0, conn_handle);
904           });
905   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath).Times(2);
906 
907   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
908   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
909 }
910 
TEST_F(StateMachineTest,OnRemoveIsoDataPathError)911 TEST_F(StateMachineTest, OnRemoveIsoDataPathError) {
912   auto broadcast_id =
913           InstantiateStateMachine(bluetooth::le_audio::types::LeAudioContextType::MEDIA);
914 
915   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
916   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
917 
918   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath)
919           .WillOnce([this](uint16_t conn_handle, uint8_t /*iso_direction*/) {
920             // Get the big_id encoded in conn_handle's MSB
921             uint8_t big_id = conn_handle >> 8;
922             auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
923                                     [big_id](auto const& entry) {
924                                       return entry.second->GetAdvertisingSid() == big_id;
925                                     });
926             if (bit == broadcasts_.end()) {
927               return;
928             }
929             bit->second->OnRemoveIsoDataPath(0, conn_handle);
930           })
931           .WillOnce([this](uint16_t conn_handle, uint8_t /*iso_direction*/) {
932             // Get the big_id encoded in conn_handle's MSB
933             uint8_t big_id = conn_handle >> 8;
934             auto bit = std::find_if(broadcasts_.begin(), broadcasts_.end(),
935                                     [big_id](auto const& entry) {
936                                       return entry.second->GetAdvertisingSid() == big_id;
937                                     });
938             if (bit == broadcasts_.end()) {
939               return;
940             }
941             bit->second->OnRemoveIsoDataPath(1, conn_handle);
942           })
943           .RetiresOnSaturation();
944   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::SUSPEND);
945 
946   // On datapath teardown failure we should stay in CONFIGURED with BIG being
947   // destroyed.
948   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
949 
950   // And still be able to start again
951   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
952   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
953 }
954 
TEST_F(StateMachineTest,GetConfig)955 TEST_F(StateMachineTest, GetConfig) {
956   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
957 
958   auto sound_context = bluetooth::le_audio::types::LeAudioContextType::MEDIA;
959   uint8_t num_channels = 2;
960 
961   auto broadcast_id = InstantiateStateMachine(sound_context);
962   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
963 
964   std::optional<BigConfig> const& big_cfg = broadcasts_[broadcast_id]->GetBigConfig();
965   ASSERT_FALSE(big_cfg.has_value());
966 
967   broadcasts_[broadcast_id]->ProcessMessage(BroadcastStateMachine::Message::START);
968   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::STREAMING);
969 
970   ASSERT_TRUE(big_cfg.has_value());
971   ASSERT_EQ(big_cfg->status, 0);
972   // This is an implementation specific thing
973   ASSERT_EQ(big_cfg->big_id, broadcasts_[broadcast_id]->GetAdvertisingSid());
974   ASSERT_EQ(big_cfg->connection_handles.size(), num_channels);
975 }
976 
TEST_F(StateMachineTest,GetBroadcastId)977 TEST_F(StateMachineTest, GetBroadcastId) {
978   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
979 
980   auto broadcast_id = InstantiateStateMachine();
981   ASSERT_NE(bluetooth::le_audio::kBroadcastIdInvalid, broadcast_id);
982   ASSERT_EQ(broadcasts_[broadcast_id]->GetState(), BroadcastStateMachine::State::CONFIGURED);
983 }
984 
TEST_F(StateMachineTest,IsPublicBroadcast)985 TEST_F(StateMachineTest, IsPublicBroadcast) {
986   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
987 
988   auto broadcast_id = InstantiateStateMachine();
989   ASSERT_EQ(broadcasts_[broadcast_id]->IsPublicBroadcast(), true);
990 }
991 
TEST_F(StateMachineTest,GetBroadcastName)992 TEST_F(StateMachineTest, GetBroadcastName) {
993   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
994 
995   auto broadcast_id = InstantiateStateMachine();
996   ASSERT_EQ(broadcasts_[broadcast_id]->GetBroadcastName(), test_broadcast_name);
997 }
998 
TEST_F(StateMachineTest,GetBroadcastAnnouncement)999 TEST_F(StateMachineTest, GetBroadcastAnnouncement) {
1000   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
1001 
1002   auto broadcast_id = InstantiateStateMachine();
1003   std::map<uint8_t, std::vector<uint8_t>> metadata = {};
1004   auto codec_config = lc3_mono_16_2;
1005   auto announcement = prepareAnnouncement(codec_config, metadata);
1006   broadcasts_[broadcast_id]->UpdateBroadcastAnnouncement(announcement);
1007 
1008   ASSERT_EQ(announcement, broadcasts_[broadcast_id]->GetBroadcastAnnouncement());
1009 }
1010 
TEST_F(StateMachineTest,GetPublicBroadcastAnnouncement)1011 TEST_F(StateMachineTest, GetPublicBroadcastAnnouncement) {
1012   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
1013 
1014   auto broadcast_id = InstantiateStateMachine();
1015   bool is_public_metadata_valid;
1016   types::LeAudioLtvMap public_ltv = types::LeAudioLtvMap::Parse(
1017           default_public_metadata.data(), default_public_metadata.size(), is_public_metadata_valid);
1018   bluetooth::le_audio::PublicBroadcastAnnouncementData pb_announcement = {
1019           .features = test_public_broadcast_features, .metadata = public_ltv.Values()};
1020 
1021   broadcasts_[broadcast_id]->UpdatePublicBroadcastAnnouncement(broadcast_id, test_broadcast_name,
1022                                                                pb_announcement);
1023 
1024   ASSERT_EQ(pb_announcement, broadcasts_[broadcast_id]->GetPublicBroadcastAnnouncement());
1025 }
1026 
TEST_F(StateMachineTest,AnnouncementTest)1027 TEST_F(StateMachineTest, AnnouncementTest) {
1028   ::AdvertiseParameters adv_params;
1029   std::vector<uint8_t> a_data;
1030   std::vector<uint8_t> p_data;
1031 
1032   EXPECT_CALL(*mock_ble_advertising_manager_, StartAdvertisingSet)
1033           .WillOnce([this, &p_data, &a_data, &adv_params](
1034                             uint8_t /*client_id*/, int /*reg_id*/,
1035                             ::BleAdvertiserInterface::IdTxPowerStatusCallback /*register_cb*/,
1036                             ::AdvertiseParameters params, std::vector<uint8_t> advertise_data,
1037                             std::vector<uint8_t> /*scan_response_data*/,
1038                             ::PeriodicAdvertisingParameters /*periodic_params*/,
1039                             std::vector<uint8_t> periodic_data, uint16_t /*duration*/,
1040                             uint8_t /*maxExtAdvEvents*/,
1041                             ::BleAdvertiserInterface::IdStatusCallback /*timeout_cb*/) {
1042             uint8_t advertiser_id = 1;
1043             uint8_t tx_power = 0;
1044             uint8_t status = 0;
1045 
1046             // Since we are not using these buffers in this callback it is safe to
1047             // move them.
1048             a_data = std::move(advertise_data);
1049             p_data = std::move(periodic_data);
1050 
1051             adv_params = params;
1052 
1053             this->adv_callbacks_->OnAdvertisingSetStarted(
1054                     BroadcastStateMachine::kLeAudioBroadcastRegId, advertiser_id, tx_power, status);
1055           });
1056 
1057   EXPECT_CALL(*(sm_callbacks_.get()), OnStateMachineCreateStatus(_, true)).Times(1);
1058 
1059   auto broadcast_id = InstantiateStateMachine();
1060   ASSERT_NE(broadcast_id, BroadcastStateMachine::kAdvSidUndefined);
1061 
1062   // Check ext. advertising data for Broadcast Announcement UUID
1063   ASSERT_NE(a_data[0], 0);     // size
1064   ASSERT_EQ(a_data[1], 0x16);  // BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE
1065   ASSERT_EQ(a_data[2], (kBroadcastAudioAnnouncementServiceUuid & 0x00FF));
1066   ASSERT_EQ(a_data[3], ((kBroadcastAudioAnnouncementServiceUuid >> 8) & 0x00FF));
1067   ASSERT_EQ(a_data[4], (broadcast_id & 0x0000FF));
1068   ASSERT_EQ(a_data[5], ((broadcast_id >> 8) & 0x0000FF));
1069   ASSERT_EQ(a_data[6], ((broadcast_id >> 16) & 0x0000FF));
1070 
1071   ASSERT_NE(a_data[7], 0);     // size
1072   ASSERT_EQ(a_data[8], 0x16);  // BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE
1073   ASSERT_EQ(a_data[9], (kPublicBroadcastAnnouncementServiceUuid & 0x00FF));
1074   ASSERT_EQ(a_data[10], ((kPublicBroadcastAnnouncementServiceUuid >> 8) & 0x00FF));
1075 
1076   // Check periodic data for Basic Announcement UUID
1077   ASSERT_NE(p_data[0], 0);     // size
1078   ASSERT_EQ(p_data[1], 0x16);  // BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE
1079   ASSERT_EQ(p_data[2], (kBasicAudioAnnouncementServiceUuid & 0x00FF));
1080   ASSERT_EQ(p_data[3], ((kBasicAudioAnnouncementServiceUuid >> 8) & 0x00FF));
1081 
1082   // Check advertising parameters
1083   ASSERT_EQ(adv_params.own_address_type, BroadcastStateMachine::kBroadcastAdvertisingType);
1084 }
1085 
TEST_F(StateMachineTest,GetMetadataBeforeGettingAddress)1086 TEST_F(StateMachineTest, GetMetadataBeforeGettingAddress) {
1087   unsigned int broadcast_id = 0;
1088 
1089   ::BleAdvertiserInterface::GetAddressCallback cb;
1090 
1091   /* Address should be already known after notifying callback recipients */
1092   EXPECT_CALL(*(sm_callbacks_.get()),
1093               OnStateMachineEvent(_, BroadcastStateMachine::State::CONFIGURED, _))
1094           .WillOnce([this](uint32_t broadcast_id, BroadcastStateMachine::State /*state*/,
1095                            const void* /*data*/) {
1096             RawAddress test_address;
1097 
1098             RawAddress::FromString("00:00:00:00:00:00", test_address);
1099             ASSERT_NE(test_address, this->broadcasts_[broadcast_id]->GetOwnAddress());
1100           });
1101 
1102   broadcast_id = InstantiateStateMachine();
1103   ASSERT_NE(broadcast_id, 0u);
1104   ASSERT_TRUE(pending_broadcasts_.empty());
1105   ASSERT_FALSE(broadcasts_.empty());
1106   ASSERT_TRUE(broadcasts_[broadcast_id]->GetBroadcastId() == broadcast_id);
1107 }
1108 
1109 }  // namespace
1110 }  // namespace broadcaster
1111 }  // namespace bluetooth::le_audio
1112