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