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