• 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 "bta/le_audio/broadcaster/state_machine.h"
19 
20 #include <bind_helpers.h>
21 #include <bluetooth/log.h>
22 
23 #include <algorithm>
24 #include <array>
25 #include <cstdint>
26 #include <functional>
27 #include <iostream>
28 #include <iterator>
29 #include <memory>
30 #include <optional>
31 #include <string>
32 #include <utility>
33 #include <vector>
34 
35 #include "base/functional/bind.h"
36 #include "base/functional/callback.h"
37 #include "bta/le_audio/broadcaster/broadcaster_types.h"
38 #include "bta/le_audio/le_audio_types.h"
39 #include "btm_api_types.h"
40 #include "btm_iso_api_types.h"
41 #include "common/strings.h"
42 #include "hardware/ble_advertiser.h"
43 #include "hardware/bt_le_audio.h"
44 #include "hci/le_advertising_manager.h"
45 #include "hcidefs.h"
46 #include "main/shim/le_advertising_manager.h"
47 #include "stack/include/btm_iso_api.h"
48 #include "types/raw_address.h"
49 
50 using bluetooth::common::ToString;
51 using bluetooth::hci::IsoManager;
52 using bluetooth::hci::iso_manager::big_create_cmpl_evt;
53 using bluetooth::hci::iso_manager::big_terminate_cmpl_evt;
54 
55 using namespace bluetooth::le_audio::broadcaster;
56 using namespace bluetooth;
57 
58 namespace {
59 
60 // Advertising channels. These should be kept the same as those defined in the
61 // stack.
62 const int kAdvertisingChannel37 = (1 << 0);
63 const int kAdvertisingChannel38 = (1 << 1);
64 const int kAdvertisingChannel39 = (1 << 2);
65 const int kAdvertisingChannelAll =
66         (kAdvertisingChannel37 | kAdvertisingChannel38 | kAdvertisingChannel39);
67 
68 class BroadcastStateMachineImpl : public BroadcastStateMachine {
69 public:
BroadcastStateMachineImpl(BroadcastStateMachineConfig msg)70   BroadcastStateMachineImpl(BroadcastStateMachineConfig msg)
71       : active_config_(std::nullopt), sm_config_(std::move(msg)) {}
72 
~BroadcastStateMachineImpl()73   ~BroadcastStateMachineImpl() {
74     if (GetState() == State::STREAMING) {
75       TerminateBig();
76     }
77     DestroyBroadcastAnnouncement();
78     if (callbacks_) {
79       callbacks_->OnStateMachineDestroyed(GetBroadcastId());
80     }
81   }
82 
Initialize()83   bool Initialize() override {
84     static constexpr uint8_t sNumBisMax = 31;
85 
86     if (sm_config_.config.GetNumBisTotal() > sNumBisMax) {
87       log::error(
88               "Channel count of {} exceeds the maximum number of possible BISes, "
89               "which is {}",
90               sm_config_.config.GetNumBisTotal(), sNumBisMax);
91       return false;
92     }
93 
94     CreateBroadcastAnnouncement(sm_config_.is_public, sm_config_.broadcast_name,
95                                 sm_config_.broadcast_id, sm_config_.public_announcement,
96                                 sm_config_.announcement, sm_config_.streaming_phy);
97     return true;
98   }
99 
GetCodecConfig() const100   const std::vector<BroadcastSubgroupCodecConfig>& GetCodecConfig() const override {
101     return sm_config_.config.subgroups;
102   }
103 
GetBroadcastConfig() const104   const BroadcastConfiguration& GetBroadcastConfig() const override { return sm_config_.config; }
105 
GetBigConfig() const106   std::optional<BigConfig> const& GetBigConfig() const override { return active_config_; }
107 
GetStateMachineConfig() const108   BroadcastStateMachineConfig const& GetStateMachineConfig() const override { return sm_config_; }
109 
RequestOwnAddress(base::Callback<void (uint8_t,RawAddress)> cb)110   void RequestOwnAddress(
111           base::Callback<void(uint8_t /* address_type*/, RawAddress /*address*/)> cb) override {
112     uint8_t advertising_sid = GetAdvertisingSid();
113     advertiser_if_->GetOwnAddress(advertising_sid, cb);
114   }
115 
RequestOwnAddress(void)116   void RequestOwnAddress(void) override {
117     auto broadcast_id = GetBroadcastId();
118     RequestOwnAddress(base::Bind(&IBroadcastStateMachineCallbacks::OnOwnAddressResponse,
119                                  base::Unretained(this->callbacks_), broadcast_id));
120   }
121 
GetOwnAddress()122   RawAddress GetOwnAddress() override { return addr_; }
123 
GetOwnAddressType()124   uint8_t GetOwnAddressType() override { return addr_type_; }
125 
GetBroadcastId() const126   bluetooth::le_audio::BroadcastId GetBroadcastId() const override {
127     return sm_config_.broadcast_id;
128   }
129 
GetBroadcastCode() const130   std::optional<bluetooth::le_audio::BroadcastCode> GetBroadcastCode() const override {
131     return sm_config_.broadcast_code;
132   }
133 
GetBroadcastAnnouncement() const134   const bluetooth::le_audio::BasicAudioAnnouncementData& GetBroadcastAnnouncement() const override {
135     return sm_config_.announcement;
136   }
137 
IsPublicBroadcast()138   bool IsPublicBroadcast() override { return sm_config_.is_public; }
139 
GetBroadcastName()140   std::string GetBroadcastName() override { return sm_config_.broadcast_name; }
141 
GetPublicBroadcastAnnouncement() const142   const bluetooth::le_audio::PublicBroadcastAnnouncementData& GetPublicBroadcastAnnouncement()
143           const override {
144     return sm_config_.public_announcement;
145   }
146 
OnCreateAnnouncement(uint8_t advertising_sid,int8_t tx_power,uint8_t status)147   void OnCreateAnnouncement(uint8_t advertising_sid, int8_t tx_power, uint8_t status) {
148     log::info("advertising_sid={} tx_power={} status={}", advertising_sid, tx_power, status);
149 
150     /* If this callback gets called the advertising_sid is valid even though the
151      * status can be other than SUCCESS.
152      */
153     advertising_sid_ = advertising_sid;
154 
155     if (status != bluetooth::hci::AdvertisingCallback::AdvertisingStatus::SUCCESS) {
156       log::error("Creating Announcement failed");
157       callbacks_->OnStateMachineCreateStatus(GetBroadcastId(), false);
158       return;
159     }
160 
161     advertiser_if_->GetOwnAddress(
162             advertising_sid,
163             base::Bind(&BroadcastStateMachineImpl::OnAddressResponse, base::Unretained(this)));
164   }
165 
OnEnableAnnouncement(bool enable,uint8_t status)166   void OnEnableAnnouncement(bool enable, uint8_t status) {
167     log::info("operation={}, broadcast_id={}, status={}", enable ? "enable" : "disable",
168               GetBroadcastId(), status);
169 
170     if (status == bluetooth::hci::AdvertisingCallback::AdvertisingStatus::SUCCESS) {
171       /* Periodic is enabled but without BIGInfo. Stream is suspended. */
172       if (enable) {
173         SetState(State::CONFIGURED);
174         /* Target state is always STREAMING state - start it now. */
175         ProcessMessage(Message::START);
176       } else {
177         /* User wanted to stop the announcement - report target state reached */
178         SetState(State::STOPPED);
179         callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
180       }
181     } else {
182       // Handle error case
183       if (enable) {
184         /* Error on enabling */
185         SetState(State::STOPPED);
186       } else {
187         /* Error on disabling */
188         SetState(State::CONFIGURED);
189       }
190       callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
191     }
192   }
193 
OnUpdateAnnouncement(uint8_t status)194   void OnUpdateAnnouncement(uint8_t status) {
195     log::info("broadcast_id={}, status={}", GetBroadcastId(), status);
196 
197     if (status == bluetooth::hci::AdvertisingCallback::AdvertisingStatus::SUCCESS) {
198       callbacks_->OnAnnouncementUpdated(GetBroadcastId());
199     } else {
200       log::error("Updating Announcement failed");
201     }
202   }
203 
UpdatePublicBroadcastAnnouncement(uint32_t broadcast_id,const std::string & broadcast_name,const bluetooth::le_audio::PublicBroadcastAnnouncementData & announcement)204   void UpdatePublicBroadcastAnnouncement(
205           uint32_t broadcast_id, const std::string& broadcast_name,
206           const bluetooth::le_audio::PublicBroadcastAnnouncementData& announcement) override {
207     std::vector<uint8_t> adv_data;
208     PrepareAdvertisingData(true, broadcast_name, broadcast_id, announcement, adv_data);
209 
210     sm_config_.broadcast_name = broadcast_name;
211     sm_config_.public_announcement = announcement;
212     advertiser_if_->SetData(advertising_sid_, false, adv_data, base::DoNothing());
213   }
214 
UpdateBroadcastAnnouncement(bluetooth::le_audio::BasicAudioAnnouncementData announcement)215   void UpdateBroadcastAnnouncement(
216           bluetooth::le_audio::BasicAudioAnnouncementData announcement) override {
217     std::vector<uint8_t> periodic_data;
218     PreparePeriodicData(announcement, periodic_data);
219 
220     sm_config_.announcement = std::move(announcement);
221     advertiser_if_->SetPeriodicAdvertisingData(advertising_sid_, periodic_data, base::DoNothing());
222   }
223 
ProcessMessage(Message msg,const void * data=nullptr)224   void ProcessMessage(Message msg, const void* data = nullptr) override {
225     log::info("broadcast_id={}, state={}, message={}", GetBroadcastId(), ToString(GetState()),
226               ToString(msg));
227     switch (msg) {
228       case Message::START:
229         start_msg_handlers[StateMachine::GetState()](data);
230         break;
231       case Message::STOP:
232         stop_msg_handlers[StateMachine::GetState()](data);
233         break;
234       case Message::SUSPEND:
235         suspend_msg_handlers[StateMachine::GetState()](data);
236         break;
237     };
238   }
239 
240   static IBroadcastStateMachineCallbacks* callbacks_;
241   static ::BleAdvertiserInterface* advertiser_if_;
242 
243 private:
244   std::optional<BigConfig> active_config_;
245   BroadcastStateMachineConfig sm_config_;
246 
247   /* Message handlers for each possible state */
248   typedef std::function<void(const void*)> msg_handler_t;
249   const std::array<msg_handler_t, BroadcastStateMachine::STATE_COUNT> start_msg_handlers{
250           /* in STOPPED state */
__anon1bc24a3d0202() 251           [this](const void*) {
252             SetState(State::CONFIGURING);
253             callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
254             EnableAnnouncement();
255           },
256           /* in CONFIGURING state */
__anon1bc24a3d0302() 257           [](const void*) { /* Do nothing */ },
258           /* in CONFIGURED state */
__anon1bc24a3d0402() 259           [this](const void*) {
260             SetState(State::ENABLING);
261             CreateBig();
262           },
263           /* in ENABLING state */
__anon1bc24a3d0502() 264           [](const void*) { /* Do nothing */ },
265           /* in DISABLING state */
__anon1bc24a3d0602() 266           [this](const void*) { SetState(State::ENABLING); },
267           /* in STOPPING state */
__anon1bc24a3d0702() 268           [](const void*) { /* Do nothing */ },
269           /* in STREAMING state */
__anon1bc24a3d0802() 270           [](const void*) { /* Do nothing */ }};
271 
272   const std::array<msg_handler_t, BroadcastStateMachine::STATE_COUNT> stop_msg_handlers{
273           /* in STOPPED state */
__anon1bc24a3d0902() 274           [](const void*) { /* Already stopped */ },
275           /* in CONFIGURING state */
__anon1bc24a3d0a02() 276           [](const void*) { /* Do nothing */ },
277           /* in CONFIGURED state */
__anon1bc24a3d0b02() 278           [this](const void*) {
279             SetState(State::STOPPING);
280             callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
281             DisableAnnouncement();
282           },
283           /* in ENABLING state */
__anon1bc24a3d0c02() 284           [this](const void*) {
285             SetState(State::STOPPING);
286             callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
287           },
288           /* in DISABLING state */
__anon1bc24a3d0d02() 289           [](const void*) { /* Do nothing */ },
290           /* in STOPPING state */
__anon1bc24a3d0e02() 291           [](const void*) { /* Do nothing */ },
292           /* in STREAMING state */
__anon1bc24a3d0f02() 293           [this](const void*) {
294             SetState(State::STOPPING);
295             callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState());
296             TriggerIsoDatapathTeardown(active_config_->connection_handles[0]);
297           }};
298 
299   const std::array<msg_handler_t, BroadcastStateMachine::STATE_COUNT> suspend_msg_handlers{
300           /* in STOPPED state */
__anon1bc24a3d1002() 301           [](const void*) { /* Do nothing */ },
302           /* in CONFIGURING state */
__anon1bc24a3d1102() 303           [](const void*) { /* Do nothing */ },
304           /* in CONFIGURED state */
__anon1bc24a3d1202() 305           [](const void*) { /* Already suspended */ },
306           /* in ENABLING state */
__anon1bc24a3d1302() 307           [this](const void*) {
308             SetState(State::DISABLING);
309 
310             if (active_config_ != std::nullopt) {
311               TerminateBig();
312             }
313           },
314           /* in DISABLING state */
__anon1bc24a3d1402() 315           [](const void*) { /* Do nothing */ },
316           /* in STOPPING state */
__anon1bc24a3d1502() 317           [](const void*) { /* Do nothing */ },
318           /* in STREAMING state */
__anon1bc24a3d1602() 319           [this](const void*) {
320             SetState(State::DISABLING);
321             TriggerIsoDatapathTeardown(active_config_->connection_handles[0]);
322           }};
323 
324   const std::array<msg_handler_t, BroadcastStateMachine::STATE_COUNT> resume_msg_handlers{
325           /* in STOPPED state */
__anon1bc24a3d1702() 326           [](const void*) { /* Do nothing */ },
327           /* in CONFIGURING state */
__anon1bc24a3d1802() 328           [](const void*) { /* Do nothing */ },
329           /* in CONFIGURED state */
__anon1bc24a3d1902() 330           [this](const void*) {
331             SetState(State::ENABLING);
332             CreateBig();
333           },
334           /* in ENABLING state */
__anon1bc24a3d1a02() 335           [](const void*) { /* Do nothing */ },
336           /* in DISABLING state */
__anon1bc24a3d1b02() 337           [](const void*) { /* Do nothing */ },
338           /* in STOPPING state */
__anon1bc24a3d1c02() 339           [](const void*) { /* Do nothing */ },
340           /* in STREAMING state */
__anon1bc24a3d1d02() 341           [](const void*) { /* Already streaming */ }};
342 
OnAddressResponse(uint8_t addr_type,RawAddress addr)343   void OnAddressResponse(uint8_t addr_type, RawAddress addr) {
344     log::info("own address={}, type={}", addr, addr_type);
345     addr_ = addr;
346     addr_type_ = addr_type;
347 
348     /* Ext. advertisings are already on */
349     SetState(State::CONFIGURED);
350 
351     callbacks_->OnStateMachineCreateStatus(GetBroadcastId(), true);
352     callbacks_->OnStateMachineEvent(GetBroadcastId(), State::CONFIGURED);
353   }
354 
CreateBroadcastAnnouncement(bool is_public,const std::string & broadcast_name,bluetooth::le_audio::BroadcastId & broadcast_id,const bluetooth::le_audio::PublicBroadcastAnnouncementData & public_announcement,const bluetooth::le_audio::BasicAudioAnnouncementData & announcement,uint8_t streaming_phy)355   void CreateBroadcastAnnouncement(
356           bool is_public, const std::string& broadcast_name,
357           bluetooth::le_audio::BroadcastId& broadcast_id,
358           const bluetooth::le_audio::PublicBroadcastAnnouncementData& public_announcement,
359           const bluetooth::le_audio::BasicAudioAnnouncementData& announcement,
360           uint8_t streaming_phy) {
361     log::info("is_public={}, broadcast_name={}, public_features={}",
362               is_public ? "public" : "non-public", broadcast_name, public_announcement.features);
363     if (advertiser_if_ != nullptr) {
364       ::AdvertiseParameters adv_params;
365       ::PeriodicAdvertisingParameters periodic_params;
366       std::vector<uint8_t> adv_data;
367       std::vector<uint8_t> periodic_data;
368 
369       PrepareAdvertisingData(is_public, broadcast_name, broadcast_id, public_announcement,
370                              adv_data);
371       PreparePeriodicData(announcement, periodic_data);
372 
373       adv_params.min_interval = 0x00A0; /* 160 * 0,625 = 100ms */
374       adv_params.max_interval = 0x0140; /* 320 * 0,625 = 200ms */
375       adv_params.advertising_event_properties = 0;
376       adv_params.channel_map = kAdvertisingChannelAll;
377       adv_params.tx_power = 8;
378       adv_params.primary_advertising_phy = PHY_LE_1M;
379       adv_params.secondary_advertising_phy = streaming_phy;
380       adv_params.scan_request_notification_enable = 0;
381       adv_params.own_address_type = kBroadcastAdvertisingType;
382 
383       periodic_params.max_interval = BroadcastStateMachine::kPaIntervalMax;
384       periodic_params.min_interval = BroadcastStateMachine::kPaIntervalMin;
385       periodic_params.periodic_advertising_properties = 0;
386       periodic_params.enable = true;
387 
388       /* Status and timeout callbacks are handled by OnAdvertisingSetStarted()
389        * which returns the status and handle to be used later in CreateBIG
390        * command.
391        */
392       advertiser_if_->StartAdvertisingSet(
393               kAdvertiserClientIdLeAudio, kLeAudioBroadcastRegId, base::DoNothing(), adv_params,
394               adv_data, std::vector<uint8_t>(), periodic_params, periodic_data, 0 /* duration */,
395               0 /* maxExtAdvEvents */, base::DoNothing());
396     }
397   }
398 
DestroyBroadcastAnnouncement()399   void DestroyBroadcastAnnouncement() { advertiser_if_->Unregister(GetAdvertisingSid()); }
400 
EnableAnnouncement()401   void EnableAnnouncement() {
402     log::info("broadcast_id={}", GetBroadcastId());
403     // Callback is handled by OnAdvertisingEnabled() which returns the status
404     advertiser_if_->Enable(GetAdvertisingSid(), true, base::DoNothing(), 0,
405                            0, /* Enable until stopped */
406                            base::DoNothing());
407   }
408 
CreateBig(void)409   void CreateBig(void) {
410     log::info("broadcast_id={}", GetBroadcastId());
411     /* TODO: Figure out how to decide on the currently hard-codded params. */
412     struct bluetooth::hci::iso_manager::big_create_params big_params = {
413             .adv_handle = GetAdvertisingSid(),
414             .num_bis = sm_config_.config.GetNumBisTotal(),
415             .sdu_itv = sm_config_.config.GetSduIntervalUs(),
416             .max_sdu_size = sm_config_.config.GetMaxSduOctets(),
417             .max_transport_latency = sm_config_.config.qos.getMaxTransportLatency(),
418             .rtn = sm_config_.config.qos.getRetransmissionNumber(),
419             .phy = sm_config_.streaming_phy,
420             .packing = 0x00, /* Sequencial */
421             .framing = 0x00, /* Unframed */
422             .enc = static_cast<uint8_t>(sm_config_.broadcast_code ? 1 : 0),
423             .enc_code = sm_config_.broadcast_code ? *sm_config_.broadcast_code
424                                                   : std::array<uint8_t, 16>({0}),
425     };
426 
427     IsoManager::GetInstance()->CreateBig(GetAdvertisingSid(), std::move(big_params));
428   }
429 
DisableAnnouncement(void)430   void DisableAnnouncement(void) {
431     log::info("broadcast_id={}", GetBroadcastId());
432     // Callback is handled by OnAdvertisingEnabled() which returns the status
433     advertiser_if_->Enable(GetAdvertisingSid(), false, base::DoNothing(), 0, 0, base::DoNothing());
434   }
435 
TerminateBig()436   void TerminateBig() {
437     log::info("disabling={}", GetState() == BroadcastStateMachine::State::DISABLING);
438     /* Terminate with reason: Remote User Terminated Connection */
439     IsoManager::GetInstance()->TerminateBig(GetAdvertisingSid(), 0x13);
440   }
441 
OnSetupIsoDataPath(uint8_t status,uint16_t conn_hdl)442   void OnSetupIsoDataPath(uint8_t status, uint16_t conn_hdl) override {
443     log::assert_that(active_config_ != std::nullopt,
444                      "assert failed: active_config_ != std::nullopt");
445 
446     if (status != 0) {
447       log::error("Failure creating data path. Tearing down the BIG now.");
448       SetState(State::DISABLING);
449       TerminateBig();
450       return;
451     }
452 
453     /* Look for the next BIS handle */
454     auto handle_it = std::find_if(active_config_->connection_handles.begin(),
455                                   active_config_->connection_handles.end(),
456                                   [conn_hdl](const auto& handle) { return conn_hdl == handle; });
457     log::assert_that(handle_it != active_config_->connection_handles.end(),
458                      "assert failed: handle_it != active_config_->connection_handles.end()");
459     handle_it = std::next(handle_it);
460 
461     if (handle_it == active_config_->connection_handles.end()) {
462       if (GetState() == BroadcastStateMachine::State::STOPPING) {
463         // All ISO setup completed, but we're in stopping state, we need to tear down all ISO
464         log::warn("ISO setup in stopping state. Tearing down ISO data path.");
465         // Remain in STOPPING, BIG will be terminated in OnRemoveIsoDataPath
466         TriggerIsoDatapathTeardown(active_config_->connection_handles[0]);
467         return;
468       }
469       /* It was the last BIS to set up - change state to streaming */
470       SetState(State::STREAMING);
471       callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState(), nullptr);
472     } else {
473       /* Note: We would feed a watchdog here if we had one */
474       /* There are more BISes to set up data path for */
475       log::info("There is more data paths to set up.");
476       TriggerIsoDatapathSetup(*handle_it);
477     }
478   }
479 
OnRemoveIsoDataPath(uint8_t status,uint16_t conn_handle)480   void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle) override {
481     log::assert_that(active_config_ != std::nullopt,
482                      "assert failed: active_config_ != std::nullopt");
483 
484     if (status != 0) {
485       log::error("Failure removing data path. Tearing down the BIG now.");
486       TerminateBig();
487       return;
488     }
489 
490     /* Look for the next BIS handle */
491     auto handle_it = std::find_if(
492             active_config_->connection_handles.begin(), active_config_->connection_handles.end(),
493             [conn_handle](const auto& handle) { return conn_handle == handle; });
494     log::assert_that(handle_it != active_config_->connection_handles.end(),
495                      "assert failed: handle_it != active_config_->connection_handles.end()");
496     handle_it = std::next(handle_it);
497 
498     if (handle_it == active_config_->connection_handles.end()) {
499       /* It was the last one to set up - start tearing down the BIG */
500       TerminateBig();
501     } else {
502       /* Note: We would feed a watchdog here if we had one */
503       /* There are more BISes to tear down data path for */
504       log::info("There is more data paths to tear down.");
505       TriggerIsoDatapathTeardown(*handle_it);
506     }
507   }
508 
TriggerIsoDatapathSetup(uint16_t conn_handle)509   void TriggerIsoDatapathSetup(uint16_t conn_handle) {
510     log::info("conn_hdl={}", conn_handle);
511     log::assert_that(active_config_ != std::nullopt,
512                      "assert failed: active_config_ != std::nullopt");
513 
514     /* Note: If coding format is transparent, 'codec_id_company' and
515      * 'codec_id_vendor' shall be ignored.
516      */
517     auto& iso_datapath_config = sm_config_.config.data_path.isoDataPathConfig;
518     bluetooth::hci::iso_manager::iso_data_path_params param = {
519             .data_path_dir = bluetooth::hci::iso_manager::kIsoDataPathDirectionIn,
520             .data_path_id = static_cast<uint8_t>(sm_config_.config.data_path.dataPathId),
521             .codec_id_format = static_cast<uint8_t>(
522                     iso_datapath_config.isTransparent ? bluetooth::hci::kIsoCodingFormatTransparent
523                                                       : iso_datapath_config.codecId.coding_format),
524             .codec_id_company =
525                     static_cast<uint16_t>(iso_datapath_config.isTransparent
526                                                   ? 0x0000
527                                                   : iso_datapath_config.codecId.vendor_company_id),
528             .codec_id_vendor =
529                     static_cast<uint16_t>(iso_datapath_config.isTransparent
530                                                   ? 0x0000
531                                                   : iso_datapath_config.codecId.vendor_codec_id),
532             .controller_delay = iso_datapath_config.controllerDelayUs,
533             .codec_conf = iso_datapath_config.configuration,
534     };
535     IsoManager::GetInstance()->SetupIsoDataPath(conn_handle, std::move(param));
536   }
537 
TriggerIsoDatapathTeardown(uint16_t conn_handle)538   void TriggerIsoDatapathTeardown(uint16_t conn_handle) {
539     log::info("conn_hdl={}", conn_handle);
540     log::assert_that(active_config_ != std::nullopt,
541                      "assert failed: active_config_ != std::nullopt");
542 
543     SetMuted(true);
544     IsoManager::GetInstance()->RemoveIsoDataPath(
545             conn_handle, bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput);
546   }
547 
HandleHciEvent(uint16_t event,void * data)548   void HandleHciEvent(uint16_t event, void* data) override {
549     switch (event) {
550       case HCI_BLE_CREATE_BIG_CPL_EVT: {
551         auto* evt = static_cast<big_create_cmpl_evt*>(data);
552 
553         if (evt->big_id != GetAdvertisingSid()) {
554           log::error("State={}, Event={}, Unknown big, big_id={}", ToString(GetState()), event,
555                      evt->big_id);
556           break;
557         }
558 
559         if (evt->status == 0x00) {
560           log::info("BIG create BIG complete, big_id={}", evt->big_id);
561           active_config_ = {
562                   .status = evt->status,
563                   .big_id = evt->big_id,
564                   .big_sync_delay = evt->big_sync_delay,
565                   .transport_latency_big = evt->transport_latency_big,
566                   .phy = evt->phy,
567                   .nse = evt->nse,
568                   .bn = evt->bn,
569                   .pto = evt->pto,
570                   .irc = evt->irc,
571                   .max_pdu = evt->max_pdu,
572                   .iso_interval = evt->iso_interval,
573                   .connection_handles = evt->conn_handles,
574           };
575 
576           if (GetState() == BroadcastStateMachine::State::DISABLING ||
577               GetState() == BroadcastStateMachine::State::STOPPING) {
578             log::info("Terminating BIG in state={}, big_id={}", ToString(GetState()), evt->big_id);
579             TerminateBig();
580           } else {
581             callbacks_->OnBigCreated(evt->conn_handles);
582             TriggerIsoDatapathSetup(evt->conn_handles[0]);
583           }
584         } else {
585           log::error("State={} Event={}. Unable to create big, big_id={}, status={}",
586                      ToString(GetState()), event, evt->big_id, evt->status);
587         }
588       } break;
589       case HCI_BLE_TERM_BIG_CPL_EVT: {
590         auto* evt = static_cast<big_terminate_cmpl_evt*>(data);
591 
592         log::info("BIG terminate BIG cmpl in state={}, reason={} big_id={}", ToString(GetState()),
593                   evt->reason, evt->big_id);
594 
595         if (evt->big_id != GetAdvertisingSid()) {
596           log::error("State={} Event={}, unknown adv.sid={}", ToString(GetState()), event,
597                      evt->big_id);
598           break;
599         }
600 
601         active_config_ = std::nullopt;
602         bool disabling = GetState() == BroadcastStateMachine::State::DISABLING;
603 
604         /* Go back to configured if BIG is inactive (we are still announcing) and state is not
605          * stopping*/
606         if (GetState() != BroadcastStateMachine::State::STOPPING) {
607           SetState(State::CONFIGURED);
608         }
609 
610         /* Check if we got this HCI event due to STOP or SUSPEND message. */
611         if (disabling) {
612           callbacks_->OnStateMachineEvent(GetBroadcastId(), GetState(), evt);
613         } else {
614           DisableAnnouncement();
615         }
616       } break;
617       default:
618         log::error("State={} Unknown event={}", ToString(GetState()), event);
619         break;
620     }
621   }
622 };
623 
624 IBroadcastStateMachineCallbacks* BroadcastStateMachineImpl::callbacks_ = nullptr;
625 ::BleAdvertiserInterface* BroadcastStateMachineImpl::advertiser_if_ = nullptr;
626 } /* namespace */
627 
CreateInstance(BroadcastStateMachineConfig msg)628 std::unique_ptr<BroadcastStateMachine> BroadcastStateMachine::CreateInstance(
629         BroadcastStateMachineConfig msg) {
630   return std::make_unique<BroadcastStateMachineImpl>(std::move(msg));
631 }
632 
Initialize(IBroadcastStateMachineCallbacks * callbacks,AdvertisingCallbacks * adv_callbacks)633 void BroadcastStateMachine::Initialize(IBroadcastStateMachineCallbacks* callbacks,
634                                        AdvertisingCallbacks* adv_callbacks) {
635   BroadcastStateMachineImpl::callbacks_ = callbacks;
636   /* Get gd le advertiser interface */
637   BroadcastStateMachineImpl::advertiser_if_ = bluetooth::shim::get_ble_advertiser_instance();
638   if (BroadcastStateMachineImpl::advertiser_if_ != nullptr) {
639     log::info("Advertiser_instance acquired");
640     BroadcastStateMachineImpl::advertiser_if_->RegisterCallbacksNative(adv_callbacks,
641                                                                        kAdvertiserClientIdLeAudio);
642   } else {
643     log::error("Could not acquire advertiser_instance!");
644     BroadcastStateMachineImpl::advertiser_if_ = nullptr;
645   }
646 }
647 
648 namespace bluetooth::le_audio {
649 namespace broadcaster {
650 
operator <<(std::ostream & os,const BroadcastStateMachine::Message & msg)651 std::ostream& operator<<(std::ostream& os, const BroadcastStateMachine::Message& msg) {
652   static const char* char_value_[BroadcastStateMachine::MESSAGE_COUNT] = {"START", "SUSPEND",
653                                                                           "STOP"};
654   os << char_value_[static_cast<uint8_t>(msg)];
655   return os;
656 }
657 
operator <<(std::ostream & os,const BroadcastStateMachine::State & state)658 std::ostream& operator<<(std::ostream& os, const BroadcastStateMachine::State& state) {
659   static const char* char_value_[BroadcastStateMachine::STATE_COUNT] = {
660           "STOPPED", "CONFIGURING", "CONFIGURED", "ENABLING", "DISABLING", "STOPPING", "STREAMING"};
661   os << char_value_[static_cast<uint8_t>(state)];
662   return os;
663 }
664 
operator <<(std::ostream & os,const bluetooth::le_audio::broadcaster::BigConfig & config)665 std::ostream& operator<<(std::ostream& os,
666                          const bluetooth::le_audio::broadcaster::BigConfig& config) {
667   os << "\n";
668   os << "        Status: 0x" << std::hex << +config.status << std::dec << "\n";
669   os << "        BIG ID: " << +config.big_id << "\n";
670   os << "        Sync delay: " << config.big_sync_delay << "\n";
671   os << "        Transport Latency: " << config.transport_latency_big << "\n";
672   os << "        Phy: " << +config.phy << "\n";
673   os << "        Nse: " << +config.nse << "\n";
674   os << "        Bn: " << +config.bn << "\n";
675   os << "        Pto: " << +config.pto << "\n";
676   os << "        Irc: " << +config.irc << "\n";
677   os << "        Max pdu: " << config.max_pdu << "\n";
678   os << "        Iso interval: " << config.iso_interval << "\n";
679   os << "        Connection handles (BISes): [";
680   for (auto& el : config.connection_handles) {
681     os << std::hex << +el << std::dec << ":";
682   }
683   os << "]";
684   return os;
685 }
686 
operator <<(std::ostream & os,const bluetooth::le_audio::broadcaster::BroadcastStateMachineConfig & config)687 std::ostream& operator<<(
688         std::ostream& os,
689         const bluetooth::le_audio::broadcaster::BroadcastStateMachineConfig& config) {
690   const char* const PHYS[] = {"NONE", "1M", "2M", "CODED"};
691 
692   os << "\n";
693   os << "        Broadcast ID: " << config.broadcast_id << "\n";
694   os << "        Streaming PHY: "
695      << ((config.streaming_phy > 3) ? std::to_string(config.streaming_phy)
696                                     : PHYS[config.streaming_phy])
697      << "\n";
698   os << "        Subgroups: {\n";
699   for (auto const& subgroup : config.config.subgroups) {
700     os << "          " << subgroup << "\n";
701   }
702   os << "        }\n";
703   os << "        Qos Config: " << config.config.qos << "\n";
704   if (config.broadcast_code) {
705     os << "        Broadcast Code: [";
706     for (auto& el : *config.broadcast_code) {
707       os << std::hex << +el << ":";
708     }
709     os << "]\n";
710   } else {
711     os << "        Broadcast Code: NONE\n";
712   }
713 
714   std::vector<uint8_t> an_raw;
715   ToRawPacket(config.announcement, an_raw);
716   os << "        Announcement RAW: [";
717   for (auto& el : an_raw) {
718     os << std::hex << +el << ":";
719   }
720   os << "]";
721 
722   return os;
723 }
724 
operator <<(std::ostream & os,const bluetooth::le_audio::broadcaster::BroadcastStateMachine & machine)725 std::ostream& operator<<(std::ostream& os,
726                          const bluetooth::le_audio::broadcaster::BroadcastStateMachine& machine) {
727   os << "    Broadcast state machine: {"
728      << "      Advertising SID: " << +machine.GetAdvertisingSid() << "\n"
729      << "      State: " << machine.GetState() << "\n";
730   os << "      State Machine Config: " << machine.GetStateMachineConfig() << "\n";
731 
732   if (machine.GetBigConfig()) {
733     os << "      BigConfig: " << *machine.GetBigConfig() << "\n";
734   } else {
735     os << "      BigConfig: NONE\n";
736   }
737   os << "    }\n";
738   return os;
739 }
740 
741 }  // namespace broadcaster
742 }  // namespace bluetooth::le_audio
743