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