1 /*
2 * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3 * 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 #define LOG_TAG "BTAudioLeAudioAIDL"
19
20 #include "le_audio_software_aidl.h"
21
22 #include <bluetooth/log.h>
23 #include <com_android_bluetooth_flags.h>
24
25 #include <atomic>
26 #include <bitset>
27 #include <unordered_map>
28 #include <vector>
29
30 #include "codec_status_aidl.h"
31 #include "hal_version_manager.h"
32 #include "os/log.h"
33
34 namespace bluetooth {
35 namespace audio {
36 namespace aidl {
37 namespace le_audio {
38
39 using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
40 using ::aidl::android::hardware::bluetooth::audio::AudioLocation;
41 using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
42 using ::aidl::android::hardware::bluetooth::audio::CodecType;
43 using ::aidl::android::hardware::bluetooth::audio::Lc3Configuration;
44 using ::aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
45 using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
46 using ::bluetooth::audio::aidl::AudioConfiguration;
47 using ::bluetooth::audio::aidl::BluetoothAudioCtrlAck;
48 using ::bluetooth::audio::le_audio::LeAudioClientInterface;
49 using ::bluetooth::audio::le_audio::StartRequestState;
50 using ::bluetooth::audio::le_audio::StreamCallbacks;
51 using ::bluetooth::le_audio::set_configurations::AseConfiguration;
52 using ::bluetooth::le_audio::types::LeAudioCoreCodecConfig;
53
le_audio_channel_mode2audio_hal(uint8_t channels_count)54 static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
55 switch (channels_count) {
56 case 1:
57 return ChannelMode::MONO;
58 case 2:
59 return ChannelMode::STEREO;
60 }
61 return ChannelMode::UNKNOWN;
62 }
63
LeAudioTransport(void (* flush)(void),StreamCallbacks stream_cb,PcmConfiguration pcm_config)64 LeAudioTransport::LeAudioTransport(void (*flush)(void),
65 StreamCallbacks stream_cb,
66 PcmConfiguration pcm_config)
67 : flush_(std::move(flush)),
68 stream_cb_(std::move(stream_cb)),
69 remote_delay_report_ms_(0),
70 total_bytes_processed_(0),
71 data_position_({}),
72 pcm_config_(std::move(pcm_config)),
73 start_request_state_(StartRequestState::IDLE),
74 dsa_mode_(DsaMode::DISABLED),
75 cached_source_metadata_({}){};
76
~LeAudioTransport()77 LeAudioTransport::~LeAudioTransport() {
78 if (cached_source_metadata_.tracks != nullptr) {
79 free(cached_source_metadata_.tracks);
80 cached_source_metadata_.tracks = nullptr;
81 }
82 }
83
StartRequest(bool)84 BluetoothAudioCtrlAck LeAudioTransport::StartRequest(bool /*is_low_latency*/) {
85 // Check if operation is pending already
86 if (GetStartRequestState() == StartRequestState::PENDING_AFTER_RESUME) {
87 log::info("Start request is already pending. Ignore the request");
88 return BluetoothAudioCtrlAck::PENDING;
89 }
90
91 SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
92 if (stream_cb_.on_resume_(true)) {
93 auto expected = StartRequestState::CONFIRMED;
94 if (std::atomic_compare_exchange_strong(&start_request_state_, &expected,
95 StartRequestState::IDLE)) {
96 log::info("Start completed.");
97 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
98 }
99
100 expected = StartRequestState::CANCELED;
101 if (std::atomic_compare_exchange_strong(&start_request_state_, &expected,
102 StartRequestState::IDLE)) {
103 log::info("Start request failed.");
104 return BluetoothAudioCtrlAck::FAILURE;
105 }
106
107 expected = StartRequestState::PENDING_BEFORE_RESUME;
108 if (std::atomic_compare_exchange_strong(
109 &start_request_state_, &expected,
110 StartRequestState::PENDING_AFTER_RESUME)) {
111 log::info("Start pending.");
112 return BluetoothAudioCtrlAck::PENDING;
113 }
114 }
115
116 log::error("Start request failed.");
117 auto expected = StartRequestState::PENDING_BEFORE_RESUME;
118 std::atomic_compare_exchange_strong(&start_request_state_, &expected,
119 StartRequestState::IDLE);
120 return BluetoothAudioCtrlAck::FAILURE;
121 }
122
StartRequestV2(bool)123 BluetoothAudioCtrlAck LeAudioTransport::StartRequestV2(
124 bool /*is_low_latency*/) {
125 // Check if operation is pending already
126 if (GetStartRequestState() == StartRequestState::PENDING_AFTER_RESUME) {
127 log::info("Start request is already pending. Ignore the request");
128 return BluetoothAudioCtrlAck::PENDING;
129 }
130
131 SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
132 if (stream_cb_.on_resume_(true)) {
133 std::lock_guard<std::mutex> guard(start_request_state_mutex_);
134
135 switch (start_request_state_) {
136 case StartRequestState::CONFIRMED:
137 log::info("Start completed.");
138 SetStartRequestState(StartRequestState::IDLE);
139 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
140 case StartRequestState::CANCELED:
141 log::info("Start request failed.");
142 SetStartRequestState(StartRequestState::IDLE);
143 return BluetoothAudioCtrlAck::FAILURE;
144 case StartRequestState::PENDING_BEFORE_RESUME:
145 log::info("Start pending.");
146 SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME);
147 return BluetoothAudioCtrlAck::PENDING;
148 default:
149 SetStartRequestState(StartRequestState::IDLE);
150 log::error("Unexpected state {}",
151 static_cast<int>(start_request_state_.load()));
152 return BluetoothAudioCtrlAck::FAILURE;
153 }
154 }
155
156 SetStartRequestState(StartRequestState::IDLE);
157 log::info("On resume failed.");
158 return BluetoothAudioCtrlAck::FAILURE;
159 }
160
SuspendRequest()161 BluetoothAudioCtrlAck LeAudioTransport::SuspendRequest() {
162 log::info("");
163 if (stream_cb_.on_suspend_()) {
164 flush_();
165 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
166 } else {
167 return BluetoothAudioCtrlAck::FAILURE;
168 }
169 }
170
StopRequest()171 void LeAudioTransport::StopRequest() {
172 log::info("");
173 if (stream_cb_.on_suspend_()) {
174 flush_();
175 }
176 }
177
SetLatencyMode(LatencyMode latency_mode)178 void LeAudioTransport::SetLatencyMode(LatencyMode latency_mode) {
179 log::debug(
180 "Latency mode: {}",
181 ::aidl::android::hardware::bluetooth::audio::toString(latency_mode));
182
183 DsaMode prev_dsa_mode = dsa_mode_;
184
185 switch (latency_mode) {
186 case LatencyMode::FREE:
187 dsa_mode_ = DsaMode::DISABLED;
188 break;
189 case LatencyMode::LOW_LATENCY:
190 dsa_mode_ = DsaMode::ACL;
191 break;
192 case LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE:
193 dsa_mode_ = DsaMode::ISO_SW;
194 break;
195 case LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE:
196 dsa_mode_ = DsaMode::ISO_HW;
197 break;
198 default:
199 log::warn(", invalid latency mode: {}", (int)latency_mode);
200 return;
201 }
202
203 if (com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
204 if (dsa_mode_ != prev_dsa_mode &&
205 cached_source_metadata_.tracks != nullptr &&
206 cached_source_metadata_.tracks != 0) {
207 log::info(", latency mode changed, update source metadata");
208 stream_cb_.on_metadata_update_(cached_source_metadata_, dsa_mode_);
209 }
210 }
211 }
212
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_processed,timespec * data_position)213 bool LeAudioTransport::GetPresentationPosition(uint64_t* remote_delay_report_ns,
214 uint64_t* total_bytes_processed,
215 timespec* data_position) {
216 log::verbose("data={} byte(s), timestamp={}.{}s, delay report={} msec.",
217 total_bytes_processed_, data_position_.tv_sec,
218 data_position_.tv_nsec, remote_delay_report_ms_);
219 if (remote_delay_report_ns != nullptr) {
220 *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
221 }
222 if (total_bytes_processed != nullptr)
223 *total_bytes_processed = total_bytes_processed_;
224 if (data_position != nullptr) *data_position = data_position_;
225
226 return true;
227 }
228
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)229 void LeAudioTransport::SourceMetadataChanged(
230 const source_metadata_v7_t& source_metadata) {
231 auto track_count = source_metadata.track_count;
232
233 if (track_count == 0) {
234 log::warn(", invalid number of metadata changed tracks");
235 return;
236 }
237
238 if (com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
239 if (cached_source_metadata_.tracks != nullptr) {
240 free(cached_source_metadata_.tracks);
241 cached_source_metadata_.tracks = nullptr;
242 }
243
244 log::info(", caching source metadata");
245
246 playback_track_metadata_v7* tracks;
247 tracks = (playback_track_metadata_v7*)malloc(sizeof(*tracks) * track_count);
248 memcpy(tracks, source_metadata.tracks, sizeof(*tracks) * track_count);
249
250 cached_source_metadata_.track_count = track_count;
251 cached_source_metadata_.tracks = tracks;
252 }
253
254 stream_cb_.on_metadata_update_(source_metadata, dsa_mode_);
255 }
256
SinkMetadataChanged(const sink_metadata_v7_t & sink_metadata)257 void LeAudioTransport::SinkMetadataChanged(
258 const sink_metadata_v7_t& sink_metadata) {
259 auto track_count = sink_metadata.track_count;
260
261 if (track_count == 0) {
262 log::warn(", invalid number of metadata changed tracks");
263 return;
264 }
265
266 if (stream_cb_.on_sink_metadata_update_)
267 stream_cb_.on_sink_metadata_update_(sink_metadata);
268 }
269
ResetPresentationPosition()270 void LeAudioTransport::ResetPresentationPosition() {
271 log::verbose("called.");
272 remote_delay_report_ms_ = 0;
273 total_bytes_processed_ = 0;
274 data_position_ = {};
275 }
276
LogBytesProcessed(size_t bytes_processed)277 void LeAudioTransport::LogBytesProcessed(size_t bytes_processed) {
278 if (bytes_processed) {
279 total_bytes_processed_ += bytes_processed;
280 clock_gettime(CLOCK_MONOTONIC, &data_position_);
281 }
282 }
283
SetRemoteDelay(uint16_t delay_report_ms)284 void LeAudioTransport::SetRemoteDelay(uint16_t delay_report_ms) {
285 log::info("delay_report={} msec", delay_report_ms);
286 remote_delay_report_ms_ = delay_report_ms;
287 }
288
LeAudioGetSelectedHalPcmConfig()289 const PcmConfiguration& LeAudioTransport::LeAudioGetSelectedHalPcmConfig() {
290 return pcm_config_;
291 }
292
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)293 void LeAudioTransport::LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,
294 uint8_t bit_rate,
295 uint8_t channels_count,
296 uint32_t data_interval) {
297 pcm_config_.sampleRateHz = (sample_rate_hz);
298 pcm_config_.bitsPerSample = (bit_rate);
299 pcm_config_.channelMode = le_audio_channel_mode2audio_hal(channels_count);
300 pcm_config_.dataIntervalUs = data_interval;
301 }
302
LeAudioSetBroadcastConfig(const::bluetooth::le_audio::broadcast_offload_config & offload_config)303 void LeAudioTransport::LeAudioSetBroadcastConfig(
304 const ::bluetooth::le_audio::broadcast_offload_config& offload_config) {
305 broadcast_config_.streamMap.resize(0);
306 for (auto& [handle, location] : offload_config.stream_map) {
307 Lc3Configuration lc3_config{
308 .pcmBitDepth = static_cast<int8_t>(offload_config.bits_per_sample),
309 .samplingFrequencyHz =
310 static_cast<int32_t>(offload_config.sampling_rate),
311 .frameDurationUs = static_cast<int32_t>(offload_config.frame_duration),
312 .octetsPerFrame = static_cast<int32_t>(offload_config.octets_per_frame),
313 .blocksPerSdu = static_cast<int8_t>(offload_config.blocks_per_sdu),
314 };
315 broadcast_config_.streamMap.push_back({
316 .streamHandle = handle,
317 .audioChannelAllocation = static_cast<int32_t>(location),
318 .leAudioCodecConfig = std::move(lc3_config),
319 });
320 }
321 }
322
323 const LeAudioBroadcastConfiguration&
LeAudioGetBroadcastConfig()324 LeAudioTransport::LeAudioGetBroadcastConfig() {
325 return broadcast_config_;
326 }
327
IsRequestCompletedAfterUpdate(const std::function<std::pair<StartRequestState,bool> (StartRequestState)> & lambda)328 bool LeAudioTransport::IsRequestCompletedAfterUpdate(
329 const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
330 lambda) {
331 std::lock_guard<std::mutex> guard(start_request_state_mutex_);
332 auto result = lambda(start_request_state_);
333 auto new_state = std::get<0>(result);
334 if (new_state != start_request_state_) {
335 start_request_state_ = new_state;
336 }
337
338 auto ret = std::get<1>(result);
339 log::verbose("new state: {}, return {}", (int)(start_request_state_.load()),
340 ret);
341
342 return ret;
343 }
344
GetStartRequestState(void)345 StartRequestState LeAudioTransport::GetStartRequestState(void) {
346 if (com::android::bluetooth::flags::
347 leaudio_start_request_state_mutex_check()) {
348 std::lock_guard<std::mutex> guard(start_request_state_mutex_);
349 }
350 return start_request_state_;
351 }
ClearStartRequestState(void)352 void LeAudioTransport::ClearStartRequestState(void) {
353 start_request_state_ = StartRequestState::IDLE;
354 }
SetStartRequestState(StartRequestState state)355 void LeAudioTransport::SetStartRequestState(StartRequestState state) {
356 start_request_state_ = state;
357 }
358
flush_unicast_sink()359 inline void flush_unicast_sink() {
360 if (LeAudioSinkTransport::interface_unicast_ == nullptr) return;
361
362 LeAudioSinkTransport::interface_unicast_->FlushAudioData();
363 }
364
flush_broadcast_sink()365 inline void flush_broadcast_sink() {
366 if (LeAudioSinkTransport::interface_broadcast_ == nullptr) return;
367
368 LeAudioSinkTransport::interface_broadcast_->FlushAudioData();
369 }
370
is_broadcaster_session(SessionType session_type)371 inline bool is_broadcaster_session(SessionType session_type) {
372 if (session_type ==
373 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
374 session_type ==
375 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH) {
376 return true;
377 }
378
379 return false;
380 }
381
LeAudioSinkTransport(SessionType session_type,StreamCallbacks stream_cb)382 LeAudioSinkTransport::LeAudioSinkTransport(SessionType session_type,
383 StreamCallbacks stream_cb)
384 : IBluetoothSinkTransportInstance(session_type, (AudioConfiguration){}) {
385 transport_ = new LeAudioTransport(
386 is_broadcaster_session(session_type) ? flush_broadcast_sink
387 : flush_unicast_sink,
388 std::move(stream_cb), {16000, ChannelMode::STEREO, 16, 0});
389 };
390
~LeAudioSinkTransport()391 LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; }
392
StartRequest(bool is_low_latency)393 BluetoothAudioCtrlAck LeAudioSinkTransport::StartRequest(bool is_low_latency) {
394 if (com::android::bluetooth::flags::leaudio_start_stream_race_fix()) {
395 return transport_->StartRequestV2(is_low_latency);
396 }
397 return transport_->StartRequest(is_low_latency);
398 }
399
SuspendRequest()400 BluetoothAudioCtrlAck LeAudioSinkTransport::SuspendRequest() {
401 return transport_->SuspendRequest();
402 }
403
StopRequest()404 void LeAudioSinkTransport::StopRequest() { transport_->StopRequest(); }
405
SetLatencyMode(LatencyMode latency_mode)406 void LeAudioSinkTransport::SetLatencyMode(LatencyMode latency_mode) {
407 transport_->SetLatencyMode(latency_mode);
408 }
409
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)410 bool LeAudioSinkTransport::GetPresentationPosition(
411 uint64_t* remote_delay_report_ns, uint64_t* total_bytes_read,
412 timespec* data_position) {
413 return transport_->GetPresentationPosition(remote_delay_report_ns,
414 total_bytes_read, data_position);
415 }
416
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)417 void LeAudioSinkTransport::SourceMetadataChanged(
418 const source_metadata_v7_t& source_metadata) {
419 transport_->SourceMetadataChanged(source_metadata);
420 }
421
SinkMetadataChanged(const sink_metadata_v7_t & sink_metadata)422 void LeAudioSinkTransport::SinkMetadataChanged(
423 const sink_metadata_v7_t& sink_metadata) {
424 transport_->SinkMetadataChanged(sink_metadata);
425 }
426
ResetPresentationPosition()427 void LeAudioSinkTransport::ResetPresentationPosition() {
428 transport_->ResetPresentationPosition();
429 }
430
LogBytesRead(size_t bytes_read)431 void LeAudioSinkTransport::LogBytesRead(size_t bytes_read) {
432 transport_->LogBytesProcessed(bytes_read);
433 }
434
SetRemoteDelay(uint16_t delay_report_ms)435 void LeAudioSinkTransport::SetRemoteDelay(uint16_t delay_report_ms) {
436 transport_->SetRemoteDelay(delay_report_ms);
437 }
438
LeAudioGetSelectedHalPcmConfig()439 const PcmConfiguration& LeAudioSinkTransport::LeAudioGetSelectedHalPcmConfig() {
440 return transport_->LeAudioGetSelectedHalPcmConfig();
441 }
442
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)443 void LeAudioSinkTransport::LeAudioSetSelectedHalPcmConfig(
444 uint32_t sample_rate_hz, uint8_t bit_rate, uint8_t channels_count,
445 uint32_t data_interval) {
446 transport_->LeAudioSetSelectedHalPcmConfig(sample_rate_hz, bit_rate,
447 channels_count, data_interval);
448 }
449
LeAudioSetBroadcastConfig(const::bluetooth::le_audio::broadcast_offload_config & offload_config)450 void LeAudioSinkTransport::LeAudioSetBroadcastConfig(
451 const ::bluetooth::le_audio::broadcast_offload_config& offload_config) {
452 transport_->LeAudioSetBroadcastConfig(offload_config);
453 }
454
455 const LeAudioBroadcastConfiguration&
LeAudioGetBroadcastConfig()456 LeAudioSinkTransport::LeAudioGetBroadcastConfig() {
457 return transport_->LeAudioGetBroadcastConfig();
458 }
459
IsRequestCompletedAfterUpdate(const std::function<std::pair<StartRequestState,bool> (StartRequestState)> & lambda)460 bool LeAudioSinkTransport::IsRequestCompletedAfterUpdate(
461 const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
462 lambda) {
463 return transport_->IsRequestCompletedAfterUpdate(lambda);
464 }
465
GetStartRequestState(void)466 StartRequestState LeAudioSinkTransport::GetStartRequestState(void) {
467 return transport_->GetStartRequestState();
468 }
ClearStartRequestState(void)469 void LeAudioSinkTransport::ClearStartRequestState(void) {
470 transport_->ClearStartRequestState();
471 }
SetStartRequestState(StartRequestState state)472 void LeAudioSinkTransport::SetStartRequestState(StartRequestState state) {
473 transport_->SetStartRequestState(state);
474 }
475
flush_source()476 void flush_source() {
477 if (LeAudioSourceTransport::interface == nullptr) return;
478
479 LeAudioSourceTransport::interface->FlushAudioData();
480 }
481
LeAudioSourceTransport(SessionType session_type,StreamCallbacks stream_cb)482 LeAudioSourceTransport::LeAudioSourceTransport(SessionType session_type,
483 StreamCallbacks stream_cb)
484 : IBluetoothSourceTransportInstance(session_type, (AudioConfiguration){}) {
485 transport_ = new LeAudioTransport(flush_source, std::move(stream_cb),
486 {16000, ChannelMode::STEREO, 16, 0});
487 };
488
~LeAudioSourceTransport()489 LeAudioSourceTransport::~LeAudioSourceTransport() { delete transport_; }
490
StartRequest(bool is_low_latency)491 BluetoothAudioCtrlAck LeAudioSourceTransport::StartRequest(
492 bool is_low_latency) {
493 if (com::android::bluetooth::flags::leaudio_start_stream_race_fix()) {
494 return transport_->StartRequestV2(is_low_latency);
495 }
496 return transport_->StartRequest(is_low_latency);
497 }
498
SuspendRequest()499 BluetoothAudioCtrlAck LeAudioSourceTransport::SuspendRequest() {
500 return transport_->SuspendRequest();
501 }
502
StopRequest()503 void LeAudioSourceTransport::StopRequest() { transport_->StopRequest(); }
504
SetLatencyMode(LatencyMode latency_mode)505 void LeAudioSourceTransport::SetLatencyMode(LatencyMode latency_mode) {
506 transport_->SetLatencyMode(latency_mode);
507 }
508
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_written,timespec * data_position)509 bool LeAudioSourceTransport::GetPresentationPosition(
510 uint64_t* remote_delay_report_ns, uint64_t* total_bytes_written,
511 timespec* data_position) {
512 return transport_->GetPresentationPosition(
513 remote_delay_report_ns, total_bytes_written, data_position);
514 }
515
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)516 void LeAudioSourceTransport::SourceMetadataChanged(
517 const source_metadata_v7_t& source_metadata) {
518 transport_->SourceMetadataChanged(source_metadata);
519 }
520
SinkMetadataChanged(const sink_metadata_v7_t & sink_metadata)521 void LeAudioSourceTransport::SinkMetadataChanged(
522 const sink_metadata_v7_t& sink_metadata) {
523 transport_->SinkMetadataChanged(sink_metadata);
524 }
525
ResetPresentationPosition()526 void LeAudioSourceTransport::ResetPresentationPosition() {
527 transport_->ResetPresentationPosition();
528 }
529
LogBytesWritten(size_t bytes_written)530 void LeAudioSourceTransport::LogBytesWritten(size_t bytes_written) {
531 transport_->LogBytesProcessed(bytes_written);
532 }
533
SetRemoteDelay(uint16_t delay_report_ms)534 void LeAudioSourceTransport::SetRemoteDelay(uint16_t delay_report_ms) {
535 transport_->SetRemoteDelay(delay_report_ms);
536 }
537
538 const PcmConfiguration&
LeAudioGetSelectedHalPcmConfig()539 LeAudioSourceTransport::LeAudioGetSelectedHalPcmConfig() {
540 return transport_->LeAudioGetSelectedHalPcmConfig();
541 }
542
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)543 void LeAudioSourceTransport::LeAudioSetSelectedHalPcmConfig(
544 uint32_t sample_rate_hz, uint8_t bit_rate, uint8_t channels_count,
545 uint32_t data_interval) {
546 transport_->LeAudioSetSelectedHalPcmConfig(sample_rate_hz, bit_rate,
547 channels_count, data_interval);
548 }
549
IsRequestCompletedAfterUpdate(const std::function<std::pair<StartRequestState,bool> (StartRequestState)> & lambda)550 bool LeAudioSourceTransport::IsRequestCompletedAfterUpdate(
551 const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
552 lambda) {
553 return transport_->IsRequestCompletedAfterUpdate(lambda);
554 }
555
GetStartRequestState(void)556 StartRequestState LeAudioSourceTransport::GetStartRequestState(void) {
557 return transport_->GetStartRequestState();
558 }
ClearStartRequestState(void)559 void LeAudioSourceTransport::ClearStartRequestState(void) {
560 transport_->ClearStartRequestState();
561 }
562
SetStartRequestState(StartRequestState state)563 void LeAudioSourceTransport::SetStartRequestState(StartRequestState state) {
564 transport_->SetStartRequestState(state);
565 }
566
567 std::unordered_map<int32_t, uint8_t> sampling_freq_map{
568 {8000, ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq8000Hz},
569 {16000,
570 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq16000Hz},
571 {24000,
572 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq24000Hz},
573 {32000,
574 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq32000Hz},
575 {44100,
576 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq44100Hz},
577 {48000,
578 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq48000Hz},
579 {88200,
580 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq88200Hz},
581 {96000,
582 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq96000Hz},
583 {176400,
584 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq176400Hz},
585 {192000,
586 ::bluetooth::le_audio::codec_spec_conf::kLeAudioSamplingFreq192000Hz}};
587
588 std::unordered_map<int32_t, uint8_t> frame_duration_map{
589 {7500, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameDur7500us},
590 {10000,
591 ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameDur10000us}};
592
593 std::unordered_map<int32_t, uint16_t> octets_per_frame_map{
594 {30, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameLen30},
595 {40, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameLen40},
596 {60, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameLen60},
597 {80, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameLen80},
598 {100, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameLen100},
599 {120, ::bluetooth::le_audio::codec_spec_conf::kLeAudioCodecFrameLen120}};
600
601 std::unordered_map<AudioLocation, uint32_t> audio_location_map{
602 {AudioLocation::UNKNOWN,
603 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontCenter},
604 {AudioLocation::FRONT_LEFT,
605 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft},
606 {AudioLocation::FRONT_RIGHT,
607 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontRight},
608 {static_cast<AudioLocation>(
609 static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
610 static_cast<uint8_t>(AudioLocation::FRONT_RIGHT)),
611 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
612 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontRight}};
613
hal_ucast_capability_to_stack_format(const UnicastCapability & hal_capability,CodecConfigSetting & stack_capability)614 bool hal_ucast_capability_to_stack_format(
615 const UnicastCapability& hal_capability,
616 CodecConfigSetting& stack_capability) {
617 if (hal_capability.codecType != CodecType::LC3) {
618 log::warn("Unsupported codecType: {}", toString(hal_capability.codecType));
619 return false;
620 }
621 if (hal_capability.leAudioCodecCapabilities.getTag() !=
622 UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities) {
623 log::warn("Unknown LE Audio capabilities(vendor proprietary?)");
624 return false;
625 }
626
627 auto& hal_lc3_capability =
628 hal_capability.leAudioCodecCapabilities
629 .get<UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
630 auto supported_channel = hal_capability.supportedChannel;
631 auto sample_rate_hz = hal_lc3_capability.samplingFrequencyHz[0];
632 auto frame_duration_us = hal_lc3_capability.frameDurationUs[0];
633 auto octets_per_frame = hal_lc3_capability.octetsPerFrame[0];
634 auto channel_count = hal_capability.channelCountPerDevice;
635
636 if (sampling_freq_map.find(sample_rate_hz) == sampling_freq_map.end() ||
637 frame_duration_map.find(frame_duration_us) == frame_duration_map.end() ||
638 octets_per_frame_map.find(octets_per_frame) ==
639 octets_per_frame_map.end() ||
640 audio_location_map.find(supported_channel) == audio_location_map.end()) {
641 log::error(
642 "Failed to convert HAL format to stack format\nsample rate hz = "
643 "{}\nframe duration us = {}\noctets per frame= {}\nsupported channel = "
644 "{}\nchannel count per device = {}\ndevice count = {}",
645 sample_rate_hz, frame_duration_us, octets_per_frame,
646 toString(supported_channel), channel_count, hal_capability.deviceCount);
647
648 return false;
649 }
650
651 stack_capability.id =
652 ::bluetooth::le_audio::set_configurations::LeAudioCodecIdLc3;
653 stack_capability.channel_count_per_iso_stream = channel_count;
654
655 stack_capability.params.Add(
656 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLtvTypeSamplingFreq,
657 sampling_freq_map[sample_rate_hz]);
658 stack_capability.params.Add(
659 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLtvTypeFrameDuration,
660 frame_duration_map[frame_duration_us]);
661 stack_capability.params.Add(::bluetooth::le_audio::codec_spec_conf::
662 kLeAudioLtvTypeAudioChannelAllocation,
663 audio_location_map[supported_channel]);
664 stack_capability.params.Add(::bluetooth::le_audio::codec_spec_conf::
665 kLeAudioLtvTypeOctetsPerCodecFrame,
666 octets_per_frame_map[octets_per_frame]);
667 return true;
668 }
669
hal_bcast_capability_to_stack_format(const BroadcastCapability & hal_bcast_capability,CodecConfigSetting & stack_capability)670 bool hal_bcast_capability_to_stack_format(
671 const BroadcastCapability& hal_bcast_capability,
672 CodecConfigSetting& stack_capability) {
673 if (hal_bcast_capability.codecType != CodecType::LC3) {
674 log::warn("Unsupported codecType: {}",
675 toString(hal_bcast_capability.codecType));
676 return false;
677 }
678 if (hal_bcast_capability.leAudioCodecCapabilities.getTag() !=
679 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities) {
680 log::warn("Unknown LE Audio capabilities(vendor proprietary?)");
681 return false;
682 }
683
684 auto& hal_lc3_capabilities =
685 hal_bcast_capability.leAudioCodecCapabilities.get<
686 BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
687
688 if (hal_lc3_capabilities->size() != 1) {
689 log::warn("The number of config is not supported yet.");
690 }
691
692 auto supported_channel = hal_bcast_capability.supportedChannel;
693 auto sample_rate_hz = (*hal_lc3_capabilities)[0]->samplingFrequencyHz[0];
694 auto frame_duration_us = (*hal_lc3_capabilities)[0]->frameDurationUs[0];
695 auto octets_per_frame = (*hal_lc3_capabilities)[0]->octetsPerFrame[0];
696 auto channel_count = hal_bcast_capability.channelCountPerStream;
697
698 if (sampling_freq_map.find(sample_rate_hz) == sampling_freq_map.end() ||
699 frame_duration_map.find(frame_duration_us) == frame_duration_map.end() ||
700 octets_per_frame_map.find(octets_per_frame) ==
701 octets_per_frame_map.end() ||
702 audio_location_map.find(supported_channel) == audio_location_map.end()) {
703 log::warn(
704 "Failed to convert HAL format to stack format\nsample rate hz = "
705 "{}\nframe duration us = {}\noctets per frame= {}\nsupported channel = "
706 "{}\nchannel count per stream = {}",
707 sample_rate_hz, frame_duration_us, octets_per_frame,
708 toString(supported_channel), channel_count);
709
710 return false;
711 }
712
713 stack_capability.id =
714 ::bluetooth::le_audio::set_configurations::LeAudioCodecIdLc3;
715 stack_capability.channel_count_per_iso_stream = channel_count;
716
717 stack_capability.params.Add(
718 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLtvTypeSamplingFreq,
719 sampling_freq_map[sample_rate_hz]);
720 stack_capability.params.Add(
721 ::bluetooth::le_audio::codec_spec_conf::kLeAudioLtvTypeFrameDuration,
722 frame_duration_map[frame_duration_us]);
723 stack_capability.params.Add(::bluetooth::le_audio::codec_spec_conf::
724 kLeAudioLtvTypeAudioChannelAllocation,
725 audio_location_map[supported_channel]);
726 stack_capability.params.Add(::bluetooth::le_audio::codec_spec_conf::
727 kLeAudioLtvTypeOctetsPerCodecFrame,
728 octets_per_frame_map[octets_per_frame]);
729 return true;
730 }
731
get_offload_capabilities()732 bluetooth::audio::le_audio::OffloadCapabilities get_offload_capabilities() {
733 log::info("");
734 std::vector<AudioSetConfiguration> offload_capabilities;
735 std::vector<AudioSetConfiguration> broadcast_offload_capabilities;
736 std::vector<AudioCapabilities> le_audio_hal_capabilities =
737 BluetoothAudioSinkClientInterface::GetAudioCapabilities(
738 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
739 std::string str_capability_log;
740
741 for (auto hal_cap : le_audio_hal_capabilities) {
742 CodecConfigSetting encode_cap, decode_cap, bcast_cap;
743 UnicastCapability hal_encode_cap =
744 hal_cap.get<AudioCapabilities::leAudioCapabilities>()
745 .unicastEncodeCapability;
746 UnicastCapability hal_decode_cap =
747 hal_cap.get<AudioCapabilities::leAudioCapabilities>()
748 .unicastDecodeCapability;
749 BroadcastCapability hal_bcast_cap =
750 hal_cap.get<AudioCapabilities::leAudioCapabilities>()
751 .broadcastCapability;
752 AudioSetConfiguration audio_set_config = {.name = "offload capability"};
753 str_capability_log.clear();
754
755 if (hal_ucast_capability_to_stack_format(hal_encode_cap, encode_cap)) {
756 auto ase_cnt =
757 hal_encode_cap.deviceCount * hal_encode_cap.channelCountPerDevice;
758 while (ase_cnt--) {
759 audio_set_config.confs.sink.push_back(AseConfiguration(encode_cap));
760 }
761 str_capability_log = " Encode Capability: " + hal_encode_cap.toString();
762 }
763
764 if (hal_ucast_capability_to_stack_format(hal_decode_cap, decode_cap)) {
765 auto ase_cnt =
766 hal_decode_cap.deviceCount * hal_decode_cap.channelCountPerDevice;
767 while (ase_cnt--) {
768 audio_set_config.confs.source.push_back(AseConfiguration(decode_cap));
769 }
770 str_capability_log += " Decode Capability: " + hal_decode_cap.toString();
771 }
772
773 if (hal_bcast_capability_to_stack_format(hal_bcast_cap, bcast_cap)) {
774 AudioSetConfiguration audio_set_config = {
775 .name = "broadcast offload capability"};
776 // Note: The offloader config supports multiple channels per stream
777 // (subgroup), corresponding to the number of BISes, where each BIS
778 // has a single channel.
779 bcast_cap.channel_count_per_iso_stream = 1;
780 auto bis_cnt = hal_bcast_cap.channelCountPerStream;
781 while (bis_cnt--) {
782 audio_set_config.confs.sink.push_back(AseConfiguration(bcast_cap));
783 }
784 broadcast_offload_capabilities.push_back(audio_set_config);
785 str_capability_log +=
786 " Broadcast Capability: " + hal_bcast_cap.toString();
787 }
788
789 if (!audio_set_config.confs.sink.empty() ||
790 !audio_set_config.confs.source.empty()) {
791 offload_capabilities.push_back(audio_set_config);
792 log::info("Supported codec capability ={}", str_capability_log);
793
794 } else {
795 log::info("Unknown codec capability ={}", hal_cap.toString());
796 }
797 }
798
799 return {offload_capabilities, broadcast_offload_capabilities};
800 }
801
offload_config_to_hal_audio_config(const::bluetooth::le_audio::offload_config & offload_config)802 AudioConfiguration offload_config_to_hal_audio_config(
803 const ::bluetooth::le_audio::offload_config& offload_config) {
804 Lc3Configuration lc3_config{
805 .pcmBitDepth = static_cast<int8_t>(offload_config.bits_per_sample),
806 .samplingFrequencyHz = static_cast<int32_t>(offload_config.sampling_rate),
807 .frameDurationUs = static_cast<int32_t>(offload_config.frame_duration),
808 .octetsPerFrame = static_cast<int32_t>(offload_config.octets_per_frame),
809 .blocksPerSdu = static_cast<int8_t>(offload_config.blocks_per_sdu),
810 };
811 LeAudioConfiguration ucast_config = {
812 .peerDelayUs = static_cast<int32_t>(offload_config.peer_delay_ms * 1000),
813 .leAudioCodecConfig = LeAudioCodecConfiguration(lc3_config)};
814
815 for (auto& [handle, location, state] : offload_config.stream_map) {
816 ucast_config.streamMap.push_back({
817 .streamHandle = handle,
818 .audioChannelAllocation = static_cast<int32_t>(location),
819 .isStreamActive = state,
820 });
821 }
822
823 return AudioConfiguration(ucast_config);
824 }
825
826 } // namespace le_audio
827 } // namespace aidl
828 } // namespace audio
829 } // namespace bluetooth
830