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