• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "BTAudioClientLeAudio"
19 
20 #include "le_audio_software.h"
21 
22 #include "client_interface.h"
23 #include "osi/include/log.h"
24 #include "osi/include/properties.h"
25 
26 namespace {
27 
28 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
29 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
30 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
31 using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
32 using ::bluetooth::audio::BluetoothAudioCtrlAck;
33 using ::bluetooth::audio::SampleRate_2_1;
34 using ::bluetooth::audio::SessionType;
35 using ::bluetooth::audio::SessionType_2_1;
36 using ::bluetooth::audio::le_audio::LeAudioClientInterface;
37 using ::bluetooth::audio::le_audio::StreamCallbacks;
38 
39 bluetooth::audio::BluetoothAudioSinkClientInterface*
40     le_audio_sink_hal_clientinterface = nullptr;
41 bluetooth::audio::BluetoothAudioSourceClientInterface*
42     le_audio_source_hal_clientinterface = nullptr;
43 
is_source_hal_enabled()44 static bool is_source_hal_enabled() {
45   return le_audio_source_hal_clientinterface != nullptr;
46 }
47 
is_sink_hal_enabled()48 static bool is_sink_hal_enabled() {
49   return le_audio_sink_hal_clientinterface != nullptr;
50 }
51 
52 class LeAudioTransport {
53  public:
LeAudioTransport(void (* flush)(void),StreamCallbacks stream_cb,PcmParameters pcm_config)54   LeAudioTransport(void (*flush)(void), StreamCallbacks stream_cb,
55                    PcmParameters pcm_config)
56       : flush_(std::move(flush)),
57         stream_cb_(std::move(stream_cb)),
58         remote_delay_report_ms_(0),
59         total_bytes_processed_(0),
60         data_position_({}),
61         pcm_config_(std::move(pcm_config)){};
62 
StartRequest()63   BluetoothAudioCtrlAck StartRequest() {
64     LOG(INFO) << __func__;
65     if (stream_cb_.on_resume_(true)) {
66       return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
67     }
68     return BluetoothAudioCtrlAck::FAILURE;
69   }
70 
SuspendRequest()71   BluetoothAudioCtrlAck SuspendRequest() {
72     LOG(INFO) << __func__;
73     if (stream_cb_.on_suspend_()) {
74       flush_();
75       return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
76     } else {
77       return BluetoothAudioCtrlAck::FAILURE;
78     }
79   }
80 
StopRequest()81   void StopRequest() {
82     LOG(INFO) << __func__;
83     if (stream_cb_.on_suspend_()) {
84       flush_();
85     }
86   }
87 
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_processed,timespec * data_position)88   bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
89                                uint64_t* total_bytes_processed,
90                                timespec* data_position) {
91     VLOG(2) << __func__ << ": data=" << total_bytes_processed_
92             << " byte(s), timestamp=" << data_position_.tv_sec << "."
93             << data_position_.tv_nsec
94             << "s, delay report=" << remote_delay_report_ms_ << " msec.";
95     if (remote_delay_report_ns != nullptr) {
96       *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
97     }
98     if (total_bytes_processed != nullptr)
99       *total_bytes_processed = total_bytes_processed_;
100     if (data_position != nullptr) *data_position = data_position_;
101 
102     return true;
103   }
104 
MetadataChanged(const source_metadata_t & source_metadata)105   void MetadataChanged(const source_metadata_t& source_metadata) {
106     auto track_count = source_metadata.track_count;
107     auto tracks = source_metadata.tracks;
108     LOG(INFO) << __func__ << ": " << track_count << " track(s) received";
109     while (track_count) {
110       VLOG(1) << __func__ << ": usage=" << tracks->usage
111               << ", content_type=" << tracks->content_type
112               << ", gain=" << tracks->gain;
113       --track_count;
114       ++tracks;
115     }
116   }
117 
ResetPresentationPosition()118   void ResetPresentationPosition() {
119     VLOG(2) << __func__ << ": called.";
120     remote_delay_report_ms_ = 0;
121     total_bytes_processed_ = 0;
122     data_position_ = {};
123   }
124 
LogBytesProcessed(size_t bytes_processed)125   void LogBytesProcessed(size_t bytes_processed) {
126     if (bytes_processed) {
127       total_bytes_processed_ += bytes_processed;
128       clock_gettime(CLOCK_MONOTONIC, &data_position_);
129     }
130   }
131 
SetRemoteDelay(uint16_t delay_report_ms)132   void SetRemoteDelay(uint16_t delay_report_ms) {
133     LOG(INFO) << __func__ << ": delay_report=" << delay_report_ms << " msec";
134     remote_delay_report_ms_ = delay_report_ms;
135   }
136 
LeAudioGetSelectedHalPcmConfig()137   const PcmParameters& LeAudioGetSelectedHalPcmConfig() { return pcm_config_; }
138 
LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,BitsPerSample bit_rate,ChannelMode channel_mode,uint32_t data_interval)139   void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
140                                       BitsPerSample bit_rate,
141                                       ChannelMode channel_mode,
142                                       uint32_t data_interval) {
143     pcm_config_.sampleRate = sample_rate;
144     pcm_config_.bitsPerSample = bit_rate;
145     pcm_config_.channelMode = channel_mode;
146     pcm_config_.dataIntervalUs = data_interval;
147   }
148 
149  private:
150   void (*flush_)(void);
151   StreamCallbacks stream_cb_;
152   uint16_t remote_delay_report_ms_;
153   uint64_t total_bytes_processed_;
154   timespec data_position_;
155   PcmParameters pcm_config_;
156 };
157 
flush_sink()158 static void flush_sink() {
159   if (!is_sink_hal_enabled()) return;
160 
161   le_audio_sink_hal_clientinterface->FlushAudioData();
162 }
163 
164 // Sink transport implementation for Le Audio
165 class LeAudioSinkTransport
166     : public bluetooth::audio::IBluetoothSinkTransportInstance {
167  public:
LeAudioSinkTransport(StreamCallbacks stream_cb)168   LeAudioSinkTransport(StreamCallbacks stream_cb)
169       : IBluetoothSinkTransportInstance(
170             SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, {}) {
171     transport_ =
172         new LeAudioTransport(flush_sink, std::move(stream_cb),
173                              {SampleRate_2_1::RATE_16000, ChannelMode::STEREO,
174                               BitsPerSample::BITS_16, 0});
175   };
176 
~LeAudioSinkTransport()177   ~LeAudioSinkTransport() { delete transport_; }
178 
StartRequest()179   BluetoothAudioCtrlAck StartRequest() override {
180     return transport_->StartRequest();
181   }
182 
SuspendRequest()183   BluetoothAudioCtrlAck SuspendRequest() override {
184     return transport_->SuspendRequest();
185   }
186 
StopRequest()187   void StopRequest() override { transport_->StopRequest(); }
188 
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)189   bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
190                                uint64_t* total_bytes_read,
191                                timespec* data_position) override {
192     return transport_->GetPresentationPosition(remote_delay_report_ns,
193                                                total_bytes_read, data_position);
194   }
195 
MetadataChanged(const source_metadata_t & source_metadata)196   void MetadataChanged(const source_metadata_t& source_metadata) override {
197     transport_->MetadataChanged(source_metadata);
198   }
199 
ResetPresentationPosition()200   void ResetPresentationPosition() override {
201     transport_->ResetPresentationPosition();
202   }
203 
LogBytesRead(size_t bytes_read)204   void LogBytesRead(size_t bytes_read) override {
205     transport_->LogBytesProcessed(bytes_read);
206   }
207 
SetRemoteDelay(uint16_t delay_report_ms)208   void SetRemoteDelay(uint16_t delay_report_ms) {
209     transport_->SetRemoteDelay(delay_report_ms);
210   }
211 
LeAudioGetSelectedHalPcmConfig()212   const PcmParameters& LeAudioGetSelectedHalPcmConfig() {
213     return transport_->LeAudioGetSelectedHalPcmConfig();
214   }
215 
LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,BitsPerSample bit_rate,ChannelMode channel_mode,uint32_t data_interval)216   void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
217                                       BitsPerSample bit_rate,
218                                       ChannelMode channel_mode,
219                                       uint32_t data_interval) {
220     transport_->LeAudioSetSelectedHalPcmConfig(sample_rate, bit_rate,
221                                                channel_mode, data_interval);
222   }
223 
224  private:
225   LeAudioTransport* transport_;
226 };
227 
flush_source()228 static void flush_source() {
229   if (le_audio_source_hal_clientinterface == nullptr) return;
230 
231   le_audio_source_hal_clientinterface->FlushAudioData();
232 }
233 
234 class LeAudioSourceTransport
235     : public bluetooth::audio::IBluetoothSourceTransportInstance {
236  public:
LeAudioSourceTransport(StreamCallbacks stream_cb)237   LeAudioSourceTransport(StreamCallbacks stream_cb)
238       : IBluetoothSourceTransportInstance(
239             SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH, {}) {
240     transport_ =
241         new LeAudioTransport(flush_source, std::move(stream_cb),
242                              {SampleRate_2_1::RATE_16000, ChannelMode::MONO,
243                               BitsPerSample::BITS_16, 0});
244   };
245 
~LeAudioSourceTransport()246   ~LeAudioSourceTransport() { delete transport_; }
247 
StartRequest()248   BluetoothAudioCtrlAck StartRequest() override {
249     return transport_->StartRequest();
250   }
251 
SuspendRequest()252   BluetoothAudioCtrlAck SuspendRequest() override {
253     return transport_->SuspendRequest();
254   }
255 
StopRequest()256   void StopRequest() override { transport_->StopRequest(); }
257 
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_written,timespec * data_position)258   bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
259                                uint64_t* total_bytes_written,
260                                timespec* data_position) override {
261     return transport_->GetPresentationPosition(
262         remote_delay_report_ns, total_bytes_written, data_position);
263   }
264 
MetadataChanged(const source_metadata_t & source_metadata)265   void MetadataChanged(const source_metadata_t& source_metadata) override {
266     transport_->MetadataChanged(source_metadata);
267   }
268 
ResetPresentationPosition()269   void ResetPresentationPosition() override {
270     transport_->ResetPresentationPosition();
271   }
272 
LogBytesWritten(size_t bytes_written)273   void LogBytesWritten(size_t bytes_written) override {
274     transport_->LogBytesProcessed(bytes_written);
275   }
276 
SetRemoteDelay(uint16_t delay_report_ms)277   void SetRemoteDelay(uint16_t delay_report_ms) {
278     transport_->SetRemoteDelay(delay_report_ms);
279   }
280 
LeAudioGetSelectedHalPcmConfig()281   const PcmParameters& LeAudioGetSelectedHalPcmConfig() {
282     return transport_->LeAudioGetSelectedHalPcmConfig();
283   }
284 
LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,BitsPerSample bit_rate,ChannelMode channel_mode,uint32_t data_interval)285   void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
286                                       BitsPerSample bit_rate,
287                                       ChannelMode channel_mode,
288                                       uint32_t data_interval) {
289     transport_->LeAudioSetSelectedHalPcmConfig(sample_rate, bit_rate,
290                                                channel_mode, data_interval);
291   }
292 
293  private:
294   LeAudioTransport* transport_;
295 };
296 
297 // Instance of Le Audio to provide call-in APIs for Bluetooth Audio Hal
298 LeAudioSinkTransport* le_audio_sink = nullptr;
299 LeAudioSourceTransport* le_audio_source = nullptr;
300 }  // namespace
301 
302 namespace bluetooth {
303 namespace audio {
304 namespace le_audio {
305 
306 LeAudioClientInterface* LeAudioClientInterface::interface = nullptr;
Get()307 LeAudioClientInterface* LeAudioClientInterface::Get() {
308   if (osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false)) {
309     LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
310     return nullptr;
311   }
312 
313   if (LeAudioClientInterface::interface == nullptr)
314     LeAudioClientInterface::interface = new LeAudioClientInterface();
315 
316   return LeAudioClientInterface::interface;
317 }
318 
le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1)319 static SampleRate_2_1 le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1) {
320   switch (sample_rate_2_1) {
321     case 8000:
322       return SampleRate_2_1::RATE_8000;
323     case 16000:
324       return SampleRate_2_1::RATE_16000;
325     case 24000:
326       return SampleRate_2_1::RATE_24000;
327     case 32000:
328       return SampleRate_2_1::RATE_32000;
329     case 44100:
330       return SampleRate_2_1::RATE_44100;
331     case 48000:
332       return SampleRate_2_1::RATE_48000;
333     case 88200:
334       return SampleRate_2_1::RATE_88200;
335     case 96000:
336       return SampleRate_2_1::RATE_96000;
337     case 176400:
338       return SampleRate_2_1::RATE_176400;
339     case 192000:
340       return SampleRate_2_1::RATE_192000;
341   };
342   return SampleRate_2_1::RATE_UNKNOWN;
343 }
344 
le_audio_bit_rate2audio_hal(uint8_t bits_per_sample)345 static BitsPerSample le_audio_bit_rate2audio_hal(uint8_t bits_per_sample) {
346   switch (bits_per_sample) {
347     case 16:
348       return BitsPerSample::BITS_16;
349     case 24:
350       return BitsPerSample::BITS_24;
351     case 32:
352       return BitsPerSample::BITS_32;
353   };
354   return BitsPerSample::BITS_UNKNOWN;
355 }
356 
le_audio_channel_mode2audio_hal(uint8_t channels_count)357 static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
358   switch (channels_count) {
359     case 1:
360       return ChannelMode::MONO;
361     case 2:
362       return ChannelMode::STEREO;
363   }
364   return ChannelMode::UNKNOWN;
365 }
366 
Cleanup()367 void LeAudioClientInterface::Sink::Cleanup() {
368   LOG(INFO) << __func__;
369   StopSession();
370   delete le_audio_sink_hal_clientinterface;
371   le_audio_sink_hal_clientinterface = nullptr;
372   delete le_audio_sink;
373   le_audio_sink = nullptr;
374 }
375 
SetPcmParameters(const PcmParameters & params)376 void LeAudioClientInterface::Sink::SetPcmParameters(
377     const PcmParameters& params) {
378   le_audio_sink->LeAudioSetSelectedHalPcmConfig(
379       le_audio_sample_rate2audio_hal(params.sample_rate),
380       le_audio_bit_rate2audio_hal(params.bits_per_sample),
381       le_audio_channel_mode2audio_hal(params.channels_count),
382       params.data_interval_us);
383 }
384 
385 // Update Le Audio delay report to BluetoothAudio HAL
SetRemoteDelay(uint16_t delay_report_ms)386 void LeAudioClientInterface::Sink::SetRemoteDelay(uint16_t delay_report_ms) {
387   LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
388   le_audio_sink->SetRemoteDelay(delay_report_ms);
389 }
390 
StartSession()391 void LeAudioClientInterface::Sink::StartSession() {
392   LOG(INFO) << __func__;
393   AudioConfiguration_2_1 audio_config;
394   audio_config.pcmConfig(le_audio_sink->LeAudioGetSelectedHalPcmConfig());
395   if (!le_audio_sink_hal_clientinterface->UpdateAudioConfig_2_1(audio_config)) {
396     LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
397     return;
398   }
399   le_audio_sink_hal_clientinterface->StartSession_2_1();
400 }
401 
StopSession()402 void LeAudioClientInterface::Sink::StopSession() {
403   LOG(INFO) << __func__;
404   le_audio_sink_hal_clientinterface->EndSession();
405 }
406 
Read(uint8_t * p_buf,uint32_t len)407 size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
408   return le_audio_sink_hal_clientinterface->ReadAudioData(p_buf, len);
409 }
410 
Cleanup()411 void LeAudioClientInterface::Source::Cleanup() {
412   LOG(INFO) << __func__;
413   StopSession();
414   delete le_audio_source_hal_clientinterface;
415   le_audio_source_hal_clientinterface = nullptr;
416   delete le_audio_source;
417   le_audio_source = nullptr;
418 }
419 
SetPcmParameters(const PcmParameters & params)420 void LeAudioClientInterface::Source::SetPcmParameters(
421     const PcmParameters& params) {
422   le_audio_source->LeAudioSetSelectedHalPcmConfig(
423       le_audio_sample_rate2audio_hal(params.sample_rate),
424       le_audio_bit_rate2audio_hal(params.bits_per_sample),
425       le_audio_channel_mode2audio_hal(params.channels_count),
426       params.data_interval_us);
427 }
428 
SetRemoteDelay(uint16_t delay_report_ms)429 void LeAudioClientInterface::Source::SetRemoteDelay(uint16_t delay_report_ms) {
430   LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
431   le_audio_source->SetRemoteDelay(delay_report_ms);
432 }
433 
StartSession()434 void LeAudioClientInterface::Source::StartSession() {
435   LOG(INFO) << __func__;
436   if (!is_source_hal_enabled()) return;
437   AudioConfiguration_2_1 audio_config;
438   audio_config.pcmConfig(le_audio_source->LeAudioGetSelectedHalPcmConfig());
439   if (!le_audio_source_hal_clientinterface->UpdateAudioConfig_2_1(
440           audio_config)) {
441     LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
442     return;
443   }
444   le_audio_source_hal_clientinterface->StartSession_2_1();
445 }
446 
StopSession()447 void LeAudioClientInterface::Source::StopSession() {
448   LOG(INFO) << __func__;
449   le_audio_source_hal_clientinterface->EndSession();
450 }
451 
Write(const uint8_t * p_buf,uint32_t len)452 size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
453                                              uint32_t len) {
454   return le_audio_source_hal_clientinterface->WriteAudioData(p_buf, len);
455 }
456 
GetSink(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread * message_loop)457 LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
458     StreamCallbacks stream_cb,
459     bluetooth::common::MessageLoopThread* message_loop) {
460   if (sink_ == nullptr) {
461     sink_ = new Sink();
462   } else {
463     LOG(WARNING) << __func__ << ", Sink is already acquired";
464     return nullptr;
465   }
466 
467   LOG(INFO) << __func__;
468 
469   le_audio_sink = new LeAudioSinkTransport(std::move(stream_cb));
470   le_audio_sink_hal_clientinterface =
471       new bluetooth::audio::BluetoothAudioSinkClientInterface(le_audio_sink,
472                                                               message_loop);
473   if (!le_audio_sink_hal_clientinterface->IsValid()) {
474     LOG(WARNING) << __func__
475                  << ": BluetoothAudio HAL for Le Audio is invalid?!";
476     delete le_audio_sink_hal_clientinterface;
477     le_audio_sink_hal_clientinterface = nullptr;
478     delete le_audio_sink;
479     le_audio_sink = nullptr;
480     delete sink_;
481     sink_ = nullptr;
482 
483     return nullptr;
484   }
485 
486   return sink_;
487 }
488 
IsSinkAcquired()489 bool LeAudioClientInterface::IsSinkAcquired() { return sink_ != nullptr; }
490 
ReleaseSink(LeAudioClientInterface::Sink * sink)491 bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* sink) {
492   if (sink != sink_) {
493     LOG(WARNING) << __func__ << ", can't release not acquired sink";
494     return false;
495   }
496 
497   if (le_audio_sink_hal_clientinterface && le_audio_sink) sink->Cleanup();
498 
499   delete (sink_);
500   sink_ = nullptr;
501 
502   return true;
503 }
504 
GetSource(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread * message_loop)505 LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
506     StreamCallbacks stream_cb,
507     bluetooth::common::MessageLoopThread* message_loop) {
508   if (source_ == nullptr) {
509     source_ = new Source();
510   } else {
511     LOG(WARNING) << __func__ << ", Source is already acquired";
512     return nullptr;
513   }
514 
515   LOG(INFO) << __func__;
516 
517   le_audio_source = new LeAudioSourceTransport(std::move(stream_cb));
518   le_audio_source_hal_clientinterface =
519       new bluetooth::audio::BluetoothAudioSourceClientInterface(le_audio_source,
520                                                                 message_loop);
521   if (!le_audio_source_hal_clientinterface->IsValid()) {
522     LOG(WARNING) << __func__
523                  << ": BluetoothAudio HAL for Le Audio is invalid?!";
524     delete le_audio_source_hal_clientinterface;
525     le_audio_source_hal_clientinterface = nullptr;
526     delete le_audio_source;
527     le_audio_source = nullptr;
528     delete source_;
529     source_ = nullptr;
530 
531     return nullptr;
532   }
533 
534   return source_;
535 }
536 
IsSourceAcquired()537 bool LeAudioClientInterface::IsSourceAcquired() { return source_ != nullptr; }
538 
ReleaseSource(LeAudioClientInterface::Source * source)539 bool LeAudioClientInterface::ReleaseSource(
540     LeAudioClientInterface::Source* source) {
541   if (source != source_) {
542     LOG(WARNING) << __func__ << ", can't release not acquired source";
543     return false;
544   }
545 
546   if (le_audio_source_hal_clientinterface && le_audio_source) source->Cleanup();
547 
548   delete (source_);
549   source_ = nullptr;
550 
551   return true;
552 }
553 
554 }  // namespace le_audio
555 }  // namespace audio
556 }  // namespace bluetooth
557