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 "BTAudioLeAudioHIDL"
19
20 #include "le_audio_software_hidl.h"
21
22 #include <bluetooth/log.h>
23
24 #include "os/log.h"
25
26 namespace bluetooth {
27 namespace audio {
28 namespace hidl {
29 namespace le_audio {
30
31 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
32 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
33 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
34 using ::bluetooth::audio::hidl::SampleRate_2_1;
35 using ::bluetooth::audio::hidl::SessionType;
36 using ::bluetooth::audio::hidl::SessionType_2_1;
37
38 using ::bluetooth::audio::le_audio::LeAudioClientInterface;
39 using ::bluetooth::audio::le_audio::StartRequestState;
40 using ::bluetooth::le_audio::DsaMode;
41
42 /**
43 * Helper utils
44 **/
45
le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1)46 static SampleRate_2_1 le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1) {
47 switch (sample_rate_2_1) {
48 case 8000:
49 return SampleRate_2_1::RATE_8000;
50 case 16000:
51 return SampleRate_2_1::RATE_16000;
52 case 24000:
53 return SampleRate_2_1::RATE_24000;
54 case 32000:
55 return SampleRate_2_1::RATE_32000;
56 case 44100:
57 return SampleRate_2_1::RATE_44100;
58 case 48000:
59 return SampleRate_2_1::RATE_48000;
60 case 88200:
61 return SampleRate_2_1::RATE_88200;
62 case 96000:
63 return SampleRate_2_1::RATE_96000;
64 case 176400:
65 return SampleRate_2_1::RATE_176400;
66 case 192000:
67 return SampleRate_2_1::RATE_192000;
68 };
69 return SampleRate_2_1::RATE_UNKNOWN;
70 }
71
le_audio_bits_per_sample2audio_hal(uint8_t bits_per_sample)72 static BitsPerSample le_audio_bits_per_sample2audio_hal(
73 uint8_t bits_per_sample) {
74 switch (bits_per_sample) {
75 case 16:
76 return BitsPerSample::BITS_16;
77 case 24:
78 return BitsPerSample::BITS_24;
79 case 32:
80 return BitsPerSample::BITS_32;
81 };
82 return BitsPerSample::BITS_UNKNOWN;
83 }
84
le_audio_channel_mode2audio_hal(uint8_t channels_count)85 static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
86 switch (channels_count) {
87 case 1:
88 return ChannelMode::MONO;
89 case 2:
90 return ChannelMode::STEREO;
91 }
92 return ChannelMode::UNKNOWN;
93 }
94
is_source_hal_enabled()95 bool is_source_hal_enabled() {
96 return LeAudioSourceTransport::interface != nullptr;
97 }
98
is_sink_hal_enabled()99 bool is_sink_hal_enabled() {
100 return LeAudioSinkTransport::interface != nullptr;
101 }
102
LeAudioTransport(void (* flush)(void),StreamCallbacks stream_cb,PcmParameters pcm_config)103 LeAudioTransport::LeAudioTransport(void (*flush)(void),
104 StreamCallbacks stream_cb,
105 PcmParameters pcm_config)
106 : flush_(std::move(flush)),
107 stream_cb_(std::move(stream_cb)),
108 remote_delay_report_ms_(0),
109 total_bytes_processed_(0),
110 data_position_({}),
111 pcm_config_(std::move(pcm_config)),
112 start_request_state_(StartRequestState::IDLE){};
113
StartRequest()114 BluetoothAudioCtrlAck LeAudioTransport::StartRequest() {
115 SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
116 if (stream_cb_.on_resume_(true)) {
117 if (start_request_state_ == StartRequestState::CONFIRMED) {
118 log::info("Start completed.");
119 SetStartRequestState(StartRequestState::IDLE);
120 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
121 }
122
123 if (start_request_state_ == StartRequestState::CANCELED) {
124 log::info("Start request failed.");
125 SetStartRequestState(StartRequestState::IDLE);
126 return BluetoothAudioCtrlAck::FAILURE;
127 }
128
129 log::info("Start pending.");
130 SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME);
131 return BluetoothAudioCtrlAck::PENDING;
132 }
133
134 log::error("Start request failed.");
135 SetStartRequestState(StartRequestState::IDLE);
136 return BluetoothAudioCtrlAck::FAILURE;
137 }
138
StartRequestV2()139 BluetoothAudioCtrlAck LeAudioTransport::StartRequestV2() {
140 SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
141 if (stream_cb_.on_resume_(true)) {
142 std::lock_guard<std::mutex> guard(start_request_state_mutex_);
143 if (start_request_state_ == StartRequestState::CONFIRMED) {
144 log::info("Start completed.");
145 SetStartRequestState(StartRequestState::IDLE);
146 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
147 }
148
149 if (start_request_state_ == StartRequestState::CANCELED) {
150 log::info("Start request failed.");
151 SetStartRequestState(StartRequestState::IDLE);
152 return BluetoothAudioCtrlAck::FAILURE;
153 }
154
155 log::info("Start pending.");
156 SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME);
157 return BluetoothAudioCtrlAck::PENDING;
158 }
159
160 log::error("Start request failed.");
161 SetStartRequestState(StartRequestState::IDLE);
162 return BluetoothAudioCtrlAck::FAILURE;
163 }
164
SuspendRequest()165 BluetoothAudioCtrlAck LeAudioTransport::SuspendRequest() {
166 log::info("");
167 if (stream_cb_.on_suspend_()) {
168 flush_();
169 return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
170 } else {
171 return BluetoothAudioCtrlAck::FAILURE;
172 }
173 }
174
StopRequest()175 void LeAudioTransport::StopRequest() {
176 log::info("");
177 if (stream_cb_.on_suspend_()) {
178 flush_();
179 }
180 }
181
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_processed,timespec * data_position)182 bool LeAudioTransport::GetPresentationPosition(uint64_t* remote_delay_report_ns,
183 uint64_t* total_bytes_processed,
184 timespec* data_position) {
185 log::verbose("data={} byte(s), timestamp={}.{}s, delay report={} msec.",
186 total_bytes_processed_, data_position_.tv_sec,
187 data_position_.tv_nsec, remote_delay_report_ms_);
188 if (remote_delay_report_ns != nullptr) {
189 *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
190 }
191 if (total_bytes_processed != nullptr)
192 *total_bytes_processed = total_bytes_processed_;
193 if (data_position != nullptr) *data_position = data_position_;
194
195 return true;
196 }
197
MetadataChanged(const source_metadata_t & source_metadata)198 void LeAudioTransport::MetadataChanged(
199 const source_metadata_t& source_metadata) {
200 auto track_count = source_metadata.track_count;
201
202 if (track_count == 0) {
203 log::warn(", invalid number of metadata changed tracks");
204 return;
205 }
206 std::vector<playback_track_metadata_v7> tracks_vec;
207 tracks_vec.reserve(track_count);
208 for (size_t i = 0; i < track_count; i++) {
209 tracks_vec.push_back({
210 .base =
211 {
212 .usage = source_metadata.tracks[i].usage,
213 .content_type = source_metadata.tracks[i].content_type,
214 .gain = source_metadata.tracks[i].gain,
215 },
216 });
217 }
218 const source_metadata_v7_t source_metadata_v7 = {
219 .track_count = tracks_vec.size(), .tracks = tracks_vec.data()};
220
221 stream_cb_.on_metadata_update_(source_metadata_v7, DsaMode::DISABLED);
222 }
223
ResetPresentationPosition()224 void LeAudioTransport::ResetPresentationPosition() {
225 log::verbose("called.");
226 remote_delay_report_ms_ = 0;
227 total_bytes_processed_ = 0;
228 data_position_ = {};
229 }
230
LogBytesProcessed(size_t bytes_processed)231 void LeAudioTransport::LogBytesProcessed(size_t bytes_processed) {
232 if (bytes_processed) {
233 total_bytes_processed_ += bytes_processed;
234 clock_gettime(CLOCK_MONOTONIC, &data_position_);
235 }
236 }
237
SetRemoteDelay(uint16_t delay_report_ms)238 void LeAudioTransport::SetRemoteDelay(uint16_t delay_report_ms) {
239 log::info("delay_report={} msec", delay_report_ms);
240 remote_delay_report_ms_ = delay_report_ms;
241 }
242
LeAudioGetSelectedHalPcmConfig()243 const PcmParameters& LeAudioTransport::LeAudioGetSelectedHalPcmConfig() {
244 return pcm_config_;
245 }
246
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)247 void LeAudioTransport::LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,
248 uint8_t bit_rate,
249 uint8_t channels_count,
250 uint32_t data_interval) {
251 pcm_config_.sampleRate = le_audio_sample_rate2audio_hal(sample_rate_hz);
252 pcm_config_.bitsPerSample = le_audio_bits_per_sample2audio_hal(bit_rate);
253 pcm_config_.channelMode = le_audio_channel_mode2audio_hal(channels_count);
254 pcm_config_.dataIntervalUs = data_interval;
255 }
256
IsRequestCompletedAfterUpdate(const std::function<std::pair<StartRequestState,bool> (StartRequestState)> & lambda)257 bool LeAudioTransport::IsRequestCompletedAfterUpdate(
258 const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
259 lambda) {
260 std::lock_guard<std::mutex> guard(start_request_state_mutex_);
261 auto result = lambda(start_request_state_);
262 auto new_state = std::get<0>(result);
263 if (new_state != start_request_state_) {
264 start_request_state_ = new_state;
265 }
266
267 auto ret = std::get<1>(result);
268 log::verbose("new state: {}, return: {}",
269 static_cast<int>(start_request_state_.load()), ret);
270 return ret;
271 }
272
GetStartRequestState(void)273 StartRequestState LeAudioTransport::GetStartRequestState(void) {
274 return start_request_state_;
275 }
ClearStartRequestState(void)276 void LeAudioTransport::ClearStartRequestState(void) {
277 start_request_state_ = StartRequestState::IDLE;
278 }
SetStartRequestState(StartRequestState state)279 void LeAudioTransport::SetStartRequestState(StartRequestState state) {
280 start_request_state_ = state;
281 }
282
flush_sink()283 void flush_sink() {
284 if (!is_sink_hal_enabled()) return;
285
286 LeAudioSinkTransport::interface->FlushAudioData();
287 }
288
LeAudioSinkTransport(SessionType_2_1 session_type,StreamCallbacks stream_cb)289 LeAudioSinkTransport::LeAudioSinkTransport(SessionType_2_1 session_type,
290 StreamCallbacks stream_cb)
291 : IBluetoothSinkTransportInstance(session_type, {}) {
292 transport_ =
293 new LeAudioTransport(flush_sink, std::move(stream_cb),
294 {SampleRate_2_1::RATE_16000, ChannelMode::STEREO,
295 BitsPerSample::BITS_16, 0});
296 };
297
~LeAudioSinkTransport()298 LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; }
299
StartRequest()300 BluetoothAudioCtrlAck LeAudioSinkTransport::StartRequest() {
301 if (com::android::bluetooth::flags::leaudio_start_stream_race_fix()) {
302 return transport_->StartRequestV2();
303 }
304 return transport_->StartRequest();
305 }
306
SuspendRequest()307 BluetoothAudioCtrlAck LeAudioSinkTransport::SuspendRequest() {
308 return transport_->SuspendRequest();
309 }
310
StopRequest()311 void LeAudioSinkTransport::StopRequest() { transport_->StopRequest(); }
312
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)313 bool LeAudioSinkTransport::GetPresentationPosition(
314 uint64_t* remote_delay_report_ns, uint64_t* total_bytes_read,
315 timespec* data_position) {
316 return transport_->GetPresentationPosition(remote_delay_report_ns,
317 total_bytes_read, data_position);
318 }
319
MetadataChanged(const source_metadata_t & source_metadata)320 void LeAudioSinkTransport::MetadataChanged(
321 const source_metadata_t& source_metadata) {
322 transport_->MetadataChanged(source_metadata);
323 }
324
ResetPresentationPosition()325 void LeAudioSinkTransport::ResetPresentationPosition() {
326 transport_->ResetPresentationPosition();
327 }
328
LogBytesRead(size_t bytes_read)329 void LeAudioSinkTransport::LogBytesRead(size_t bytes_read) {
330 transport_->LogBytesProcessed(bytes_read);
331 }
332
SetRemoteDelay(uint16_t delay_report_ms)333 void LeAudioSinkTransport::SetRemoteDelay(uint16_t delay_report_ms) {
334 transport_->SetRemoteDelay(delay_report_ms);
335 }
336
LeAudioGetSelectedHalPcmConfig()337 const PcmParameters& LeAudioSinkTransport::LeAudioGetSelectedHalPcmConfig() {
338 return transport_->LeAudioGetSelectedHalPcmConfig();
339 }
340
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)341 void LeAudioSinkTransport::LeAudioSetSelectedHalPcmConfig(
342 uint32_t sample_rate_hz, uint8_t bit_rate, uint8_t channels_count,
343 uint32_t data_interval) {
344 transport_->LeAudioSetSelectedHalPcmConfig(sample_rate_hz, bit_rate,
345 channels_count, data_interval);
346 }
347
IsRequestCompletedAfterUpdate(const std::function<std::pair<StartRequestState,bool> (StartRequestState)> & lambda)348 bool LeAudioSinkTransport::IsRequestCompletedAfterUpdate(
349 const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
350 lambda) {
351 return transport_->IsRequestCompletedAfterUpdate(lambda);
352 }
353
GetStartRequestState(void)354 StartRequestState LeAudioSinkTransport::GetStartRequestState(void) {
355 return transport_->GetStartRequestState();
356 }
ClearStartRequestState(void)357 void LeAudioSinkTransport::ClearStartRequestState(void) {
358 transport_->ClearStartRequestState();
359 }
SetStartRequestState(StartRequestState state)360 void LeAudioSinkTransport::SetStartRequestState(StartRequestState state) {
361 transport_->SetStartRequestState(state);
362 }
363
flush_source()364 void flush_source() {
365 if (LeAudioSourceTransport::interface == nullptr) return;
366
367 LeAudioSourceTransport::interface->FlushAudioData();
368 }
369
LeAudioSourceTransport(SessionType_2_1 session_type,StreamCallbacks stream_cb)370 LeAudioSourceTransport::LeAudioSourceTransport(SessionType_2_1 session_type,
371 StreamCallbacks stream_cb)
372 : IBluetoothSourceTransportInstance(session_type, {}) {
373 transport_ =
374 new LeAudioTransport(flush_source, std::move(stream_cb),
375 {SampleRate_2_1::RATE_16000, ChannelMode::MONO,
376 BitsPerSample::BITS_16, 0});
377 };
378
~LeAudioSourceTransport()379 LeAudioSourceTransport::~LeAudioSourceTransport() { delete transport_; }
380
StartRequest()381 BluetoothAudioCtrlAck LeAudioSourceTransport::StartRequest() {
382 if (com::android::bluetooth::flags::leaudio_start_stream_race_fix()) {
383 return transport_->StartRequestV2();
384 }
385 return transport_->StartRequest();
386 }
387
SuspendRequest()388 BluetoothAudioCtrlAck LeAudioSourceTransport::SuspendRequest() {
389 return transport_->SuspendRequest();
390 }
391
StopRequest()392 void LeAudioSourceTransport::StopRequest() { transport_->StopRequest(); }
393
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_written,timespec * data_position)394 bool LeAudioSourceTransport::GetPresentationPosition(
395 uint64_t* remote_delay_report_ns, uint64_t* total_bytes_written,
396 timespec* data_position) {
397 return transport_->GetPresentationPosition(
398 remote_delay_report_ns, total_bytes_written, data_position);
399 }
400
MetadataChanged(const source_metadata_t & source_metadata)401 void LeAudioSourceTransport::MetadataChanged(
402 const source_metadata_t& source_metadata) {
403 transport_->MetadataChanged(source_metadata);
404 }
405
ResetPresentationPosition()406 void LeAudioSourceTransport::ResetPresentationPosition() {
407 transport_->ResetPresentationPosition();
408 }
409
LogBytesWritten(size_t bytes_written)410 void LeAudioSourceTransport::LogBytesWritten(size_t bytes_written) {
411 transport_->LogBytesProcessed(bytes_written);
412 }
413
SetRemoteDelay(uint16_t delay_report_ms)414 void LeAudioSourceTransport::SetRemoteDelay(uint16_t delay_report_ms) {
415 transport_->SetRemoteDelay(delay_report_ms);
416 }
417
LeAudioGetSelectedHalPcmConfig()418 const PcmParameters& LeAudioSourceTransport::LeAudioGetSelectedHalPcmConfig() {
419 return transport_->LeAudioGetSelectedHalPcmConfig();
420 }
421
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)422 void LeAudioSourceTransport::LeAudioSetSelectedHalPcmConfig(
423 uint32_t sample_rate_hz, uint8_t bit_rate, uint8_t channels_count,
424 uint32_t data_interval) {
425 transport_->LeAudioSetSelectedHalPcmConfig(sample_rate_hz, bit_rate,
426 channels_count, data_interval);
427 }
428
IsRequestCompletedAfterUpdate(const std::function<std::pair<StartRequestState,bool> (StartRequestState)> & lambda)429 bool LeAudioSourceTransport::IsRequestCompletedAfterUpdate(
430 const std::function<std::pair<StartRequestState, bool>(StartRequestState)>&
431 lambda) {
432 return transport_->IsRequestCompletedAfterUpdate(lambda);
433 }
GetStartRequestState(void)434 StartRequestState LeAudioSourceTransport::GetStartRequestState(void) {
435 return transport_->GetStartRequestState();
436 }
ClearStartRequestState(void)437 void LeAudioSourceTransport::ClearStartRequestState(void) {
438 transport_->ClearStartRequestState();
439 }
SetStartRequestState(StartRequestState state)440 void LeAudioSourceTransport::SetStartRequestState(StartRequestState state) {
441 transport_->SetStartRequestState(state);
442 }
443 } // namespace le_audio
444 } // namespace hidl
445 } // namespace audio
446 } // namespace bluetooth
447