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