• 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 <base/bind.h>
19 
20 #include "bta/include/bta_le_audio_api.h"
21 #include "bta/include/bta_le_audio_broadcaster_api.h"
22 #include "bta/le_audio/broadcaster/state_machine.h"
23 #include "bta/le_audio/le_audio_types.h"
24 #include "bta/le_audio/le_audio_utils.h"
25 #include "device/include/controller.h"
26 #include "embdrv/lc3/include/lc3.h"
27 #include "gd/common/strings.h"
28 #include "internal_include/stack_config.h"
29 #include "osi/include/log.h"
30 #include "osi/include/properties.h"
31 #include "stack/include/btm_api_types.h"
32 #include "stack/include/btm_iso_api.h"
33 
34 using bluetooth::common::ToString;
35 using bluetooth::hci::IsoManager;
36 using bluetooth::hci::iso_manager::big_create_cmpl_evt;
37 using bluetooth::hci::iso_manager::big_terminate_cmpl_evt;
38 using bluetooth::hci::iso_manager::BigCallbacks;
39 using bluetooth::le_audio::BasicAudioAnnouncementData;
40 using bluetooth::le_audio::BroadcastId;
41 using le_audio::CodecManager;
42 using le_audio::LeAudioCodecConfiguration;
43 using le_audio::LeAudioSourceAudioHalClient;
44 using le_audio::broadcaster::BigConfig;
45 using le_audio::broadcaster::BroadcastCodecWrapper;
46 using le_audio::broadcaster::BroadcastQosConfig;
47 using le_audio::broadcaster::BroadcastStateMachine;
48 using le_audio::broadcaster::BroadcastStateMachineConfig;
49 using le_audio::broadcaster::IBroadcastStateMachineCallbacks;
50 using le_audio::types::AudioContexts;
51 using le_audio::types::CodecLocation;
52 using le_audio::types::kLeAudioCodingFormatLC3;
53 using le_audio::types::LeAudioContextType;
54 using le_audio::types::LeAudioLtvMap;
55 using le_audio::utils::GetAllCcids;
56 using le_audio::utils::GetAllowedAudioContextsFromSourceMetadata;
57 
58 namespace {
59 class LeAudioBroadcasterImpl;
60 LeAudioBroadcasterImpl* instance;
61 
62 /* Class definitions */
63 
64 /* LeAudioBroadcasterImpl class represents main implementation class for le
65  * audio broadcaster feature in the stack.
66  *
67  * This class may be bonded with Test socket which allows to drive an instance
68  * for test purposes.
69  */
70 class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
71   enum class AudioDataPathState {
72     INACTIVE,
73     ACTIVE,
74     SUSPENDED,
75   };
76 
77  public:
LeAudioBroadcasterImpl(bluetooth::le_audio::LeAudioBroadcasterCallbacks * callbacks_)78   LeAudioBroadcasterImpl(
79       bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_)
80       : callbacks_(callbacks_),
81         current_phy_(PHY_LE_2M),
82         audio_data_path_state_(AudioDataPathState::INACTIVE),
83         le_audio_source_hal_client_(nullptr) {
84     LOG_INFO();
85 
86     /* Register State machine callbacks */
87     BroadcastStateMachine::Initialize(&state_machine_callbacks_);
88 
89     GenerateBroadcastIds();
90   }
91 
92   ~LeAudioBroadcasterImpl() override = default;
93 
GenerateBroadcastIds(void)94   void GenerateBroadcastIds(void) {
95     btsnd_hcic_ble_rand(base::Bind([](BT_OCTET8 rand) {
96       if (!instance) return;
97 
98       /* LE Rand returns 8 octets. Lets' make 2 outstanding Broadcast Ids out
99        * of it */
100       for (int i = 0; i < 8; i += 4) {
101         BroadcastId broadcast_id = 0;
102         /* Broadcast ID should be 3 octets long (BAP v1.0 spec.) */
103         STREAM_TO_UINT24(broadcast_id, rand);
104         if (broadcast_id == bluetooth::le_audio::kBroadcastIdInvalid) continue;
105         instance->available_broadcast_ids_.emplace_back(broadcast_id);
106       }
107 
108       if (instance->available_broadcast_ids_.empty()) {
109         LOG_ALWAYS_FATAL("Unable to generate proper broadcast identifiers.");
110       }
111     }));
112   }
113 
CleanUp()114   void CleanUp() {
115     LOG_INFO("Broadcaster");
116     broadcasts_.clear();
117     callbacks_ = nullptr;
118 
119     if (le_audio_source_hal_client_) {
120       le_audio_source_hal_client_->Stop();
121       le_audio_source_hal_client_.reset();
122     }
123   }
124 
Stop()125   void Stop() {
126     LOG_INFO("Broadcaster");
127 
128     for (auto& sm_pair : broadcasts_) {
129       StopAudioBroadcast(sm_pair.first);
130     }
131   }
132 
prepareAnnouncement(const BroadcastCodecWrapper & codec_config,LeAudioLtvMap metadata)133   static BasicAudioAnnouncementData prepareAnnouncement(
134       const BroadcastCodecWrapper& codec_config, LeAudioLtvMap metadata) {
135     BasicAudioAnnouncementData announcement;
136 
137     /* Prepare the announcement */
138     announcement.presentation_delay = 0x004E20; /* TODO: Use the proper value */
139 
140     auto const& codec_id = codec_config.GetLeAudioCodecId();
141 
142     /* Note: Currently we have a single audio source configured with a one
143      *       set of codec/pcm parameters thus we can use a single subgroup
144      *       for all the BISes. Configure common BIS codec params at the
145      *       subgroup level.
146      */
147     announcement.subgroup_configs = {{
148         .codec_config =
149             {
150                 .codec_id = codec_id.coding_format,
151                 .vendor_company_id = codec_id.vendor_company_id,
152                 .vendor_codec_id = codec_id.vendor_codec_id,
153                 .codec_specific_params =
154                     codec_config.GetSubgroupCodecSpecData().Values(),
155             },
156         .metadata = metadata.Values(),
157         .bis_configs = {},
158     }};
159 
160     /* BIS indices range is [1-31] - BASS, Sec.3.2 Broadcast Receive State. */
161     for (uint8_t i = 0; i < codec_config.GetNumChannels(); ++i) {
162       announcement.subgroup_configs[0].bis_configs.push_back(
163           {.codec_specific_params =
164                codec_config.GetBisCodecSpecData(i + 1).Values(),
165            .bis_index = static_cast<uint8_t>(i + 1)});
166     }
167 
168     return announcement;
169   }
170 
UpdateStreamingContextTypeOnAllSubgroups(const AudioContexts & contexts)171   void UpdateStreamingContextTypeOnAllSubgroups(const AudioContexts& contexts) {
172     LOG_DEBUG("%s context_type_map=%s", __func__, contexts.to_string().c_str());
173 
174     auto ccids = GetAllCcids(contexts);
175     if (ccids.empty()) {
176       LOG_WARN("%s No content providers available for context_type_map=%s.",
177                __func__, contexts.to_string().c_str());
178     }
179 
180     std::vector<uint8_t> stream_context_vec(2);
181     auto pp = stream_context_vec.data();
182     UINT16_TO_STREAM(pp, contexts.value());
183 
184     for (auto const& kv_it : broadcasts_) {
185       auto& broadcast = kv_it.second;
186       if (broadcast->GetState() == BroadcastStateMachine::State::STREAMING) {
187         auto announcement = broadcast->GetBroadcastAnnouncement();
188         bool broadcast_update = false;
189 
190         // Replace context type and CCID list
191         for (auto& subgroup : announcement.subgroup_configs) {
192           auto subgroup_ltv = LeAudioLtvMap(subgroup.metadata);
193           bool subgroup_update = false;
194 
195           auto existing_context = subgroup_ltv.Find(
196               le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
197           if (existing_context) {
198             if (memcmp(stream_context_vec.data(), existing_context->data(),
199                        existing_context->size()) != 0) {
200               subgroup_ltv.Add(
201                   le_audio::types::kLeAudioMetadataTypeStreamingAudioContext,
202                   stream_context_vec);
203               subgroup_update = true;
204             }
205           } else {
206             subgroup_ltv.Add(
207                 le_audio::types::kLeAudioMetadataTypeStreamingAudioContext,
208                 stream_context_vec);
209             subgroup_update = true;
210           }
211 
212           auto existing_ccid_list =
213               subgroup_ltv.Find(le_audio::types::kLeAudioMetadataTypeCcidList);
214           if (existing_ccid_list) {
215             if (ccids.empty()) {
216               subgroup_ltv.Remove(
217                   le_audio::types::kLeAudioMetadataTypeCcidList);
218               subgroup_update = true;
219 
220             } else if (!std::is_permutation(ccids.begin(), ccids.end(),
221                                             existing_ccid_list->begin())) {
222               subgroup_ltv.Add(le_audio::types::kLeAudioMetadataTypeCcidList,
223                                ccids);
224               subgroup_update = true;
225             }
226           } else if (!ccids.empty()) {
227             subgroup_ltv.Add(le_audio::types::kLeAudioMetadataTypeCcidList,
228                              ccids);
229             subgroup_update = true;
230           }
231 
232           if (subgroup_update) {
233             subgroup.metadata = subgroup_ltv.Values();
234             broadcast_update = true;
235           }
236         }
237 
238         if (broadcast_update) {
239           broadcast->UpdateBroadcastAnnouncement(std::move(announcement));
240         }
241       }
242     }
243   }
244 
UpdateMetadata(uint32_t broadcast_id,std::vector<uint8_t> metadata)245   void UpdateMetadata(uint32_t broadcast_id,
246                       std::vector<uint8_t> metadata) override {
247     if (broadcasts_.count(broadcast_id) == 0) {
248       LOG_ERROR("No such broadcast_id=%d", broadcast_id);
249       return;
250     }
251 
252     LOG_INFO("For broadcast_id=%d", broadcast_id);
253 
254     auto& codec_config = broadcasts_[broadcast_id]->GetCodecConfig();
255 
256     /* Prepare the announcement format */
257     bool is_metadata_valid;
258     auto ltv = LeAudioLtvMap::Parse(metadata.data(), metadata.size(),
259                                     is_metadata_valid);
260     if (!is_metadata_valid) {
261       LOG_ERROR("Invalid metadata provided.");
262       return;
263     }
264 
265     auto context_type = AudioContexts(LeAudioContextType::MEDIA);
266 
267     /* Adds multiple contexts and CCIDs regardless of the incoming audio
268      * context. Android has only two CCIDs, one for Media and one for
269      * Conversational context. Even though we are not broadcasting
270      * Conversational streams, some PTS test cases wants multiple CCIDs.
271      */
272     if (stack_config_get_interface()
273             ->get_pts_force_le_audio_multiple_contexts_metadata()) {
274       context_type =
275           LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
276       auto stream_context_vec =
277           ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
278       if (stream_context_vec) {
279         auto pp = stream_context_vec.value().data();
280         UINT16_TO_STREAM(pp, context_type.value());
281       }
282     }
283 
284     auto stream_context_vec =
285         ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
286     if (stream_context_vec) {
287       auto pp = stream_context_vec.value().data();
288       STREAM_TO_UINT16(context_type.value_ref(), pp);
289     }
290 
291     // Append the CCID list
292     auto ccid_vec = GetAllCcids(context_type);
293     if (!ccid_vec.empty()) {
294       ltv.Add(le_audio::types::kLeAudioMetadataTypeCcidList, ccid_vec);
295     }
296 
297     BasicAudioAnnouncementData announcement =
298         prepareAnnouncement(codec_config, std::move(ltv));
299 
300     broadcasts_[broadcast_id]->UpdateBroadcastAnnouncement(
301         std::move(announcement));
302   }
303 
CreateAudioBroadcast(std::vector<uint8_t> metadata,std::optional<bluetooth::le_audio::BroadcastCode> broadcast_code)304   void CreateAudioBroadcast(std::vector<uint8_t> metadata,
305                             std::optional<bluetooth::le_audio::BroadcastCode>
306                                 broadcast_code) override {
307     auto broadcast_id = available_broadcast_ids_.back();
308     available_broadcast_ids_.pop_back();
309     if (available_broadcast_ids_.size() == 0) GenerateBroadcastIds();
310 
311     /* Prepare the announcement format */
312     bool is_metadata_valid;
313     auto ltv = LeAudioLtvMap::Parse(metadata.data(), metadata.size(),
314                                     is_metadata_valid);
315     if (!is_metadata_valid) {
316       LOG_ERROR("Invalid metadata provided.");
317       return;
318     }
319 
320     auto context_type = AudioContexts(LeAudioContextType::MEDIA);
321 
322     /* Adds multiple contexts and CCIDs regardless of the incoming audio
323      * context. Android has only two CCIDs, one for Media and one for
324      * Conversational context. Even though we are not broadcasting
325      * Conversational streams, some PTS test cases wants multiple CCIDs.
326      */
327     if (stack_config_get_interface()
328             ->get_pts_force_le_audio_multiple_contexts_metadata()) {
329       context_type =
330           LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
331       auto stream_context_vec =
332           ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
333       if (stream_context_vec) {
334         auto pp = stream_context_vec.value().data();
335         UINT16_TO_STREAM(pp, context_type.value());
336       }
337     }
338 
339     auto stream_context_vec =
340         ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext);
341     if (stream_context_vec) {
342       auto pp = stream_context_vec.value().data();
343       STREAM_TO_UINT16(context_type.value_ref(), pp);
344     }
345 
346     // Append the CCID list
347     auto ccid_vec = GetAllCcids(context_type);
348     if (!ccid_vec.empty()) {
349       ltv.Add(le_audio::types::kLeAudioMetadataTypeCcidList, ccid_vec);
350     }
351 
352     if (CodecManager::GetInstance()->GetCodecLocation() ==
353         CodecLocation::ADSP) {
354       auto offload_config =
355           CodecManager::GetInstance()->GetBroadcastOffloadConfig();
356       BroadcastCodecWrapper codec_config(
357           {.coding_format = le_audio::types::kLeAudioCodingFormatLC3,
358            .vendor_company_id =
359                le_audio::types::kLeAudioVendorCompanyIdUndefined,
360            .vendor_codec_id = le_audio::types::kLeAudioVendorCodecIdUndefined},
361           {.num_channels =
362                static_cast<uint8_t>(offload_config->stream_map.size()),
363            .sample_rate = offload_config->sampling_rate,
364            .bits_per_sample = offload_config->bits_per_sample,
365            .data_interval_us = offload_config->frame_duration},
366           offload_config->codec_bitrate, offload_config->octets_per_frame);
367       BroadcastQosConfig qos_config(offload_config->retransmission_number,
368                                     offload_config->max_transport_latency);
369 
370       BroadcastStateMachineConfig msg = {
371           .broadcast_id = broadcast_id,
372           .streaming_phy = GetStreamingPhy(),
373           .codec_wrapper = codec_config,
374           .qos_config = qos_config,
375           .announcement = prepareAnnouncement(codec_config, std::move(ltv)),
376           .broadcast_code = std::move(broadcast_code)};
377 
378       pending_broadcasts_.push_back(
379           std::move(BroadcastStateMachine::CreateInstance(std::move(msg))));
380     } else {
381       auto codec_qos_pair =
382           le_audio::broadcaster::getStreamConfigForContext(context_type);
383       BroadcastStateMachineConfig msg = {
384           .broadcast_id = broadcast_id,
385           .streaming_phy = GetStreamingPhy(),
386           .codec_wrapper = codec_qos_pair.first,
387           .qos_config = codec_qos_pair.second,
388           .announcement =
389               prepareAnnouncement(codec_qos_pair.first, std::move(ltv)),
390           .broadcast_code = std::move(broadcast_code)};
391 
392       /* Create the broadcaster instance - we'll receive it's init state in the
393        * async callback
394        */
395       pending_broadcasts_.push_back(
396           std::move(BroadcastStateMachine::CreateInstance(std::move(msg))));
397     }
398 
399     LOG_INFO("CreateAudioBroadcast");
400 
401     // Notify the error instead just fail silently
402     if (!pending_broadcasts_.back()->Initialize()) {
403       pending_broadcasts_.pop_back();
404       callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
405                                      false);
406     }
407   }
408 
SuspendAudioBroadcast(uint32_t broadcast_id)409   void SuspendAudioBroadcast(uint32_t broadcast_id) override {
410     LOG_INFO("broadcast_id=%d", broadcast_id);
411 
412     if (broadcasts_.count(broadcast_id) != 0) {
413       LOG_INFO("Stopping AudioHalClient");
414       if (le_audio_source_hal_client_) le_audio_source_hal_client_->Stop();
415       broadcasts_[broadcast_id]->SetMuted(true);
416       broadcasts_[broadcast_id]->ProcessMessage(
417           BroadcastStateMachine::Message::SUSPEND, nullptr);
418     } else {
419       LOG_ERROR("No such broadcast_id=%d", broadcast_id);
420     }
421   }
422 
IsAnyoneStreaming()423   static bool IsAnyoneStreaming() {
424     if (!instance) return false;
425 
426     auto const& iter =
427         std::find_if(instance->broadcasts_.cbegin(),
428                      instance->broadcasts_.cend(), [](auto const& sm) {
429                        return sm.second->GetState() ==
430                               BroadcastStateMachine::State::STREAMING;
431                      });
432     return (iter != instance->broadcasts_.cend());
433   }
434 
StartAudioBroadcast(uint32_t broadcast_id)435   void StartAudioBroadcast(uint32_t broadcast_id) override {
436     LOG_INFO("Starting broadcast_id=%d", broadcast_id);
437 
438     if (IsAnyoneStreaming()) {
439       LOG_ERROR("Stop the other broadcast first!");
440       return;
441     }
442 
443     if (broadcasts_.count(broadcast_id) != 0) {
444       if (!le_audio_source_hal_client_) {
445         le_audio_source_hal_client_ =
446             LeAudioSourceAudioHalClient::AcquireBroadcast();
447         if (!le_audio_source_hal_client_) {
448           LOG_ERROR("Could not acquire le audio");
449           return;
450         }
451       }
452 
453       broadcasts_[broadcast_id]->ProcessMessage(
454           BroadcastStateMachine::Message::START, nullptr);
455     } else {
456       LOG_ERROR("No such broadcast_id=%d", broadcast_id);
457     }
458   }
459 
StopAudioBroadcast(uint32_t broadcast_id)460   void StopAudioBroadcast(uint32_t broadcast_id) override {
461     if (broadcasts_.count(broadcast_id) == 0) {
462       LOG_ERROR("no such broadcast_id=%d", broadcast_id);
463       return;
464     }
465 
466     LOG_INFO("Stopping AudioHalClient, broadcast_id=%d", broadcast_id);
467 
468     if (le_audio_source_hal_client_) le_audio_source_hal_client_->Stop();
469     broadcasts_[broadcast_id]->SetMuted(true);
470     broadcasts_[broadcast_id]->ProcessMessage(
471         BroadcastStateMachine::Message::STOP, nullptr);
472   }
473 
DestroyAudioBroadcast(uint32_t broadcast_id)474   void DestroyAudioBroadcast(uint32_t broadcast_id) override {
475     LOG_INFO("Destroying broadcast_id=%d", broadcast_id);
476     broadcasts_.erase(broadcast_id);
477   }
478 
GetBroadcastMetadataOpt(bluetooth::le_audio::BroadcastId broadcast_id)479   std::optional<bluetooth::le_audio::BroadcastMetadata> GetBroadcastMetadataOpt(
480       bluetooth::le_audio::BroadcastId broadcast_id) {
481     bluetooth::le_audio::BroadcastMetadata metadata;
482     for (auto const& kv_it : broadcasts_) {
483       if (kv_it.second->GetBroadcastId() == broadcast_id) {
484         metadata.broadcast_id = kv_it.second->GetBroadcastId();
485         metadata.adv_sid = kv_it.second->GetAdvertisingSid();
486         metadata.pa_interval = kv_it.second->GetPaInterval();
487         metadata.addr = kv_it.second->GetOwnAddress();
488         metadata.addr_type = kv_it.second->GetOwnAddressType();
489         metadata.broadcast_code = kv_it.second->GetBroadcastCode();
490         metadata.basic_audio_announcement =
491             kv_it.second->GetBroadcastAnnouncement();
492         return metadata;
493       }
494     }
495     return std::nullopt;
496   }
497 
GetBroadcastMetadata(uint32_t broadcast_id)498   void GetBroadcastMetadata(uint32_t broadcast_id) override {
499     if (broadcasts_.count(broadcast_id) == 0) {
500       LOG_ERROR("No such broadcast_id=%d", broadcast_id);
501       return;
502     }
503 
504     auto meta = GetBroadcastMetadataOpt(broadcast_id);
505     if (!meta) {
506       LOG_ERROR("No metadata for broadcast_id=%d", broadcast_id);
507       return;
508     }
509     callbacks_->OnBroadcastMetadataChanged(broadcast_id,
510                                            std::move(meta.value()));
511   }
512 
GetAllBroadcastStates(void)513   void GetAllBroadcastStates(void) override {
514     for (auto const& kv_it : broadcasts_) {
515       callbacks_->OnBroadcastStateChanged(
516           kv_it.second->GetBroadcastId(),
517           static_cast<bluetooth::le_audio::BroadcastState>(
518               kv_it.second->GetState()));
519     }
520   }
521 
IsValidBroadcast(uint32_t broadcast_id,uint8_t addr_type,RawAddress addr,base::Callback<void (uint8_t,uint8_t,RawAddress,bool)> cb)522   void IsValidBroadcast(
523       uint32_t broadcast_id, uint8_t addr_type, RawAddress addr,
524       base::Callback<void(uint8_t /* broadcast_id */, uint8_t /* addr_type */,
525                           RawAddress /* addr */, bool /* is_local */)>
526           cb) override {
527     if (broadcasts_.count(broadcast_id) == 0) {
528       LOG_ERROR("No such broadcast_id=%d", broadcast_id);
529       std::move(cb).Run(broadcast_id, addr_type, addr, false);
530       return;
531     }
532 
533     broadcasts_[broadcast_id]->RequestOwnAddress(base::Bind(
534         [](uint32_t broadcast_id, uint8_t req_address_type,
535            RawAddress req_address,
536            base::Callback<void(uint8_t /* broadcast_id */,
537                                uint8_t /* addr_type */, RawAddress /* addr */,
538                                bool /* is_local */)>
539                cb,
540            uint8_t rcv_address_type, RawAddress rcv_address) {
541           bool is_local = (req_address_type == rcv_address_type) &&
542                           (req_address == rcv_address);
543           std::move(cb).Run(broadcast_id, req_address_type, req_address,
544                             is_local);
545         },
546         broadcast_id, addr_type, addr, std::move(cb)));
547   }
548 
SetStreamingPhy(uint8_t phy)549   void SetStreamingPhy(uint8_t phy) override { current_phy_ = phy; }
550 
GetStreamingPhy(void) const551   uint8_t GetStreamingPhy(void) const override { return current_phy_; }
552 
BroadcastIdFromBigHandle(uint8_t big_handle) const553   BroadcastId BroadcastIdFromBigHandle(uint8_t big_handle) const {
554     auto pair_it =
555         std::find_if(broadcasts_.begin(), broadcasts_.end(),
556                      [big_handle](auto const& entry) {
557                        return entry.second->GetAdvertisingSid() == big_handle;
558                      });
559     if (pair_it != broadcasts_.end()) {
560       return pair_it->second->GetBroadcastId();
561     }
562     return bluetooth::le_audio::kBroadcastIdInvalid;
563   }
564 
OnSetupIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t big_handle)565   void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle,
566                           uint8_t big_handle) override {
567     auto broadcast_id = BroadcastIdFromBigHandle(big_handle);
568     CHECK(broadcasts_.count(broadcast_id) != 0);
569     broadcasts_[broadcast_id]->OnSetupIsoDataPath(status, conn_handle);
570   }
571 
OnRemoveIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t big_handle)572   void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle,
573                            uint8_t big_handle) override {
574     auto broadcast_id = BroadcastIdFromBigHandle(big_handle);
575     CHECK(broadcasts_.count(broadcast_id) != 0);
576     broadcasts_[broadcast_id]->OnRemoveIsoDataPath(status, conn_handle);
577   }
578 
OnBigEvent(uint8_t event,void * data)579   void OnBigEvent(uint8_t event, void* data) override {
580     switch (event) {
581       case bluetooth::hci::iso_manager::kIsoEventBigOnCreateCmpl: {
582         auto* evt = static_cast<big_create_cmpl_evt*>(data);
583         auto broadcast_id = BroadcastIdFromBigHandle(evt->big_id);
584         CHECK(broadcasts_.count(broadcast_id) != 0);
585         broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT,
586                                                   evt);
587 
588       } break;
589       case bluetooth::hci::iso_manager::kIsoEventBigOnTerminateCmpl: {
590         auto* evt = static_cast<big_terminate_cmpl_evt*>(data);
591         auto broadcast_id = BroadcastIdFromBigHandle(evt->big_id);
592         CHECK(broadcasts_.count(broadcast_id) != 0);
593         broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
594                                                   evt);
595         le_audio_source_hal_client_.reset();
596       } break;
597       default:
598         LOG_ERROR("Invalid event=%d", event);
599     }
600   }
601 
Dump(int fd)602   void Dump(int fd) {
603     std::stringstream stream;
604 
605     stream << "    Number of broadcasts: " << broadcasts_.size() << "\n";
606     for (auto& broadcast_pair : broadcasts_) {
607       auto& broadcast = broadcast_pair.second;
608       if (broadcast) stream << *broadcast;
609     }
610 
611     dprintf(fd, "%s", stream.str().c_str());
612   }
613 
614  private:
615   static class BroadcastStateMachineCallbacks
616       : public IBroadcastStateMachineCallbacks {
OnStateMachineCreateStatus(uint32_t broadcast_id,bool initialized)617     void OnStateMachineCreateStatus(uint32_t broadcast_id,
618                                     bool initialized) override {
619       auto pending_broadcast = std::find_if(
620           instance->pending_broadcasts_.begin(),
621           instance->pending_broadcasts_.end(), [broadcast_id](auto& sm) {
622             return (sm->GetBroadcastId() == broadcast_id);
623           });
624       LOG_ASSERT(pending_broadcast != instance->pending_broadcasts_.end());
625       LOG_ASSERT(instance->broadcasts_.count(broadcast_id) == 0);
626 
627       if (initialized) {
628         const uint32_t broadcast_id = (*pending_broadcast)->GetBroadcastId();
629         LOG_INFO("broadcast_id=%d state=%s", broadcast_id,
630                  ToString((*pending_broadcast)->GetState()).c_str());
631 
632         instance->broadcasts_[broadcast_id] = std::move(*pending_broadcast);
633       } else {
634         LOG_ERROR("Failed creating broadcast!");
635       }
636       instance->pending_broadcasts_.erase(pending_broadcast);
637       instance->callbacks_->OnBroadcastCreated(broadcast_id, initialized);
638     }
639 
OnStateMachineDestroyed(uint32_t broadcast_id)640     void OnStateMachineDestroyed(uint32_t broadcast_id) override {
641       /* This is a special case when state machine destructor calls this
642        * callback. It may happen during the Cleanup() call when all state
643        * machines are erased and instance can already be set to null to avoid
644        * unnecessary calls.
645        */
646       if (instance) instance->callbacks_->OnBroadcastDestroyed(broadcast_id);
647     }
648 
getStreamerCount()649     static int getStreamerCount() {
650       return std::count_if(instance->broadcasts_.begin(),
651                            instance->broadcasts_.end(), [](auto const& sm) {
652                              LOG_VERBOSE(
653                                  "broadcast_id=%d, state=%s",
654                                  sm.second->GetBroadcastId(),
655                                  ToString(sm.second->GetState()).c_str());
656                              return sm.second->GetState() ==
657                                     BroadcastStateMachine::State::STREAMING;
658                            });
659     }
660 
OnStateMachineEvent(uint32_t broadcast_id,BroadcastStateMachine::State state,const void * data)661     void OnStateMachineEvent(uint32_t broadcast_id,
662                              BroadcastStateMachine::State state,
663                              const void* data) override {
664       LOG_INFO("broadcast_id=%d state=%s", broadcast_id,
665                ToString(state).c_str());
666 
667       switch (state) {
668         case BroadcastStateMachine::State::STOPPED:
669           /* Pass through */
670         case BroadcastStateMachine::State::CONFIGURING:
671           /* Pass through */
672         case BroadcastStateMachine::State::CONFIGURED:
673           /* Pass through */
674         case BroadcastStateMachine::State::STOPPING:
675           /* Nothing to do here? */
676           break;
677         case BroadcastStateMachine::State::STREAMING:
678           if (getStreamerCount() == 1) {
679             LOG_INFO("Starting AudioHalClient");
680 
681             if (instance->broadcasts_.count(broadcast_id) != 0) {
682               const auto& broadcast = instance->broadcasts_.at(broadcast_id);
683 
684               // Reconfigure encoder instance for the new stream requirements
685               audio_receiver_.setCurrentCodecConfig(
686                   broadcast->GetCodecConfig());
687               audio_receiver_.CheckAndReconfigureEncoders();
688 
689               broadcast->SetMuted(false);
690               auto cfg = static_cast<const LeAudioCodecConfiguration*>(data);
691               auto is_started = instance->le_audio_source_hal_client_->Start(
692                   *cfg, &audio_receiver_);
693               if (!is_started) {
694                 /* Audio Source setup failed - stop the broadcast */
695                 instance->StopAudioBroadcast(broadcast_id);
696                 return;
697               }
698 
699               instance->audio_data_path_state_ = AudioDataPathState::ACTIVE;
700             }
701           }
702           break;
703       };
704 
705       instance->callbacks_->OnBroadcastStateChanged(
706           broadcast_id,
707           static_cast<bluetooth::le_audio::BroadcastState>(state));
708     }
709 
OnOwnAddressResponse(uint32_t broadcast_id,uint8_t addr_type,RawAddress addr)710     void OnOwnAddressResponse(uint32_t broadcast_id, uint8_t addr_type,
711                               RawAddress addr) override {
712       /* Not used currently */
713     }
714 
OnBigCreated(const std::vector<uint16_t> & conn_handle)715     void OnBigCreated(const std::vector<uint16_t>& conn_handle) {
716       CodecManager::GetInstance()->UpdateBroadcastConnHandle(
717           conn_handle,
718           std::bind(
719               &LeAudioSourceAudioHalClient::UpdateBroadcastAudioConfigToHal,
720               instance->le_audio_source_hal_client_.get(),
721               std::placeholders::_1));
722     }
723   } state_machine_callbacks_;
724 
725   static class LeAudioSourceCallbacksImpl
726       : public LeAudioSourceAudioHalClient::Callbacks {
727    public:
LeAudioSourceCallbacksImpl()728     LeAudioSourceCallbacksImpl()
729         : codec_wrapper_(le_audio::broadcaster::getStreamConfigForContext(
730                              AudioContexts(LeAudioContextType::UNSPECIFIED))
731                              .first) {}
732 
CheckAndReconfigureEncoders()733     void CheckAndReconfigureEncoders() {
734       auto const& codec_id = codec_wrapper_.GetLeAudioCodecId();
735       if (codec_id.coding_format != kLeAudioCodingFormatLC3) {
736         LOG_ERROR("Invalid codec ID: [%d:%d:%d]", codec_id.coding_format,
737                   codec_id.vendor_company_id, codec_id.vendor_codec_id);
738         return;
739       }
740 
741       if (enc_audio_buffers_.size() != codec_wrapper_.GetNumChannels()) {
742         enc_audio_buffers_.resize(codec_wrapper_.GetNumChannels());
743       }
744 
745       const int dt_us = codec_wrapper_.GetDataIntervalUs();
746       const int sr_hz = codec_wrapper_.GetSampleRate();
747       const auto encoder_bytes = lc3_encoder_size(dt_us, sr_hz);
748       const auto channel_bytes = codec_wrapper_.GetMaxSduSizePerChannel();
749 
750       /* TODO: We should act smart and reuse current configurations */
751       encoders_.clear();
752       encoders_mem_.clear();
753       while (encoders_.size() < codec_wrapper_.GetNumChannels()) {
754         auto& encoder_buf = enc_audio_buffers_.at(encoders_.size());
755         encoder_buf.resize(channel_bytes);
756 
757         encoders_mem_.emplace_back(malloc(encoder_bytes), &std::free);
758         encoders_.emplace_back(
759             lc3_setup_encoder(dt_us, sr_hz, 0, encoders_mem_.back().get()));
760       }
761     }
762 
getCurrentCodecConfig(void) const763     const BroadcastCodecWrapper& getCurrentCodecConfig(void) const {
764       return codec_wrapper_;
765     }
766 
setCurrentCodecConfig(BroadcastCodecWrapper const & config)767     void setCurrentCodecConfig(BroadcastCodecWrapper const& config) {
768       codec_wrapper_ = config;
769     }
770 
encodeLc3Channel(lc3_encoder_t encoder,std::vector<uint8_t> & out_buffer,const std::vector<uint8_t> & data,int initial_channel_offset,int pitch_samples,int num_channels)771     void encodeLc3Channel(lc3_encoder_t encoder,
772                           std::vector<uint8_t>& out_buffer,
773                           const std::vector<uint8_t>& data,
774                           int initial_channel_offset, int pitch_samples,
775                           int num_channels) {
776       auto encoder_status =
777           lc3_encode(encoder, LC3_PCM_FORMAT_S16,
778                      (int16_t*)(data.data() + initial_channel_offset),
779                      pitch_samples, out_buffer.size(), out_buffer.data());
780       if (encoder_status != 0) {
781         LOG_ERROR("Encoding error=%d", encoder_status);
782       }
783     }
784 
sendBroadcastData(const std::unique_ptr<BroadcastStateMachine> & broadcast,std::vector<std::vector<uint8_t>> & encoded_channels)785     static void sendBroadcastData(
786         const std::unique_ptr<BroadcastStateMachine>& broadcast,
787         std::vector<std::vector<uint8_t>>& encoded_channels) {
788       auto const& config = broadcast->GetBigConfig();
789       if (config == std::nullopt) {
790         LOG_ERROR(
791             "Broadcast broadcast_id=%d has no valid BIS configurations in "
792             "state=%s",
793             broadcast->GetBroadcastId(),
794             ToString(broadcast->GetState()).c_str());
795         return;
796       }
797 
798       if (config->connection_handles.size() < encoded_channels.size()) {
799         LOG_ERROR("Not enough BIS'es to broadcast all channels!");
800         return;
801       }
802 
803       for (uint8_t chan = 0; chan < encoded_channels.size(); ++chan) {
804         IsoManager::GetInstance()->SendIsoData(config->connection_handles[chan],
805                                                encoded_channels[chan].data(),
806                                                encoded_channels[chan].size());
807       }
808     }
809 
OnAudioDataReady(const std::vector<uint8_t> & data)810     virtual void OnAudioDataReady(const std::vector<uint8_t>& data) override {
811       if (!instance) return;
812 
813       LOG_VERBOSE("Received %zu bytes.", data.size());
814 
815       /* Constants for the channel data configuration */
816       const auto num_channels = codec_wrapper_.GetNumChannels();
817       const auto bytes_per_sample = (codec_wrapper_.GetBitsPerSample() / 8);
818 
819       /* Prepare encoded data for all channels */
820       for (uint8_t chan = 0; chan < num_channels; ++chan) {
821         /* TODO: Use encoder agnostic wrapper */
822         encodeLc3Channel(encoders_[chan], enc_audio_buffers_[chan], data,
823                          chan * bytes_per_sample, num_channels, num_channels);
824       }
825 
826       /* Currently there is no way to broadcast multiple distinct streams.
827        * We just receive all system sounds mixed into a one stream and each
828        * broadcast gets the same data.
829        */
830       for (auto& broadcast_pair : instance->broadcasts_) {
831         auto& broadcast = broadcast_pair.second;
832         if ((broadcast->GetState() ==
833              BroadcastStateMachine::State::STREAMING) &&
834             !broadcast->IsMuted())
835           sendBroadcastData(broadcast, enc_audio_buffers_);
836       }
837       LOG_VERBOSE("All data sent.");
838     }
839 
OnAudioSuspend(std::promise<void> do_suspend_promise)840     virtual void OnAudioSuspend(
841         std::promise<void> do_suspend_promise) override {
842       LOG_INFO();
843       /* TODO: Should we suspend all broadcasts - remove BIGs? */
844       do_suspend_promise.set_value();
845       if (instance)
846         instance->audio_data_path_state_ = AudioDataPathState::SUSPENDED;
847     }
848 
OnAudioResume(void)849     virtual void OnAudioResume(void) override {
850       LOG_INFO();
851       if (!instance) return;
852 
853       /* TODO: Should we resume all broadcasts - recreate BIGs? */
854       instance->audio_data_path_state_ = AudioDataPathState::ACTIVE;
855 
856       if (!IsAnyoneStreaming()) {
857         instance->le_audio_source_hal_client_->CancelStreamingRequest();
858         return;
859       }
860 
861       instance->le_audio_source_hal_client_->ConfirmStreamingRequest();
862     }
863 
OnAudioMetadataUpdate(std::vector<struct playback_track_metadata> source_metadata)864     virtual void OnAudioMetadataUpdate(
865         std::vector<struct playback_track_metadata> source_metadata) override {
866       LOG_INFO();
867       if (!instance) return;
868 
869       /* TODO: Should we take supported contexts from ASCS? */
870       auto supported_context_types = le_audio::types::kLeAudioContextAllTypes;
871       auto contexts = GetAllowedAudioContextsFromSourceMetadata(
872           source_metadata, supported_context_types);
873       if (contexts.any()) {
874         /* NOTICE: We probably don't want to change the stream configuration
875          * on each metadata change, so just update the context type metadata.
876          * Since we are not able to identify individual track streams and
877          * they are all mixed inside a single data stream, we will update
878          * the metadata of all BIS subgroups with the same combined context.
879          */
880         instance->UpdateStreamingContextTypeOnAllSubgroups(contexts);
881       }
882     }
883 
884    private:
885     BroadcastCodecWrapper codec_wrapper_;
886     std::vector<lc3_encoder_t> encoders_;
887     std::vector<std::unique_ptr<void, decltype(&std::free)>> encoders_mem_;
888     std::vector<std::vector<uint8_t>> enc_audio_buffers_;
889   } audio_receiver_;
890 
891   bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_;
892   std::map<uint32_t, std::unique_ptr<BroadcastStateMachine>> broadcasts_;
893   std::vector<std::unique_ptr<BroadcastStateMachine>> pending_broadcasts_;
894 
895   /* Some BIG params are set globally */
896   uint8_t current_phy_;
897   AudioDataPathState audio_data_path_state_;
898   std::unique_ptr<LeAudioSourceAudioHalClient> le_audio_source_hal_client_;
899   std::vector<BroadcastId> available_broadcast_ids_;
900 };
901 
902 /* Static members definitions */
903 LeAudioBroadcasterImpl::BroadcastStateMachineCallbacks
904     LeAudioBroadcasterImpl::state_machine_callbacks_;
905 LeAudioBroadcasterImpl::LeAudioSourceCallbacksImpl
906     LeAudioBroadcasterImpl::audio_receiver_;
907 
908 } /* namespace */
909 
Initialize(bluetooth::le_audio::LeAudioBroadcasterCallbacks * callbacks,base::Callback<bool ()> audio_hal_verifier)910 void LeAudioBroadcaster::Initialize(
911     bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks,
912     base::Callback<bool()> audio_hal_verifier) {
913   LOG_INFO();
914   if (instance) {
915     LOG_ERROR("Already initialized");
916     return;
917   }
918 
919   if (!controller_get_interface()->supports_ble_isochronous_broadcaster() &&
920       !osi_property_get_bool("persist.bluetooth.fake_iso_support", false)) {
921     LOG_WARN("Isochronous Broadcast not supported by the controller!");
922     return;
923   }
924 
925   if (!std::move(audio_hal_verifier).Run()) {
926     LOG_ALWAYS_FATAL("HAL requirements not met. Init aborted.");
927   }
928 
929   IsoManager::GetInstance()->Start();
930 
931   instance = new LeAudioBroadcasterImpl(callbacks);
932   /* Register HCI event handlers */
933   IsoManager::GetInstance()->RegisterBigCallbacks(instance);
934 }
935 
IsLeAudioBroadcasterRunning()936 bool LeAudioBroadcaster::IsLeAudioBroadcasterRunning() { return instance; }
937 
Get(void)938 LeAudioBroadcaster* LeAudioBroadcaster::Get(void) {
939   LOG_INFO();
940   CHECK(instance);
941   return instance;
942 }
943 
Stop(void)944 void LeAudioBroadcaster::Stop(void) {
945   LOG_INFO();
946 
947   if (instance) {
948     instance->Stop();
949   }
950 }
951 
Cleanup(void)952 void LeAudioBroadcaster::Cleanup(void) {
953   LOG_INFO();
954 
955   if (instance == nullptr) return;
956 
957   LeAudioBroadcasterImpl* ptr = instance;
958   instance = nullptr;
959 
960   ptr->CleanUp();
961   delete ptr;
962 }
963 
DebugDump(int fd)964 void LeAudioBroadcaster::DebugDump(int fd) {
965   dprintf(fd, "Le Audio Broadcaster:\n");
966   if (instance) instance->Dump(fd);
967   dprintf(fd, "\n");
968 }
969