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 }
953
954 if (queued_create_broadcast_request_) {
955 auto broadcast_msg = std::move(*queued_create_broadcast_request_);
956 queued_create_broadcast_request_ = std::nullopt;
957
958 log::info("Create queued broadcast.");
959 InstantiateBroadcast(std::move(broadcast_msg));
960 }
961 }
962 }
963
Dump(int fd)964 void Dump(int fd) {
965 std::stringstream stream;
966
967 stream << " Number of broadcasts: " << broadcasts_.size() << "\n";
968 for (auto& broadcast_pair : broadcasts_) {
969 auto& broadcast = broadcast_pair.second;
970 if (broadcast) {
971 stream << *broadcast;
972 }
973 }
974
975 dprintf(fd, "%s", stream.str().c_str());
976 }
977
978 private:
SuspendAudioBroadcasts()979 void SuspendAudioBroadcasts() {
980 log::info("");
981 for (auto& broadcast_pair : broadcasts_) {
982 auto& broadcast = broadcast_pair.second;
983 broadcast->SetMuted(true);
984 broadcast->ProcessMessage(BroadcastStateMachine::Message::SUSPEND, nullptr);
985 }
986 }
987
StopAudioBroadcasts()988 void StopAudioBroadcasts() {
989 log::info("");
990 if (le_audio_source_hal_client_) {
991 le_audio_source_hal_client_->Stop();
992 }
993 for (auto& broadcast_pair : broadcasts_) {
994 auto& broadcast = broadcast_pair.second;
995 broadcast->SetMuted(true);
996 broadcast->ProcessMessage(BroadcastStateMachine::Message::STOP, nullptr);
997 }
998 bluetooth::le_audio::MetricsCollector::Get()->OnBroadcastStateChanged(false);
999 }
1000
setBroadcastTimers()1001 void setBroadcastTimers() {
1002 log::info(" Started");
1003 alarm_set_on_mloop(
1004 big_terminate_timer_, kBigTerminateTimeoutMs,
1005 [](void*) {
1006 if (instance) {
1007 instance->SuspendAudioBroadcasts();
1008 }
1009 },
1010 nullptr);
1011
1012 alarm_set_on_mloop(
1013 broadcast_stop_timer_, kBroadcastStopTimeoutMs,
1014 [](void*) {
1015 if (instance) {
1016 instance->StopAudioBroadcasts();
1017 }
1018 },
1019 nullptr);
1020 }
1021
cancelBroadcastTimers()1022 void cancelBroadcastTimers() {
1023 log::info("");
1024 alarm_cancel(big_terminate_timer_);
1025 alarm_cancel(broadcast_stop_timer_);
1026 }
1027
1028 static class BroadcastStateMachineCallbacks : public IBroadcastStateMachineCallbacks {
OnStateMachineCreateStatus(uint32_t broadcast_id,bool initialized)1029 void OnStateMachineCreateStatus(uint32_t broadcast_id, bool initialized) override {
1030 auto pending_broadcast = std::find_if(
1031 instance->pending_broadcasts_.begin(), instance->pending_broadcasts_.end(),
1032 [broadcast_id](auto& sm) { return sm->GetBroadcastId() == broadcast_id; });
1033 log::assert_that(pending_broadcast != instance->pending_broadcasts_.end(),
1034 "assert failed: pending_broadcast != "
1035 "instance->pending_broadcasts_.end()");
1036 log::assert_that(instance->broadcasts_.count(broadcast_id) == 0,
1037 "assert failed: instance->broadcasts_.count(broadcast_id) == 0");
1038
1039 if (initialized) {
1040 const uint32_t broadcast_id = (*pending_broadcast)->GetBroadcastId();
1041 log::info("broadcast_id={} state={}", broadcast_id,
1042 ToString((*pending_broadcast)->GetState()));
1043
1044 instance->broadcasts_[broadcast_id] = std::move(*pending_broadcast);
1045 } else {
1046 log::error("Failed creating broadcast!");
1047 }
1048 instance->pending_broadcasts_.erase(pending_broadcast);
1049 instance->callbacks_->OnBroadcastCreated(broadcast_id, initialized);
1050 }
1051
OnStateMachineDestroyed(uint32_t broadcast_id)1052 void OnStateMachineDestroyed(uint32_t broadcast_id) override {
1053 /* This is a special case when state machine destructor calls this
1054 * callback. It may happen during the Cleanup() call when all state
1055 * machines are erased and instance can already be set to null to avoid
1056 * unnecessary calls.
1057 */
1058 if (instance) {
1059 instance->callbacks_->OnBroadcastDestroyed(broadcast_id);
1060 }
1061 }
1062
getStreamerCount()1063 static int getStreamerCount() {
1064 return std::count_if(
1065 instance->broadcasts_.begin(), instance->broadcasts_.end(), [](auto const& sm) {
1066 log::verbose("broadcast_id={}, state={}", sm.second->GetBroadcastId(),
1067 ToString(sm.second->GetState()));
1068 return sm.second->GetState() == BroadcastStateMachine::State::STREAMING;
1069 });
1070 }
1071
OnStateMachineEvent(uint32_t broadcast_id,BroadcastStateMachine::State state,const void *)1072 void OnStateMachineEvent(uint32_t broadcast_id, BroadcastStateMachine::State state,
1073 const void* /*data*/) override {
1074 log::info("broadcast_id={} state={}", broadcast_id, ToString(state));
1075
1076 switch (state) {
1077 case BroadcastStateMachine::State::STOPPED:
1078 break;
1079 case BroadcastStateMachine::State::CONFIGURING:
1080 break;
1081 case BroadcastStateMachine::State::CONFIGURED:
1082 if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
1083 instance->UpdateAudioActiveStateInPublicAnnouncement();
1084 }
1085 break;
1086 case BroadcastStateMachine::State::ENABLING:
1087 break;
1088 case BroadcastStateMachine::State::DISABLING:
1089 break;
1090 case BroadcastStateMachine::State::STOPPING:
1091 break;
1092 case BroadcastStateMachine::State::STREAMING:
1093 if (getStreamerCount() == 1) {
1094 log::info("Starting AudioHalClient");
1095
1096 if (instance->broadcasts_.count(broadcast_id) != 0) {
1097 const auto& broadcast = instance->broadcasts_.at(broadcast_id);
1098 const auto& broadcast_config = broadcast->GetBroadcastConfig();
1099
1100 // Reconfigure encoder instances for the new stream requirements
1101 audio_receiver_.CheckAndReconfigureEncoders(broadcast_config);
1102
1103 broadcast->SetMuted(false);
1104 if (!com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
1105 auto is_started = instance->le_audio_source_hal_client_->Start(
1106 broadcast_config.GetAudioHalClientConfig(), &audio_receiver_);
1107 if (!is_started) {
1108 /* Audio Source setup failed - stop the broadcast */
1109 instance->StopAudioBroadcast(broadcast_id);
1110 return;
1111 }
1112 } else {
1113 instance->UpdateAudioActiveStateInPublicAnnouncement();
1114 }
1115 }
1116 }
1117 break;
1118 };
1119
1120 instance->callbacks_->OnBroadcastStateChanged(
1121 broadcast_id, static_cast<bluetooth::le_audio::BroadcastState>(state));
1122 }
1123
OnOwnAddressResponse(uint32_t,uint8_t,RawAddress)1124 void OnOwnAddressResponse(uint32_t /*broadcast_id*/, uint8_t /*addr_type*/,
1125 RawAddress /*addr*/) override {
1126 /* Not used currently */
1127 }
1128
OnBigCreated(const std::vector<uint16_t> & conn_handle)1129 void OnBigCreated(const std::vector<uint16_t>& conn_handle) {
1130 CodecManager::GetInstance()->UpdateBroadcastConnHandle(
1131 conn_handle,
1132 std::bind(&LeAudioSourceAudioHalClient::UpdateBroadcastAudioConfigToHal,
1133 instance->le_audio_source_hal_client_.get(), std::placeholders::_1));
1134
1135 if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
1136 instance->le_audio_source_hal_client_->ConfirmStreamingRequest();
1137 }
1138 }
1139
OnAnnouncementUpdated(uint32_t broadcast_id)1140 void OnAnnouncementUpdated(uint32_t broadcast_id) {
1141 instance->GetBroadcastMetadata(broadcast_id);
1142 }
1143 } state_machine_callbacks_;
1144
1145 static class BroadcastAdvertisingCallbacks : public ::AdvertisingCallbacks {
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t tx_power,uint8_t status)1146 void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power,
1147 uint8_t status) {
1148 if (!instance) {
1149 return;
1150 }
1151
1152 if (reg_id == BroadcastStateMachine::kLeAudioBroadcastRegId &&
1153 !instance->pending_broadcasts_.empty()) {
1154 instance->pending_broadcasts_.back()->OnCreateAnnouncement(advertiser_id, tx_power, status);
1155 } else {
1156 log::warn("Ignored OnAdvertisingSetStarted callback reg_id:{} advertiser_id:{}", reg_id,
1157 advertiser_id);
1158 }
1159 }
1160
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)1161 void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
1162 if (!instance) {
1163 return;
1164 }
1165
1166 auto const& iter = std::find_if(instance->broadcasts_.cbegin(), instance->broadcasts_.cend(),
1167 [advertiser_id](auto const& sm) {
1168 return sm.second->GetAdvertisingSid() == advertiser_id;
1169 });
1170 if (iter != instance->broadcasts_.cend()) {
1171 iter->second->OnEnableAnnouncement(enable, status);
1172 } else {
1173 log::warn("Ignored OnAdvertisingEnabled callback advertiser_id:{}", advertiser_id);
1174 }
1175 }
1176
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)1177 void OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
1178 if (com::android::bluetooth::flags::leaudio_broadcast_update_metadata_callback()) {
1179 if (!instance) {
1180 return;
1181 }
1182
1183 auto const& iter =
1184 std::find_if(instance->broadcasts_.cbegin(), instance->broadcasts_.cend(),
1185 [advertiser_id](auto const& sm) {
1186 return sm.second->GetAdvertisingSid() == advertiser_id;
1187 });
1188 if (iter != instance->broadcasts_.cend()) {
1189 iter->second->OnUpdateAnnouncement(status);
1190 } else {
1191 log::warn("Ignored OnAdvertisingDataSet callback advertiser_id:{}", advertiser_id);
1192 }
1193 } else {
1194 log::warn("Not being used, ignored OnAdvertisingDataSet callback advertiser_id:{}",
1195 advertiser_id);
1196 }
1197 }
1198
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t)1199 void OnScanResponseDataSet(uint8_t advertiser_id, uint8_t /*status*/) {
1200 log::warn("Not being used, ignored OnScanResponseDataSet callback advertiser_id:{}",
1201 advertiser_id);
1202 }
1203
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t,uint8_t)1204 void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t /*tx_power*/,
1205 uint8_t /*status*/) {
1206 log::warn("Not being used, ignored OnAdvertisingParametersUpdated callback advertiser_id:{}",
1207 advertiser_id);
1208 }
1209
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t)1210 void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id, uint8_t /*status*/) {
1211 log::warn(
1212 "Not being used, ignored OnPeriodicAdvertisingParametersUpdated "
1213 "callback advertiser_id:{}",
1214 advertiser_id);
1215 }
1216
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)1217 void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
1218 if (com::android::bluetooth::flags::leaudio_broadcast_update_metadata_callback()) {
1219 if (!instance) {
1220 return;
1221 }
1222
1223 auto const& iter =
1224 std::find_if(instance->broadcasts_.cbegin(), instance->broadcasts_.cend(),
1225 [advertiser_id](auto const& sm) {
1226 return sm.second->GetAdvertisingSid() == advertiser_id;
1227 });
1228 if (iter != instance->broadcasts_.cend()) {
1229 iter->second->OnUpdateAnnouncement(status);
1230 } else {
1231 log::warn("Ignored OnPeriodicAdvertisingDataSet callback advertiser_id:{}",
1232 advertiser_id);
1233 }
1234 } else {
1235 log::warn("Not being used, ignored OnPeriodicAdvertisingDataSet callback advertiser_id:{}",
1236 advertiser_id);
1237 }
1238 }
1239
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool,uint8_t)1240 void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool /*enable*/, uint8_t /*status*/) {
1241 log::warn("Not being used, ignored OnPeriodicAdvertisingEnabled callback advertiser_id:{}",
1242 advertiser_id);
1243 }
1244
OnOwnAddressRead(uint8_t advertiser_id,uint8_t,RawAddress)1245 void OnOwnAddressRead(uint8_t advertiser_id, uint8_t /*address_type*/, RawAddress /*address*/) {
1246 log::warn("Not being used, ignored OnOwnAddressRead callback advertiser_id:{}",
1247 advertiser_id);
1248 }
1249 } state_machine_adv_callbacks_;
1250
1251 static class LeAudioSourceCallbacksImpl : public LeAudioSourceAudioHalClient::Callbacks {
1252 public:
1253 LeAudioSourceCallbacksImpl() = default;
CheckAndReconfigureEncoders(const BroadcastConfiguration & broadcast_config)1254 void CheckAndReconfigureEncoders(const BroadcastConfiguration& broadcast_config) {
1255 /* TODO: Move software codec instance management to the Codec Manager */
1256 if (CodecManager::GetInstance()->GetCodecLocation() == CodecLocation::ADSP) {
1257 return;
1258 }
1259
1260 auto codec_config = broadcast_config.GetAudioHalClientConfig();
1261
1262 /* Note: Currently we support only a single subgroup software encoding.
1263 * In future consider mirroring the same data in a different quality
1264 * subgroups.
1265 */
1266 auto const& subgroup_config = broadcast_config.subgroups.at(0);
1267
1268 auto const& codec_id = subgroup_config.GetLeAudioCodecId();
1269 /* TODO: We should act smart and reuse current configurations */
1270 sw_enc_.clear();
1271 while (sw_enc_.size() != subgroup_config.GetNumChannelsTotal()) {
1272 auto codec = bluetooth::le_audio::CodecInterface::CreateInstance(codec_id);
1273
1274 auto codec_status = codec->InitEncoder(codec_config, codec_config);
1275 if (codec_status != bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
1276 log::error("Channel {} codec setup failed with err: {}", (uint32_t)sw_enc_.size(),
1277 codec_status);
1278 return;
1279 }
1280
1281 sw_enc_.emplace_back(std::move(codec));
1282 }
1283
1284 broadcast_config_ = broadcast_config;
1285 }
1286
sendBroadcastData(const std::unique_ptr<BroadcastStateMachine> & broadcast,std::vector<std::unique_ptr<bluetooth::le_audio::CodecInterface>> & encoders)1287 static void sendBroadcastData(
1288 const std::unique_ptr<BroadcastStateMachine>& broadcast,
1289 std::vector<std::unique_ptr<bluetooth::le_audio::CodecInterface>>& encoders) {
1290 auto const& config = broadcast->GetBigConfig();
1291 if (config == std::nullopt) {
1292 log::error("Broadcast broadcast_id={} has no valid BIS configurations in state={}",
1293 broadcast->GetBroadcastId(), ToString(broadcast->GetState()));
1294 return;
1295 }
1296
1297 if (config->connection_handles.size() < encoders.size()) {
1298 log::error("Not enough BIS'es to broadcast all channels!");
1299 return;
1300 }
1301
1302 for (uint8_t chan = 0; chan < encoders.size(); ++chan) {
1303 IsoManager::GetInstance()->SendIsoData(
1304 config->connection_handles[chan],
1305 (const uint8_t*)encoders[chan]->GetDecodedSamples().data(),
1306 encoders[chan]->GetDecodedSamples().size() * 2);
1307 }
1308 }
1309
OnAudioDataReady(const std::vector<uint8_t> & data)1310 virtual void OnAudioDataReady(const std::vector<uint8_t>& data) override {
1311 if (!instance) {
1312 return;
1313 }
1314
1315 log::verbose("Received {} bytes.", data.size());
1316
1317 if (instance->audio_state_ == AudioState::STOPPED) {
1318 log::warn("audio stopped, skip audio data ready callback");
1319 return;
1320 }
1321
1322 if (!broadcast_config_.has_value() || (broadcast_config_->subgroups.size() == 0)) {
1323 log::error("Codec was not configured properly");
1324 return;
1325 }
1326
1327 /* Note: Currently we support only a single subgroup.
1328 * In future consider mirroring the same data in a different quality
1329 * subgroups.
1330 */
1331 auto const& subgroup_config = broadcast_config_->subgroups.at(0);
1332
1333 /* Constants for the channel data configuration */
1334 const auto num_bis = subgroup_config.GetNumBis();
1335 const auto bytes_per_sample = (subgroup_config.GetBitsPerSample() / 8);
1336
1337 /* Prepare encoded data for all channels */
1338 for (uint8_t bis_idx = 0; bis_idx < num_bis; ++bis_idx) {
1339 auto initial_channel_offset = bis_idx * bytes_per_sample;
1340 sw_enc_[bis_idx]->Encode(data.data() + initial_channel_offset, num_bis,
1341 subgroup_config.GetBisOctetsPerCodecFrame(bis_idx));
1342 }
1343
1344 /* Currently there is no way to broadcast multiple distinct streams.
1345 * We just receive all system sounds mixed into a one stream and each
1346 * broadcast gets the same data.
1347 */
1348 for (auto& broadcast_pair : instance->broadcasts_) {
1349 auto& broadcast = broadcast_pair.second;
1350 if ((broadcast->GetState() == BroadcastStateMachine::State::STREAMING) &&
1351 !broadcast->IsMuted()) {
1352 sendBroadcastData(broadcast, sw_enc_);
1353 }
1354 }
1355 log::verbose("All data sent.");
1356 }
1357
OnAudioSuspend(void)1358 virtual void OnAudioSuspend(void) override {
1359 log::info("");
1360 if (!instance) {
1361 return;
1362 }
1363
1364 if (instance->audio_state_ == AudioState::STOPPED) {
1365 log::warn("audio stopped, skip suspend request");
1366 return;
1367 }
1368
1369 instance->audio_state_ = AudioState::SUSPENDED;
1370 if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
1371 instance->UpdateAudioActiveStateInPublicAnnouncement();
1372 instance->setBroadcastTimers();
1373 }
1374 }
1375
OnAudioResume(void)1376 virtual void OnAudioResume(void) override {
1377 log::info("");
1378 if (!instance) {
1379 return;
1380 }
1381
1382 if (instance->audio_state_ == AudioState::STOPPED) {
1383 log::warn("audio stopped, skip resume request");
1384 instance->le_audio_source_hal_client_->CancelStreamingRequest();
1385 return;
1386 }
1387
1388 instance->audio_state_ = AudioState::ACTIVE;
1389 if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
1390 if (instance->broadcasts_.empty()) {
1391 log::warn("No broadcasts are ready to resume (pending: {} broadcasts)",
1392 instance->pending_broadcasts_.size());
1393 instance->le_audio_source_hal_client_->CancelStreamingRequest();
1394 return;
1395 }
1396
1397 instance->cancelBroadcastTimers();
1398 instance->UpdateAudioActiveStateInPublicAnnouncement();
1399
1400 /* In case of double call of resume when broadcast are already in streaming states */
1401 if (IsAnyoneStreaming()) {
1402 log::debug("broadcasts are already streaming");
1403 instance->le_audio_source_hal_client_->ConfirmStreamingRequest();
1404 return;
1405 }
1406
1407 for (auto& broadcast_pair : instance->broadcasts_) {
1408 auto& broadcast = broadcast_pair.second;
1409 broadcast->ProcessMessage(BroadcastStateMachine::Message::START, nullptr);
1410 }
1411 } else {
1412 if (!IsAnyoneStreaming()) {
1413 instance->le_audio_source_hal_client_->CancelStreamingRequest();
1414 return;
1415 }
1416
1417 instance->le_audio_source_hal_client_->ConfirmStreamingRequest();
1418 }
1419 }
1420
OnAudioMetadataUpdate(const std::vector<struct playback_track_metadata_v7> source_metadata,DsaMode)1421 virtual void OnAudioMetadataUpdate(
1422 const std::vector<struct playback_track_metadata_v7> source_metadata,
1423 DsaMode /*dsa_mode*/) override {
1424 log::info("");
1425 if (!instance) {
1426 return;
1427 }
1428
1429 /* TODO: Should we take supported contexts from ASCS? */
1430 auto contexts = GetAudioContextsFromSourceMetadata(source_metadata);
1431 if (contexts.any()) {
1432 /* NOTICE: We probably don't want to change the stream configuration
1433 * on each metadata change, so just update the context type metadata.
1434 * Since we are not able to identify individual track streams and
1435 * they are all mixed inside a single data stream, we will update
1436 * the metadata of all BIS subgroups with the same combined context.
1437 */
1438 instance->UpdateStreamingContextTypeOnAllSubgroups(contexts);
1439 }
1440 }
1441
1442 private:
1443 std::optional<BroadcastConfiguration> broadcast_config_;
1444 std::vector<std::unique_ptr<bluetooth::le_audio::CodecInterface>> sw_enc_;
1445 } audio_receiver_;
1446
1447 bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_;
1448 std::map<uint32_t, std::unique_ptr<BroadcastStateMachine>> broadcasts_;
1449 std::vector<std::unique_ptr<BroadcastStateMachine>> pending_broadcasts_;
1450 std::optional<BroadcastStateMachineConfig> queued_create_broadcast_request_;
1451 std::optional<uint32_t> queued_start_broadcast_request_;
1452
1453 /* Some BIG params are set globally */
1454 uint8_t current_phy_;
1455 std::unique_ptr<LeAudioSourceAudioHalClient> le_audio_source_hal_client_;
1456 std::vector<BroadcastId> available_broadcast_ids_;
1457
1458 // Current state of audio playback
1459 AudioState audio_state_;
1460
1461 // Flag to track iso state
1462 bool is_iso_running_ = false;
1463
1464 static constexpr uint64_t kBigTerminateTimeoutMs = 10 * 1000;
1465 static constexpr uint64_t kBroadcastStopTimeoutMs = 30 * 60 * 1000;
1466 alarm_t* big_terminate_timer_;
1467 alarm_t* broadcast_stop_timer_;
1468 };
1469
1470 /* Static members definitions */
1471 LeAudioBroadcasterImpl::BroadcastStateMachineCallbacks
1472 LeAudioBroadcasterImpl::state_machine_callbacks_;
1473 LeAudioBroadcasterImpl::LeAudioSourceCallbacksImpl LeAudioBroadcasterImpl::audio_receiver_;
1474 LeAudioBroadcasterImpl::BroadcastAdvertisingCallbacks
1475 LeAudioBroadcasterImpl::state_machine_adv_callbacks_;
1476 } /* namespace */
1477
Initialize(bluetooth::le_audio::LeAudioBroadcasterCallbacks * callbacks,base::Callback<bool ()> audio_hal_verifier)1478 void LeAudioBroadcaster::Initialize(bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks,
1479 base::Callback<bool()> audio_hal_verifier) {
1480 std::scoped_lock<std::mutex> lock(instance_mutex);
1481 log::info("");
1482 if (instance) {
1483 log::error("Already initialized");
1484 return;
1485 }
1486
1487 if (!bluetooth::shim::GetController()->SupportsBleIsochronousBroadcaster() &&
1488 !osi_property_get_bool("persist.bluetooth.fake_iso_support", false)) {
1489 log::warn("Isochronous Broadcast not supported by the controller!");
1490 return;
1491 }
1492
1493 if (!std::move(audio_hal_verifier).Run()) {
1494 log::fatal("HAL requirements not met. Init aborted.");
1495 }
1496
1497 IsoManager::GetInstance()->Start();
1498
1499 instance = new LeAudioBroadcasterImpl(callbacks);
1500 /* Register HCI event handlers */
1501 IsoManager::GetInstance()->RegisterBigCallbacks(instance);
1502 /* Register for active traffic */
1503 IsoManager::GetInstance()->RegisterOnIsoTrafficActiveCallback([](bool is_active) {
1504 if (instance) {
1505 instance->IsoTrafficEventCb(is_active);
1506 }
1507 });
1508 }
1509
IsLeAudioBroadcasterRunning()1510 bool LeAudioBroadcaster::IsLeAudioBroadcasterRunning() { return instance; }
1511
Get(void)1512 LeAudioBroadcaster* LeAudioBroadcaster::Get(void) {
1513 log::info("");
1514 log::assert_that(instance != nullptr, "assert failed: instance != nullptr");
1515 return instance;
1516 }
1517
Stop(void)1518 void LeAudioBroadcaster::Stop(void) {
1519 log::info("");
1520
1521 if (instance) {
1522 instance->Stop();
1523 }
1524 }
1525
Cleanup(void)1526 void LeAudioBroadcaster::Cleanup(void) {
1527 std::scoped_lock<std::mutex> lock(instance_mutex);
1528 log::info("");
1529
1530 if (instance == nullptr) {
1531 return;
1532 }
1533
1534 LeAudioBroadcasterImpl* ptr = instance;
1535 instance = nullptr;
1536
1537 ptr->CleanUp();
1538 delete ptr;
1539 }
1540
DebugDump(int fd)1541 void LeAudioBroadcaster::DebugDump(int fd) {
1542 std::scoped_lock<std::mutex> lock(instance_mutex);
1543 dprintf(fd, "Le Audio Broadcaster:\n");
1544 if (instance) {
1545 instance->Dump(fd);
1546 }
1547 dprintf(fd, "\n");
1548 }
1549