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