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