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