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