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/functional/bind.h>
19 #include <bluetooth/log.h>
20 #include <lc3.h>
21 
22 #include <mutex>
23 
24 #include "bta/include/bta_le_audio_broadcaster_api.h"
25 #include "bta/le_audio/broadcaster/state_machine.h"
26 #include "bta/le_audio/codec_interface.h"
27 #include "bta/le_audio/content_control_id_keeper.h"
28 #include "bta/le_audio/le_audio_types.h"
29 #include "bta/le_audio/le_audio_utils.h"
30 #include "bta/le_audio/metrics_collector.h"
31 #include "bta_le_audio_api.h"
32 #include "common/strings.h"
33 #include "hci/controller_interface.h"
34 #include "internal_include/stack_config.h"
35 #include "main/shim/entry.h"
36 #include "os/log.h"
37 #include "osi/include/properties.h"
38 #include "stack/include/bt_types.h"
39 #include "stack/include/btm_api_types.h"
40 #include "stack/include/btm_iso_api.h"
41 
42 using bluetooth::common::ToString;
43 using bluetooth::hci::IsoManager;
44 using bluetooth::hci::iso_manager::big_create_cmpl_evt;
45 using bluetooth::hci::iso_manager::big_terminate_cmpl_evt;
46 using bluetooth::hci::iso_manager::BigCallbacks;
47 using bluetooth::le_audio::BasicAudioAnnouncementData;
48 using bluetooth::le_audio::BasicAudioAnnouncementSubgroup;
49 using bluetooth::le_audio::BroadcastId;
50 using bluetooth::le_audio::CodecManager;
51 using bluetooth::le_audio::ContentControlIdKeeper;
52 using bluetooth::le_audio::DsaMode;
53 using bluetooth::le_audio::LeAudioCodecConfiguration;
54 using bluetooth::le_audio::LeAudioSourceAudioHalClient;
55 using bluetooth::le_audio::PublicBroadcastAnnouncementData;
56 using bluetooth::le_audio::broadcaster::BigConfig;
57 using bluetooth::le_audio::broadcaster::BroadcastConfiguration;
58 using bluetooth::le_audio::broadcaster::BroadcastQosConfig;
59 using bluetooth::le_audio::broadcaster::BroadcastStateMachine;
60 using bluetooth::le_audio::broadcaster::BroadcastStateMachineConfig;
61 using bluetooth::le_audio::broadcaster::BroadcastSubgroupCodecConfig;
62 using bluetooth::le_audio::broadcaster::IBroadcastStateMachineCallbacks;
63 using bluetooth::le_audio::types::AudioContexts;
64 using bluetooth::le_audio::types::CodecLocation;
65 using bluetooth::le_audio::types::kLeAudioCodingFormatLC3;
66 using bluetooth::le_audio::types::LeAudioContextType;
67 using bluetooth::le_audio::types::LeAudioLtvMap;
68 using bluetooth::le_audio::utils::GetAudioContextsFromSourceMetadata;
69 
70 using namespace bluetooth;
71 
72 namespace {
73 class LeAudioBroadcasterImpl;
74 LeAudioBroadcasterImpl* instance;
75 std::mutex instance_mutex;
76 
77 /* Class definitions */
78 
79 /* LeAudioBroadcasterImpl class represents main implementation class for le
80  * audio broadcaster feature in the stack.
81  *
82  * This class may be bonded with Test socket which allows to drive an instance
83  * for test purposes.
84  */
85 class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks {
86   enum class AudioDataPathState {
87     INACTIVE,
88     ACTIVE,
89     SUSPENDED,
90   };
91 
92  public:
LeAudioBroadcasterImpl(bluetooth::le_audio::LeAudioBroadcasterCallbacks * callbacks_)93   LeAudioBroadcasterImpl(
94       bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_)
95       : callbacks_(callbacks_),
96         current_phy_(PHY_LE_2M),
97         audio_data_path_state_(AudioDataPathState::INACTIVE),
98         le_audio_source_hal_client_(nullptr) {
99     log::info("");
100 
101     /* Register State machine callbacks */
102     BroadcastStateMachine::Initialize(&state_machine_callbacks_,
103                                       &state_machine_adv_callbacks_);
104 
105     GenerateBroadcastIds();
106   }
107 
108   ~LeAudioBroadcasterImpl() override = default;
109 
GenerateBroadcastIds(void)110   void GenerateBroadcastIds(void) {
111     btsnd_hcic_ble_rand(base::Bind([](BT_OCTET8 rand) {
112       if (!instance) return;
113 
114       /* LE Rand returns 8 octets. Lets' make 2 outstanding Broadcast Ids out
115        * of it */
116       for (int i = 0; i < 8; i += 4) {
117         BroadcastId broadcast_id = 0;
118         /* Broadcast ID should be 3 octets long (BAP v1.0 spec.) */
119         STREAM_TO_UINT24(broadcast_id, rand);
120         if (broadcast_id == bluetooth::le_audio::kBroadcastIdInvalid) continue;
121         instance->available_broadcast_ids_.emplace_back(broadcast_id);
122       }
123 
124       if (instance->available_broadcast_ids_.empty()) {
125         log::fatal("Unable to generate proper broadcast identifiers.");
126       }
127     }));
128   }
129 
CleanUp()130   void CleanUp() {
131     log::info("Broadcaster");
132     broadcasts_.clear();
133     callbacks_ = nullptr;
134     is_iso_running_ = false;
135 
136     if (!LeAudioClient::IsLeAudioClientRunning())
137       IsoManager::GetInstance()->Stop();
138 
139     queued_start_broadcast_request_ = std::nullopt;
140     queued_create_broadcast_request_ = std::nullopt;
141 
142     if (le_audio_source_hal_client_) {
143       le_audio_source_hal_client_->Stop();
144       auto result =
145           CodecManager::GetInstance()->UpdateActiveBroadcastAudioHalClient(
146               le_audio_source_hal_client_.get(), false);
147       log::assert_that(result, "Could not update session in codec manager");
148       le_audio_source_hal_client_.reset();
149     }
150   }
151 
Stop()152   void Stop() {
153     log::info("Broadcaster");
154 
155     for (auto& sm_pair : broadcasts_) {
156       StopAudioBroadcast(sm_pair.first);
157     }
158   }
159 
preparePublicAnnouncement(uint8_t features,const LeAudioLtvMap & metadata)160   static PublicBroadcastAnnouncementData preparePublicAnnouncement(
161       uint8_t features, const LeAudioLtvMap& metadata) {
162     PublicBroadcastAnnouncementData announcement;
163 
164     /* Prepare the announcement */
165     announcement.features = features;
166     announcement.metadata = metadata.Values();
167     return announcement;
168   }
169 
prepareBasicAnnouncement(const std::vector<BroadcastSubgroupCodecConfig> & subgroup_configs,const std::vector<LeAudioLtvMap> & metadata_group)170   static BasicAudioAnnouncementData prepareBasicAnnouncement(
171       const std::vector<BroadcastSubgroupCodecConfig>& subgroup_configs,
172       const std::vector<LeAudioLtvMap>& metadata_group) {
173     BasicAudioAnnouncementData announcement;
174 
175     /* Prepare the announcement */
176     announcement.presentation_delay_us = 40000; /* us */
177 
178     log::assert_that(subgroup_configs.size() == metadata_group.size(),
179                      "The number of metadata subgroups {} does not match the "
180                      "number of subgroup configurations {}.",
181                      metadata_group.size(), subgroup_configs.size());
182 
183     uint8_t subgroup_idx = 0;
184     uint8_t bis_index = 0;
185     while (subgroup_idx < subgroup_configs.size() &&
186            subgroup_idx < metadata_group.size()) {
187       const auto& subgroup_config = subgroup_configs.at(subgroup_idx);
188       const auto& metadata = metadata_group.at(subgroup_idx);
189 
190       auto const& codec_id = subgroup_config.GetLeAudioCodecId();
191       auto const subgroup_codec_spec =
192           subgroup_config.GetCommonBisCodecSpecData();
193       auto opt_vendor_spec_data = subgroup_config.GetVendorCodecSpecData();
194 
195       /* Note: Currently we have a single audio source configured with a one
196        *       set of codec/pcm parameters thus we can use a single subgroup
197        *       for all the BISes. Configure common BIS codec params at the
198        *       subgroup level.
199        */
200       BasicAudioAnnouncementSubgroup config = {
201           .codec_config =
202               {
203                   .codec_id = codec_id.coding_format,
204                   .vendor_company_id = codec_id.vendor_company_id,
205                   .vendor_codec_id = codec_id.vendor_codec_id,
206                   .codec_specific_params =
207                       opt_vendor_spec_data.has_value()
208                           ? std::map<uint8_t, std::vector<uint8_t>>{}
209                           : subgroup_codec_spec.Values(),
210                   .vendor_codec_specific_params =
211                       std::move(opt_vendor_spec_data),
212               },
213           .metadata = metadata.Values(),
214           .bis_configs = {},
215       };
216 
217       for (uint8_t bis_cfg_idx = 0;
218            bis_cfg_idx < subgroup_config.GetAllBisConfigCount();
219            ++bis_cfg_idx) {
220         auto bis_cfg_num_of_bises = subgroup_config.GetNumBis(bis_cfg_idx);
221         for (uint8_t bis_num = 0; bis_num < bis_cfg_num_of_bises; ++bis_num) {
222           // Internally BISes are indexed from 0 in each subgroup, but the BT
223           // spec requires the indices to start from 1 in the entire BIG.
224           ++bis_index;
225 
226           // Check for vendor byte array
227           bluetooth::le_audio::BasicAudioAnnouncementBisConfig bis_config;
228           auto vendor_config =
229               subgroup_config.GetBisVendorCodecSpecData(bis_num);
230           if (vendor_config) {
231             bis_config.vendor_codec_specific_params = vendor_config.value();
232           }
233 
234           // Check for non vendor LTVs
235           auto config_ltv =
236               subgroup_config.GetBisCodecSpecData(bis_num, bis_cfg_idx);
237           if (config_ltv) {
238             // Remove the part which is common with the parent subgroup
239             // parameters
240             config_ltv->RemoveAllTypes(subgroup_codec_spec);
241             bis_config.codec_specific_params = config_ltv->Values();
242           }
243 
244           bis_config.bis_index = bis_index;
245           config.bis_configs.push_back(std::move(bis_config));
246         }
247       }
248 
249       announcement.subgroup_configs.push_back(config);
250       ++subgroup_idx;
251     }
252 
253     return announcement;
254   }
255 
UpdateStreamingContextTypeOnAllSubgroups(const AudioContexts & contexts)256   void UpdateStreamingContextTypeOnAllSubgroups(const AudioContexts& contexts) {
257     log::debug("context_type_map={}", contexts.to_string());
258 
259     auto ccids = ContentControlIdKeeper::GetInstance()->GetAllCcids(contexts);
260     if (ccids.empty()) {
261       log::warn("No content providers available for context_type_map={}.",
262                 contexts.to_string());
263     }
264 
265     std::vector<uint8_t> stream_context_vec(2);
266     auto pp = stream_context_vec.data();
267     UINT16_TO_STREAM(pp, contexts.value());
268 
269     for (auto const& kv_it : broadcasts_) {
270       auto& broadcast = kv_it.second;
271       if (broadcast->GetState() == BroadcastStateMachine::State::STREAMING) {
272         auto announcement = broadcast->GetBroadcastAnnouncement();
273         bool broadcast_update = false;
274 
275         // Replace context type and CCID list
276         for (auto& subgroup : announcement.subgroup_configs) {
277           auto subgroup_ltv = LeAudioLtvMap(subgroup.metadata);
278           bool subgroup_update = false;
279 
280           auto existing_context =
281               subgroup_ltv.Find(bluetooth::le_audio::types::
282                                     kLeAudioMetadataTypeStreamingAudioContext);
283           if (existing_context) {
284             if (memcmp(stream_context_vec.data(), existing_context->data(),
285                        existing_context->size()) != 0) {
286               subgroup_ltv.Add(bluetooth::le_audio::types::
287                                    kLeAudioMetadataTypeStreamingAudioContext,
288                                stream_context_vec);
289               subgroup_update = true;
290             }
291           } else {
292             subgroup_ltv.Add(bluetooth::le_audio::types::
293                                  kLeAudioMetadataTypeStreamingAudioContext,
294                              stream_context_vec);
295             subgroup_update = true;
296           }
297 
298           auto existing_ccid_list = subgroup_ltv.Find(
299               bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
300           if (existing_ccid_list) {
301             if (ccids.empty()) {
302               subgroup_ltv.Remove(
303                   bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
304               subgroup_update = true;
305 
306             } else if (!std::is_permutation(ccids.begin(), ccids.end(),
307                                             existing_ccid_list->begin())) {
308               subgroup_ltv.Add(
309                   bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList,
310                   ccids);
311               subgroup_update = true;
312             }
313           } else if (!ccids.empty()) {
314             subgroup_ltv.Add(
315                 bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList,
316                 ccids);
317             subgroup_update = true;
318           }
319 
320           if (subgroup_update) {
321             subgroup.metadata = subgroup_ltv.Values();
322             broadcast_update = true;
323           }
324         }
325 
326         if (broadcast_update) {
327           broadcast->UpdateBroadcastAnnouncement(std::move(announcement));
328         }
329       }
330     }
331   }
332 
UpdateMetadata(uint32_t broadcast_id,const std::string & broadcast_name,const std::vector<uint8_t> & public_metadata,const std::vector<std::vector<uint8_t>> & subgroup_metadata)333   void UpdateMetadata(
334       uint32_t broadcast_id, const std::string& broadcast_name,
335       const std::vector<uint8_t>& public_metadata,
336       const std::vector<std::vector<uint8_t>>& subgroup_metadata) override {
337     std::vector<LeAudioLtvMap> subgroup_ltvs;
338 
339     if (broadcasts_.count(broadcast_id) == 0) {
340       log::error("No such broadcast_id={}", broadcast_id);
341       return;
342     }
343 
344     log::info("For broadcast_id={}", broadcast_id);
345 
346     for (const std::vector<uint8_t>& metadata : subgroup_metadata) {
347       /* Prepare the announcement format */
348       bool is_metadata_valid;
349       auto ltv = LeAudioLtvMap::Parse(metadata.data(), metadata.size(), is_metadata_valid);
350       if (!is_metadata_valid) {
351         log::error("Invalid metadata provided.");
352         return;
353       }
354 
355       auto context_type = AudioContexts(LeAudioContextType::MEDIA);
356 
357       /* Adds multiple contexts and CCIDs regardless of the incoming audio
358        * context. Android has only two CCIDs, one for Media and one for
359        * Conversational context. Even though we are not broadcasting
360        * Conversational streams, some PTS test cases wants multiple CCIDs.
361        */
362       if (stack_config_get_interface()
363               ->get_pts_force_le_audio_multiple_contexts_metadata()) {
364         context_type =
365             LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
366         auto stream_context_vec =
367             ltv.Find(bluetooth::le_audio::types::
368                          kLeAudioMetadataTypeStreamingAudioContext);
369         if (stream_context_vec) {
370           auto pp = stream_context_vec.value().data();
371           if (stream_context_vec.value().size() < 2) {
372             log::error("stream_context_vec.value() size < 2");
373             return;
374           }
375           UINT16_TO_STREAM(pp, context_type.value());
376         }
377       }
378 
379       auto stream_context_vec =
380           ltv.Find(bluetooth::le_audio::types::
381                        kLeAudioMetadataTypeStreamingAudioContext);
382       if (stream_context_vec) {
383         auto pp = stream_context_vec.value().data();
384         if (stream_context_vec.value().size() < 2) {
385           log::error("stream_context_vec.value() size < 2");
386           return;
387         }
388         STREAM_TO_UINT16(context_type.value_ref(), pp);
389       }
390 
391       // Append the CCID list
392       auto ccid_vec =
393           ContentControlIdKeeper::GetInstance()->GetAllCcids(context_type);
394       if (!ccid_vec.empty()) {
395         ltv.Add(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList,
396                 ccid_vec);
397       }
398 
399       // Push to subgroup ltvs
400       subgroup_ltvs.push_back(ltv);
401     }
402 
403     if (broadcasts_[broadcast_id]->IsPublicBroadcast()) {
404       // Only update broadcast name and public metadata if current broadcast is
405       // public Otherwise ignore those fields
406       bool is_public_metadata_valid;
407       LeAudioLtvMap public_ltv =
408           LeAudioLtvMap::Parse(public_metadata.data(), public_metadata.size(),
409                                is_public_metadata_valid);
410       if (!is_public_metadata_valid) {
411         log::error("Invalid public metadata provided.");
412         return;
413       }
414       PublicBroadcastAnnouncementData pb_announcement =
415           preparePublicAnnouncement(broadcasts_[broadcast_id]
416                                         ->GetPublicBroadcastAnnouncement()
417                                         .features,
418                                     public_ltv);
419 
420       broadcasts_[broadcast_id]->UpdatePublicBroadcastAnnouncement(
421           broadcast_id, broadcast_name, pb_announcement);
422     }
423 
424     auto& subgroup_configs = broadcasts_[broadcast_id]->GetCodecConfig();
425     BasicAudioAnnouncementData announcement =
426         prepareBasicAnnouncement(subgroup_configs, subgroup_ltvs);
427 
428     broadcasts_[broadcast_id]->UpdateBroadcastAnnouncement(
429         std::move(announcement));
430   }
431 
432   /* Choose the dominating audio context when multiple contexts are mixed */
ChooseConfigurationContextType(AudioContexts audio_contexts)433   LeAudioContextType ChooseConfigurationContextType(
434       AudioContexts audio_contexts) {
435     log::debug("Got contexts={}", bluetooth::common::ToString(audio_contexts));
436 
437     /* Prioritize the most common use cases. */
438     if (audio_contexts.any()) {
439       LeAudioContextType context_priority_list[] = {
440           LeAudioContextType::LIVE,          LeAudioContextType::GAME,
441           LeAudioContextType::MEDIA,         LeAudioContextType::EMERGENCYALARM,
442           LeAudioContextType::ALERTS,        LeAudioContextType::INSTRUCTIONAL,
443           LeAudioContextType::NOTIFICATIONS, LeAudioContextType::SOUNDEFFECTS,
444       };
445       for (auto ct : context_priority_list) {
446         if (audio_contexts.test(ct)) {
447           log::debug("Selecting configuration context type: {}", ToString(ct));
448           return ct;
449         }
450       }
451     }
452 
453     auto fallback_config = LeAudioContextType::MEDIA;
454     log::debug("Selecting configuration context type: {}",
455                ToString(fallback_config));
456     return fallback_config;
457   }
458 
CreateAudioBroadcast(bool is_public,const std::string & broadcast_name,const std::optional<bluetooth::le_audio::BroadcastCode> & broadcast_code,const std::vector<uint8_t> & public_metadata,const std::vector<uint8_t> & subgroup_quality,const std::vector<std::vector<uint8_t>> & subgroup_metadata)459   void CreateAudioBroadcast(
460       bool is_public, const std::string& broadcast_name,
461       const std::optional<bluetooth::le_audio::BroadcastCode>& broadcast_code,
462       const std::vector<uint8_t>& public_metadata,
463       const std::vector<uint8_t>& subgroup_quality,
464       const std::vector<std::vector<uint8_t>>& subgroup_metadata) override {
465     uint8_t public_features = 0;
466     LeAudioLtvMap public_ltv;
467     std::vector<LeAudioLtvMap> subgroup_ltvs;
468 
469     if (queued_create_broadcast_request_) {
470       log::error("Not processed yet queued broadcast");
471       callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
472                                      false);
473       return;
474     }
475 
476     if (is_public) {
477       // Prepare public broadcast announcement format
478       bool is_metadata_valid;
479       public_ltv = LeAudioLtvMap::Parse(
480           public_metadata.data(), public_metadata.size(), is_metadata_valid);
481       if (!is_metadata_valid) {
482         log::error("Invalid metadata provided.");
483         callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
484                                        false);
485         return;
486       }
487       // Prepare public features byte
488       // bit 0 Encryption broadcast stream encrypted or not
489       // bit 1 Standard quality audio configuration present or not
490       // bit 2 High quality audio configuration present or not
491       // bit 3-7 RFU
492       public_features = static_cast<uint8_t>(broadcast_code ? 1 : 0);
493     }
494 
495     auto broadcast_id = available_broadcast_ids_.back();
496     available_broadcast_ids_.pop_back();
497     if (available_broadcast_ids_.size() == 0) GenerateBroadcastIds();
498 
499     auto context_type = AudioContexts(LeAudioContextType::MEDIA);
500 
501     /* Adds multiple contexts and CCIDs regardless of the incoming audio
502      * context. Android has only two CCIDs, one for Media and one for
503      * Conversational context. Even though we are not broadcasting
504      * Conversational streams, some PTS test cases wants multiple CCIDs.
505      */
506     if (stack_config_get_interface()
507             ->get_pts_force_le_audio_multiple_contexts_metadata()) {
508       context_type =
509           LeAudioContextType::MEDIA | LeAudioContextType::CONVERSATIONAL;
510     }
511 
512     for (const uint8_t quality : subgroup_quality) {
513       if (quality == bluetooth::le_audio::QUALITY_STANDARD) {
514         public_features |= bluetooth::le_audio::kLeAudioQualityStandard;
515       } else if (quality == bluetooth::le_audio::QUALITY_HIGH) {
516         public_features |= bluetooth::le_audio::kLeAudioQualityHigh;
517       }
518     }
519 
520     for (const std::vector<uint8_t>& metadata : subgroup_metadata) {
521       /* Prepare the announcement format */
522       bool is_metadata_valid;
523       auto ltv = LeAudioLtvMap::Parse(metadata.data(), metadata.size(), is_metadata_valid);
524       if (!is_metadata_valid) {
525         log::error("Invalid metadata provided.");
526         callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
527                                        false);
528         return;
529       }
530 
531       if (stack_config_get_interface()
532               ->get_pts_force_le_audio_multiple_contexts_metadata()) {
533         auto stream_context_vec =
534             ltv.Find(bluetooth::le_audio::types::
535                          kLeAudioMetadataTypeStreamingAudioContext);
536         if (stream_context_vec) {
537           if (stream_context_vec.value().size() < 2) {
538             log::error("kLeAudioMetadataTypeStreamingAudioContext size < 2");
539             callbacks_->OnBroadcastCreated(
540                 bluetooth::le_audio::kBroadcastIdInvalid, false);
541             return;
542           }
543           auto pp = stream_context_vec.value().data();
544           UINT16_TO_STREAM(pp, context_type.value());
545         }
546       }
547 
548       auto stream_context_vec =
549           ltv.Find(bluetooth::le_audio::types::
550                        kLeAudioMetadataTypeStreamingAudioContext);
551       if (stream_context_vec) {
552         if (stream_context_vec.value().size() < 2) {
553           log::error("kLeAudioMetadataTypeStreamingAudioContext size < 2");
554           callbacks_->OnBroadcastCreated(
555               bluetooth::le_audio::kBroadcastIdInvalid, false);
556           return;
557         }
558 
559         auto pp = stream_context_vec.value().data();
560         STREAM_TO_UINT16(context_type.value_ref(), pp);
561       }
562 
563       // Append the CCID list
564       auto ccid_vec =
565           ContentControlIdKeeper::GetInstance()->GetAllCcids(context_type);
566       if (!ccid_vec.empty()) {
567         ltv.Add(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList,
568                 ccid_vec);
569       }
570 
571       // Push to subgroup ltvs
572       subgroup_ltvs.push_back(ltv);
573     }
574 
575     // Prepare the configuration requirements for each subgroup.
576     // Note: For now, each subgroup contains exactly the same content, but
577     // differs in codec configuration.
578     CodecManager::BroadcastConfigurationRequirements requirements;
579     for (auto& idx : subgroup_quality) {
580       requirements.subgroup_quality.push_back(
581           {ChooseConfigurationContextType(context_type), idx});
582     }
583 
584     if (!le_audio_source_hal_client_) {
585       le_audio_source_hal_client_ =
586           LeAudioSourceAudioHalClient::AcquireBroadcast();
587       if (!le_audio_source_hal_client_) {
588         log::error("Could not acquire le audio");
589         return;
590       }
591       auto result =
592           CodecManager::GetInstance()->UpdateActiveBroadcastAudioHalClient(
593               le_audio_source_hal_client_.get(), true);
594       log::assert_that(result, "Could not update session in codec manager");
595     }
596 
597     auto config = CodecManager::GetInstance()->GetBroadcastConfig(requirements);
598     if (!config) {
599       log::error("No valid broadcast offload config");
600       callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
601                                      false);
602       return;
603     }
604 
605     if (public_features & bluetooth::le_audio::kLeAudioQualityHigh &&
606         config->GetSamplingFrequencyHzMax() < 48000) {
607       log::warn(
608           "Preferred quality isn't supported. Fallback to standard audio "
609           "quality");
610       public_features &= (0xFFFF & ~bluetooth::le_audio::kLeAudioQualityHigh);
611       public_features |= bluetooth::le_audio::kLeAudioQualityStandard;
612     }
613 
614     BroadcastStateMachineConfig msg = {
615         .is_public = is_public,
616         .broadcast_id = broadcast_id,
617         .broadcast_name = broadcast_name,
618         .streaming_phy = GetStreamingPhy(),
619         .config = *config,
620         .announcement =
621             prepareBasicAnnouncement(config->subgroups, subgroup_ltvs),
622         .broadcast_code = std::move(broadcast_code)};
623     if (is_public) {
624       msg.public_announcement =
625           preparePublicAnnouncement(public_features, public_ltv);
626     }
627 
628     // If there is ongoing ISO traffic, it might be a unicast stream
629     if (is_iso_running_) {
630       log::info("Iso is still active. Queueing broadcast creation for later.");
631       if (queued_create_broadcast_request_) {
632         log::warn(
633             "Already queued. Updating queued broadcast creation with the new "
634             "configuration.");
635       }
636       queued_create_broadcast_request_ = std::move(msg);
637       return;
638     }
639 
640     InstantiateBroadcast(std::move(msg));
641   }
642 
InstantiateBroadcast(BroadcastStateMachineConfig msg)643   void InstantiateBroadcast(BroadcastStateMachineConfig msg) {
644     log::info("CreateAudioBroadcast");
645 
646     /* Put the new broadcast on the initialization queue, notify the error and
647      * drop the pending broadcast data if init fails.
648      */
649     pending_broadcasts_.push_back(
650         BroadcastStateMachine::CreateInstance(std::move(msg)));
651     if (!pending_broadcasts_.back()->Initialize()) {
652       pending_broadcasts_.pop_back();
653       callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid,
654                                      false);
655     }
656   }
657 
SuspendAudioBroadcast(uint32_t broadcast_id)658   void SuspendAudioBroadcast(uint32_t broadcast_id) override {
659     log::info("broadcast_id={}", broadcast_id);
660 
661     if (broadcasts_.count(broadcast_id) != 0) {
662       log::info("Stopping AudioHalClient");
663       if (le_audio_source_hal_client_) le_audio_source_hal_client_->Stop();
664       broadcasts_[broadcast_id]->SetMuted(true);
665       broadcasts_[broadcast_id]->ProcessMessage(
666           BroadcastStateMachine::Message::SUSPEND, nullptr);
667     } else {
668       log::error("No such broadcast_id={}", broadcast_id);
669     }
670   }
671 
IsAnyoneStreaming()672   static bool IsAnyoneStreaming() {
673     if (!instance) return false;
674 
675     auto const& iter =
676         std::find_if(instance->broadcasts_.cbegin(),
677                      instance->broadcasts_.cend(), [](auto const& sm) {
678                        return sm.second->GetState() ==
679                               BroadcastStateMachine::State::STREAMING;
680                      });
681     return (iter != instance->broadcasts_.cend());
682   }
683 
StartAudioBroadcast(uint32_t broadcast_id)684   void StartAudioBroadcast(uint32_t broadcast_id) override {
685     log::info("Starting broadcast_id={}", broadcast_id);
686 
687     if (queued_start_broadcast_request_) {
688       log::error("Not processed yet start broadcast request");
689       return;
690     }
691 
692     if (is_iso_running_) {
693       queued_start_broadcast_request_ = broadcast_id;
694       return;
695     }
696 
697     if (IsAnyoneStreaming()) {
698       log::error("Stop the other broadcast first!");
699       return;
700     }
701 
702     if (broadcasts_.count(broadcast_id) != 0) {
703       if (!le_audio_source_hal_client_) {
704         le_audio_source_hal_client_ =
705             LeAudioSourceAudioHalClient::AcquireBroadcast();
706         if (!le_audio_source_hal_client_) {
707           log::error("Could not acquire le audio");
708           return;
709         }
710 
711         auto result =
712             CodecManager::GetInstance()->UpdateActiveBroadcastAudioHalClient(
713                 le_audio_source_hal_client_.get(), true);
714         log::assert_that(result, "Could not update session in codec manager");
715       }
716 
717       broadcasts_[broadcast_id]->ProcessMessage(
718           BroadcastStateMachine::Message::START, nullptr);
719       bluetooth::le_audio::MetricsCollector::Get()->OnBroadcastStateChanged(
720           true);
721     } else {
722       log::error("No such broadcast_id={}", broadcast_id);
723     }
724   }
725 
StopAudioBroadcast(uint32_t broadcast_id)726   void StopAudioBroadcast(uint32_t broadcast_id) override {
727     if (broadcasts_.count(broadcast_id) == 0) {
728       log::error("no such broadcast_id={}", broadcast_id);
729       return;
730     }
731 
732     log::info("Stopping AudioHalClient, broadcast_id={}", broadcast_id);
733 
734     if (le_audio_source_hal_client_) le_audio_source_hal_client_->Stop();
735     broadcasts_[broadcast_id]->SetMuted(true);
736     broadcasts_[broadcast_id]->ProcessMessage(
737         BroadcastStateMachine::Message::STOP, nullptr);
738     bluetooth::le_audio::MetricsCollector::Get()->OnBroadcastStateChanged(
739         false);
740   }
741 
DestroyAudioBroadcast(uint32_t broadcast_id)742   void DestroyAudioBroadcast(uint32_t broadcast_id) override {
743     log::info("Destroying broadcast_id={}", broadcast_id);
744     broadcasts_.erase(broadcast_id);
745 
746     if (broadcasts_.empty() && le_audio_source_hal_client_) {
747       auto result =
748           CodecManager::GetInstance()->UpdateActiveBroadcastAudioHalClient(
749               le_audio_source_hal_client_.get(), false);
750       log::assert_that(result, "Could not update session in codec manager");
751       le_audio_source_hal_client_.reset();
752     }
753   }
754 
GetBroadcastMetadataOpt(bluetooth::le_audio::BroadcastId broadcast_id)755   std::optional<bluetooth::le_audio::BroadcastMetadata> GetBroadcastMetadataOpt(
756       bluetooth::le_audio::BroadcastId broadcast_id) {
757     bluetooth::le_audio::BroadcastMetadata metadata;
758     for (auto const& kv_it : broadcasts_) {
759       if (kv_it.second->GetBroadcastId() == broadcast_id) {
760         metadata.is_public = kv_it.second->IsPublicBroadcast();
761         metadata.broadcast_id = kv_it.second->GetBroadcastId();
762         metadata.broadcast_name = kv_it.second->GetBroadcastName();
763         metadata.adv_sid = kv_it.second->GetAdvertisingSid();
764         metadata.pa_interval = kv_it.second->GetPaInterval();
765         metadata.addr = kv_it.second->GetOwnAddress();
766         metadata.addr_type = kv_it.second->GetOwnAddressType();
767         metadata.broadcast_code = kv_it.second->GetBroadcastCode();
768         metadata.basic_audio_announcement =
769             kv_it.second->GetBroadcastAnnouncement();
770         metadata.public_announcement =
771             kv_it.second->GetPublicBroadcastAnnouncement();
772         return metadata;
773       }
774     }
775     return std::nullopt;
776   }
777 
GetBroadcastMetadata(uint32_t broadcast_id)778   void GetBroadcastMetadata(uint32_t broadcast_id) override {
779     if (broadcasts_.count(broadcast_id) == 0) {
780       log::error("No such broadcast_id={}", broadcast_id);
781       return;
782     }
783 
784     auto meta = GetBroadcastMetadataOpt(broadcast_id);
785     if (!meta) {
786       log::error("No metadata for broadcast_id={}", broadcast_id);
787       return;
788     }
789     callbacks_->OnBroadcastMetadataChanged(broadcast_id,
790                                            std::move(meta.value()));
791   }
792 
GetAllBroadcastStates(void)793   void GetAllBroadcastStates(void) override {
794     for (auto const& kv_it : broadcasts_) {
795       callbacks_->OnBroadcastStateChanged(
796           kv_it.second->GetBroadcastId(),
797           static_cast<bluetooth::le_audio::BroadcastState>(
798               kv_it.second->GetState()));
799     }
800   }
801 
IsValidBroadcast(uint32_t broadcast_id,uint8_t addr_type,RawAddress addr,base::Callback<void (uint8_t,uint8_t,RawAddress,bool)> cb)802   void IsValidBroadcast(
803       uint32_t broadcast_id, uint8_t addr_type, RawAddress addr,
804       base::Callback<void(uint8_t /* broadcast_id */, uint8_t /* addr_type */,
805                           RawAddress /* addr */, bool /* is_local */)>
806           cb) override {
807     if (broadcasts_.count(broadcast_id) == 0) {
808       log::error("No such broadcast_id={}", broadcast_id);
809       std::move(cb).Run(broadcast_id, addr_type, addr, false);
810       return;
811     }
812 
813     broadcasts_[broadcast_id]->RequestOwnAddress(base::Bind(
814         [](uint32_t broadcast_id, uint8_t req_address_type,
815            RawAddress req_address,
816            base::Callback<void(uint8_t /* broadcast_id */,
817                                uint8_t /* addr_type */, RawAddress /* addr */,
818                                bool /* is_local */)>
819                cb,
820            uint8_t rcv_address_type, RawAddress rcv_address) {
821           bool is_local = (req_address_type == rcv_address_type) &&
822                           (req_address == rcv_address);
823           std::move(cb).Run(broadcast_id, req_address_type, req_address,
824                             is_local);
825         },
826         broadcast_id, addr_type, addr, std::move(cb)));
827   }
828 
SetStreamingPhy(uint8_t phy)829   void SetStreamingPhy(uint8_t phy) override { current_phy_ = phy; }
830 
GetStreamingPhy(void) const831   uint8_t GetStreamingPhy(void) const override { return current_phy_; }
832 
BroadcastIdFromBigHandle(uint8_t big_handle) const833   BroadcastId BroadcastIdFromBigHandle(uint8_t big_handle) const {
834     auto pair_it =
835         std::find_if(broadcasts_.begin(), broadcasts_.end(),
836                      [big_handle](auto const& entry) {
837                        return entry.second->GetAdvertisingSid() == big_handle;
838                      });
839     if (pair_it != broadcasts_.end()) {
840       return pair_it->second->GetBroadcastId();
841     }
842     return bluetooth::le_audio::kBroadcastIdInvalid;
843   }
844 
OnSetupIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t big_handle)845   void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle,
846                           uint8_t big_handle) override {
847     auto broadcast_id = BroadcastIdFromBigHandle(big_handle);
848     log::assert_that(broadcasts_.count(broadcast_id) != 0,
849                      "assert failed: broadcasts_.count(broadcast_id) != 0");
850     broadcasts_[broadcast_id]->OnSetupIsoDataPath(status, conn_handle);
851   }
852 
OnRemoveIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t big_handle)853   void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle,
854                            uint8_t big_handle) override {
855     auto broadcast_id = BroadcastIdFromBigHandle(big_handle);
856     log::assert_that(broadcasts_.count(broadcast_id) != 0,
857                      "assert failed: broadcasts_.count(broadcast_id) != 0");
858     broadcasts_[broadcast_id]->OnRemoveIsoDataPath(status, conn_handle);
859   }
860 
OnBigEvent(uint8_t event,void * data)861   void OnBigEvent(uint8_t event, void* data) override {
862     switch (event) {
863       case bluetooth::hci::iso_manager::kIsoEventBigOnCreateCmpl: {
864         auto* evt = static_cast<big_create_cmpl_evt*>(data);
865         auto broadcast_id = BroadcastIdFromBigHandle(evt->big_id);
866         log::assert_that(broadcasts_.count(broadcast_id) != 0,
867                          "assert failed: broadcasts_.count(broadcast_id) != 0");
868         broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_CREATE_BIG_CPL_EVT,
869                                                   evt);
870 
871       } break;
872       case bluetooth::hci::iso_manager::kIsoEventBigOnTerminateCmpl: {
873         auto* evt = static_cast<big_terminate_cmpl_evt*>(data);
874         auto broadcast_id = BroadcastIdFromBigHandle(evt->big_id);
875         log::assert_that(broadcasts_.count(broadcast_id) != 0,
876                          "assert failed: broadcasts_.count(broadcast_id) != 0");
877         broadcasts_[broadcast_id]->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT,
878                                                   evt);
879         auto result =
880             CodecManager::GetInstance()->UpdateActiveBroadcastAudioHalClient(
881                 le_audio_source_hal_client_.get(), false);
882         log::assert_that(result, "Could not update session in codec manager");
883         le_audio_source_hal_client_.reset();
884       } break;
885       default:
886         log::error("Invalid event={}", event);
887     }
888   }
889 
IsoTrafficEventCb(bool is_active)890   void IsoTrafficEventCb(bool is_active) {
891     is_iso_running_ = is_active;
892     log::info("is_iso_running: {}", is_iso_running_);
893     if (!is_iso_running_) {
894       if (queued_start_broadcast_request_) {
895         auto broadcast_id = *queued_start_broadcast_request_;
896         queued_start_broadcast_request_ = std::nullopt;
897 
898         log::info("Start queued broadcast.");
899         StartAudioBroadcast(broadcast_id);
900       }
901       if (queued_create_broadcast_request_) {
902         auto broadcast_msg = std::move(*queued_create_broadcast_request_);
903         queued_create_broadcast_request_ = std::nullopt;
904 
905         log::info("Create queued broadcast.");
906         InstantiateBroadcast(std::move(broadcast_msg));
907       }
908     }
909   }
910 
Dump(int fd)911   void Dump(int fd) {
912     std::stringstream stream;
913 
914     stream << "    Number of broadcasts: " << broadcasts_.size() << "\n";
915     for (auto& broadcast_pair : broadcasts_) {
916       auto& broadcast = broadcast_pair.second;
917       if (broadcast) stream << *broadcast;
918     }
919 
920     dprintf(fd, "%s", stream.str().c_str());
921   }
922 
923  private:
924   static class BroadcastStateMachineCallbacks
925       : public IBroadcastStateMachineCallbacks {
OnStateMachineCreateStatus(uint32_t broadcast_id,bool initialized)926     void OnStateMachineCreateStatus(uint32_t broadcast_id,
927                                     bool initialized) override {
928       auto pending_broadcast = std::find_if(
929           instance->pending_broadcasts_.begin(),
930           instance->pending_broadcasts_.end(), [broadcast_id](auto& sm) {
931             return (sm->GetBroadcastId() == broadcast_id);
932           });
933       log::assert_that(pending_broadcast != instance->pending_broadcasts_.end(),
934                        "assert failed: pending_broadcast != "
935                        "instance->pending_broadcasts_.end()");
936       log::assert_that(
937           instance->broadcasts_.count(broadcast_id) == 0,
938           "assert failed: instance->broadcasts_.count(broadcast_id) == 0");
939 
940       if (initialized) {
941         const uint32_t broadcast_id = (*pending_broadcast)->GetBroadcastId();
942         log::info("broadcast_id={} state={}", broadcast_id,
943                   ToString((*pending_broadcast)->GetState()));
944 
945         instance->broadcasts_[broadcast_id] = std::move(*pending_broadcast);
946       } else {
947         log::error("Failed creating broadcast!");
948       }
949       instance->pending_broadcasts_.erase(pending_broadcast);
950       instance->callbacks_->OnBroadcastCreated(broadcast_id, initialized);
951     }
952 
OnStateMachineDestroyed(uint32_t broadcast_id)953     void OnStateMachineDestroyed(uint32_t broadcast_id) override {
954       /* This is a special case when state machine destructor calls this
955        * callback. It may happen during the Cleanup() call when all state
956        * machines are erased and instance can already be set to null to avoid
957        * unnecessary calls.
958        */
959       if (instance) instance->callbacks_->OnBroadcastDestroyed(broadcast_id);
960     }
961 
getStreamerCount()962     static int getStreamerCount() {
963       return std::count_if(instance->broadcasts_.begin(),
964                            instance->broadcasts_.end(), [](auto const& sm) {
965                              log::verbose("broadcast_id={}, state={}",
966                                           sm.second->GetBroadcastId(),
967                                           ToString(sm.second->GetState()));
968                              return sm.second->GetState() ==
969                                     BroadcastStateMachine::State::STREAMING;
970                            });
971     }
972 
OnStateMachineEvent(uint32_t broadcast_id,BroadcastStateMachine::State state,const void * data)973     void OnStateMachineEvent(uint32_t broadcast_id,
974                              BroadcastStateMachine::State state,
975                              const void* data) override {
976       log::info("broadcast_id={} state={}", broadcast_id, ToString(state));
977 
978       switch (state) {
979         case BroadcastStateMachine::State::STOPPED:
980           /* Pass through */
981         case BroadcastStateMachine::State::CONFIGURING:
982           /* Pass through */
983         case BroadcastStateMachine::State::CONFIGURED:
984           /* Pass through */
985         case BroadcastStateMachine::State::STOPPING:
986           /* Nothing to do here? */
987           break;
988         case BroadcastStateMachine::State::STREAMING:
989           if (getStreamerCount() == 1) {
990             log::info("Starting AudioHalClient");
991 
992             if (instance->broadcasts_.count(broadcast_id) != 0) {
993               const auto& broadcast = instance->broadcasts_.at(broadcast_id);
994               const auto& broadcast_config = broadcast->GetBroadcastConfig();
995 
996               // Reconfigure encoder instances for the new stream requirements
997               audio_receiver_.CheckAndReconfigureEncoders(broadcast_config);
998 
999               broadcast->SetMuted(false);
1000               auto is_started = instance->le_audio_source_hal_client_->Start(
1001                   broadcast_config.GetAudioHalClientConfig(), &audio_receiver_);
1002               if (!is_started) {
1003                 /* Audio Source setup failed - stop the broadcast */
1004                 instance->StopAudioBroadcast(broadcast_id);
1005                 return;
1006               }
1007 
1008               instance->audio_data_path_state_ = AudioDataPathState::ACTIVE;
1009             }
1010           }
1011           break;
1012       };
1013 
1014       instance->callbacks_->OnBroadcastStateChanged(
1015           broadcast_id,
1016           static_cast<bluetooth::le_audio::BroadcastState>(state));
1017     }
1018 
OnOwnAddressResponse(uint32_t broadcast_id,uint8_t addr_type,RawAddress addr)1019     void OnOwnAddressResponse(uint32_t broadcast_id, uint8_t addr_type,
1020                               RawAddress addr) override {
1021       /* Not used currently */
1022     }
1023 
OnBigCreated(const std::vector<uint16_t> & conn_handle)1024     void OnBigCreated(const std::vector<uint16_t>& conn_handle) {
1025       CodecManager::GetInstance()->UpdateBroadcastConnHandle(
1026           conn_handle,
1027           std::bind(
1028               &LeAudioSourceAudioHalClient::UpdateBroadcastAudioConfigToHal,
1029               instance->le_audio_source_hal_client_.get(),
1030               std::placeholders::_1));
1031     }
1032   } state_machine_callbacks_;
1033 
1034   static class BroadcastAdvertisingCallbacks : public AdvertisingCallbacks {
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t tx_power,uint8_t status)1035     void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id,
1036                                  int8_t tx_power, uint8_t status) {
1037       if (!instance) return;
1038 
1039       if (reg_id == BroadcastStateMachine::kLeAudioBroadcastRegId &&
1040           !instance->pending_broadcasts_.empty()) {
1041         instance->pending_broadcasts_.back()->OnCreateAnnouncement(
1042             advertiser_id, tx_power, status);
1043       } else {
1044         log::warn(
1045             "Ignored OnAdvertisingSetStarted callback reg_id:{} "
1046             "advertiser_id:{}",
1047             reg_id, advertiser_id);
1048       }
1049     }
1050 
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)1051     void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable,
1052                               uint8_t status) {
1053       if (!instance) return;
1054 
1055       auto const& iter = std::find_if(
1056           instance->broadcasts_.cbegin(), instance->broadcasts_.cend(),
1057           [advertiser_id](auto const& sm) {
1058             return sm.second->GetAdvertisingSid() == advertiser_id;
1059           });
1060       if (iter != instance->broadcasts_.cend()) {
1061         iter->second->OnEnableAnnouncement(enable, status);
1062       } else {
1063         log::warn("Ignored OnAdvertisingEnabled callback advertiser_id:{}",
1064                   advertiser_id);
1065       }
1066     }
1067 
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)1068     void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
1069       log::warn(
1070           "Not being used, ignored OnAdvertisingDataSet callback "
1071           "advertiser_id:{}",
1072           advertiser_id);
1073     }
1074 
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t status)1075     void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) {
1076       log::warn(
1077           "Not being used, ignored OnScanResponseDataSet callback "
1078           "advertiser_id:{}",
1079           advertiser_id);
1080     }
1081 
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t tx_power,uint8_t status)1082     void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power,
1083                                         uint8_t status) {
1084       log::warn(
1085           "Not being used, ignored OnAdvertisingParametersUpdated callback "
1086           "advertiser_id:{}",
1087           advertiser_id);
1088     }
1089 
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t status)1090     void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,
1091                                                 uint8_t status) {
1092       log::warn(
1093           "Not being used, ignored OnPeriodicAdvertisingParametersUpdated "
1094           "callback advertiser_id:{}",
1095           advertiser_id);
1096     }
1097 
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)1098     void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
1099       log::warn(
1100           "Not being used, ignored OnPeriodicAdvertisingDataSet callback "
1101           "advertiser_id:{}",
1102           advertiser_id);
1103     }
1104 
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)1105     void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable,
1106                                       uint8_t status) {
1107       log::warn(
1108           "Not being used, ignored OnPeriodicAdvertisingEnabled callback "
1109           "advertiser_id:{}",
1110           advertiser_id);
1111     }
1112 
OnOwnAddressRead(uint8_t advertiser_id,uint8_t address_type,RawAddress address)1113     void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type,
1114                           RawAddress address) {
1115       log::warn(
1116           "Not being used, ignored OnOwnAddressRead callback advertiser_id:{}",
1117           advertiser_id);
1118     }
1119   } state_machine_adv_callbacks_;
1120 
1121   static class LeAudioSourceCallbacksImpl
1122       : public LeAudioSourceAudioHalClient::Callbacks {
1123    public:
1124     LeAudioSourceCallbacksImpl() = default;
CheckAndReconfigureEncoders(const BroadcastConfiguration & broadcast_config)1125     void CheckAndReconfigureEncoders(
1126         const BroadcastConfiguration& broadcast_config) {
1127       /* TODO: Move software codec instance management to the Codec Manager */
1128       if (CodecManager::GetInstance()->GetCodecLocation() ==
1129           CodecLocation::ADSP) {
1130         return;
1131       }
1132 
1133       auto codec_config = broadcast_config.GetAudioHalClientConfig();
1134 
1135       /* Note: Currently we support only a single subgroup software encoding.
1136        * In future consider mirroring the same data in a different quality
1137        * subgroups.
1138        */
1139       auto const& subgroup_config = broadcast_config.subgroups.at(0);
1140 
1141       auto const& codec_id = subgroup_config.GetLeAudioCodecId();
1142       /* TODO: We should act smart and reuse current configurations */
1143       sw_enc_.clear();
1144       while (sw_enc_.size() != subgroup_config.GetNumChannelsTotal()) {
1145         auto codec =
1146             bluetooth::le_audio::CodecInterface::CreateInstance(codec_id);
1147 
1148         auto codec_status = codec->InitEncoder(codec_config, codec_config);
1149         if (codec_status !=
1150             bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
1151           log::error("Channel {} codec setup failed with err: {}",
1152                      (uint32_t)sw_enc_.size(), codec_status);
1153           return;
1154         }
1155 
1156         sw_enc_.emplace_back(std::move(codec));
1157       }
1158 
1159       broadcast_config_ = broadcast_config;
1160     }
1161 
sendBroadcastData(const std::unique_ptr<BroadcastStateMachine> & broadcast,std::vector<std::unique_ptr<bluetooth::le_audio::CodecInterface>> & encoders)1162     static void sendBroadcastData(
1163         const std::unique_ptr<BroadcastStateMachine>& broadcast,
1164         std::vector<std::unique_ptr<bluetooth::le_audio::CodecInterface>>&
1165             encoders) {
1166       auto const& config = broadcast->GetBigConfig();
1167       if (config == std::nullopt) {
1168         log::error(
1169             "Broadcast broadcast_id={} has no valid BIS configurations in "
1170             "state={}",
1171             broadcast->GetBroadcastId(), ToString(broadcast->GetState()));
1172         return;
1173       }
1174 
1175       if (config->connection_handles.size() < encoders.size()) {
1176         log::error("Not enough BIS'es to broadcast all channels!");
1177         return;
1178       }
1179 
1180       for (uint8_t chan = 0; chan < encoders.size(); ++chan) {
1181         IsoManager::GetInstance()->SendIsoData(
1182             config->connection_handles[chan],
1183             (const uint8_t*)encoders[chan]->GetDecodedSamples().data(),
1184             encoders[chan]->GetDecodedSamples().size() * 2);
1185       }
1186     }
1187 
OnAudioDataReady(const std::vector<uint8_t> & data)1188     virtual void OnAudioDataReady(const std::vector<uint8_t>& data) override {
1189       if (!instance) return;
1190 
1191       log::verbose("Received {} bytes.", data.size());
1192 
1193       if (!broadcast_config_.has_value() ||
1194           (broadcast_config_->subgroups.size() == 0)) {
1195         log::error("Codec was not configured properly");
1196         return;
1197       }
1198 
1199       /* Note: Currently we support only a single subgroup.
1200        * In future consider mirroring the same data in a different quality
1201        * subgroups.
1202        */
1203       auto const& subgroup_config = broadcast_config_->subgroups.at(0);
1204 
1205       /* Constants for the channel data configuration */
1206       const auto num_bis = subgroup_config.GetNumBis();
1207       const auto bytes_per_sample = (subgroup_config.GetBitsPerSample() / 8);
1208 
1209       /* Prepare encoded data for all channels */
1210       for (uint8_t bis_idx = 0; bis_idx < num_bis; ++bis_idx) {
1211         auto initial_channel_offset = bis_idx * bytes_per_sample;
1212         sw_enc_[bis_idx]->Encode(
1213             data.data() + initial_channel_offset, num_bis,
1214             subgroup_config.GetBisOctetsPerCodecFrame(bis_idx));
1215       }
1216 
1217       /* Currently there is no way to broadcast multiple distinct streams.
1218        * We just receive all system sounds mixed into a one stream and each
1219        * broadcast gets the same data.
1220        */
1221       for (auto& broadcast_pair : instance->broadcasts_) {
1222         auto& broadcast = broadcast_pair.second;
1223         if ((broadcast->GetState() ==
1224              BroadcastStateMachine::State::STREAMING) &&
1225             !broadcast->IsMuted())
1226           sendBroadcastData(broadcast, sw_enc_);
1227       }
1228       log::verbose("All data sent.");
1229     }
1230 
OnAudioSuspend(void)1231     virtual void OnAudioSuspend(void) override {
1232       log::info("");
1233       /* TODO: Should we suspend all broadcasts - remove BIGs? */
1234       if (instance)
1235         instance->audio_data_path_state_ = AudioDataPathState::SUSPENDED;
1236     }
1237 
OnAudioResume(void)1238     virtual void OnAudioResume(void) override {
1239       log::info("");
1240       if (!instance) return;
1241 
1242       /* TODO: Should we resume all broadcasts - recreate BIGs? */
1243       instance->audio_data_path_state_ = AudioDataPathState::ACTIVE;
1244 
1245       if (!IsAnyoneStreaming()) {
1246         instance->le_audio_source_hal_client_->CancelStreamingRequest();
1247         return;
1248       }
1249 
1250       instance->le_audio_source_hal_client_->ConfirmStreamingRequest();
1251     }
1252 
OnAudioMetadataUpdate(const std::vector<struct playback_track_metadata_v7> source_metadata,DsaMode dsa_mode)1253     virtual void OnAudioMetadataUpdate(
1254         const std::vector<struct playback_track_metadata_v7> source_metadata,
1255         DsaMode dsa_mode) override {
1256       log::info("");
1257       if (!instance) return;
1258 
1259       /* TODO: Should we take supported contexts from ASCS? */
1260       auto contexts = GetAudioContextsFromSourceMetadata(source_metadata);
1261       if (contexts.any()) {
1262         /* NOTICE: We probably don't want to change the stream configuration
1263          * on each metadata change, so just update the context type metadata.
1264          * Since we are not able to identify individual track streams and
1265          * they are all mixed inside a single data stream, we will update
1266          * the metadata of all BIS subgroups with the same combined context.
1267          */
1268         instance->UpdateStreamingContextTypeOnAllSubgroups(contexts);
1269       }
1270     }
1271 
1272    private:
1273     std::optional<BroadcastConfiguration> broadcast_config_;
1274     std::vector<std::unique_ptr<bluetooth::le_audio::CodecInterface>> sw_enc_;
1275   } audio_receiver_;
1276 
1277   bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_;
1278   std::map<uint32_t, std::unique_ptr<BroadcastStateMachine>> broadcasts_;
1279   std::vector<std::unique_ptr<BroadcastStateMachine>> pending_broadcasts_;
1280   std::optional<BroadcastStateMachineConfig> queued_create_broadcast_request_;
1281   std::optional<uint32_t> queued_start_broadcast_request_;
1282 
1283   /* Some BIG params are set globally */
1284   uint8_t current_phy_;
1285   AudioDataPathState audio_data_path_state_;
1286   std::unique_ptr<LeAudioSourceAudioHalClient> le_audio_source_hal_client_;
1287   std::vector<BroadcastId> available_broadcast_ids_;
1288 
1289   // Flag to track iso state
1290   bool is_iso_running_ = false;
1291 };
1292 
1293 /* Static members definitions */
1294 LeAudioBroadcasterImpl::BroadcastStateMachineCallbacks
1295     LeAudioBroadcasterImpl::state_machine_callbacks_;
1296 LeAudioBroadcasterImpl::LeAudioSourceCallbacksImpl
1297     LeAudioBroadcasterImpl::audio_receiver_;
1298 LeAudioBroadcasterImpl::BroadcastAdvertisingCallbacks
1299     LeAudioBroadcasterImpl::state_machine_adv_callbacks_;
1300 } /* namespace */
1301 
Initialize(bluetooth::le_audio::LeAudioBroadcasterCallbacks * callbacks,base::Callback<bool ()> audio_hal_verifier)1302 void LeAudioBroadcaster::Initialize(
1303     bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks,
1304     base::Callback<bool()> audio_hal_verifier) {
1305   std::scoped_lock<std::mutex> lock(instance_mutex);
1306   log::info("");
1307   if (instance) {
1308     log::error("Already initialized");
1309     return;
1310   }
1311 
1312   if (!bluetooth::shim::GetController()->SupportsBleIsochronousBroadcaster() &&
1313       !osi_property_get_bool("persist.bluetooth.fake_iso_support", false)) {
1314     log::warn("Isochronous Broadcast not supported by the controller!");
1315     return;
1316   }
1317 
1318   if (!std::move(audio_hal_verifier).Run()) {
1319     log::fatal("HAL requirements not met. Init aborted.");
1320   }
1321 
1322   IsoManager::GetInstance()->Start();
1323 
1324   instance = new LeAudioBroadcasterImpl(callbacks);
1325   /* Register HCI event handlers */
1326   IsoManager::GetInstance()->RegisterBigCallbacks(instance);
1327   /* Register for active traffic */
1328   IsoManager::GetInstance()->RegisterOnIsoTrafficActiveCallback(
1329       [](bool is_active) {
1330         if (instance) instance->IsoTrafficEventCb(is_active);
1331       });
1332 }
1333 
IsLeAudioBroadcasterRunning()1334 bool LeAudioBroadcaster::IsLeAudioBroadcasterRunning() { return instance; }
1335 
Get(void)1336 LeAudioBroadcaster* LeAudioBroadcaster::Get(void) {
1337   log::info("");
1338   log::assert_that(instance != nullptr, "assert failed: instance != nullptr");
1339   return instance;
1340 }
1341 
Stop(void)1342 void LeAudioBroadcaster::Stop(void) {
1343   log::info("");
1344 
1345   if (instance) {
1346     instance->Stop();
1347   }
1348 }
1349 
Cleanup(void)1350 void LeAudioBroadcaster::Cleanup(void) {
1351   std::scoped_lock<std::mutex> lock(instance_mutex);
1352   log::info("");
1353 
1354   if (instance == nullptr) return;
1355 
1356   LeAudioBroadcasterImpl* ptr = instance;
1357   instance = nullptr;
1358 
1359   ptr->CleanUp();
1360   delete ptr;
1361 }
1362 
DebugDump(int fd)1363 void LeAudioBroadcaster::DebugDump(int fd) {
1364   std::scoped_lock<std::mutex> lock(instance_mutex);
1365   dprintf(fd, "Le Audio Broadcaster:\n");
1366   if (instance) instance->Dump(fd);
1367   dprintf(fd, "\n");
1368 }
1369