1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "audio_hal_interface/le_audio_software_host_transport.h"
18
19 #include <bluetooth/log.h>
20
21 #include <functional>
22
23 namespace bluetooth {
24 namespace audio {
25 namespace host {
26 namespace le_audio {
27
LeAudioTransport(std::function<void ()> flush,StreamCallbacks stream_cb,PcmParameters pcm_config)28 LeAudioTransport::LeAudioTransport(std::function<void()> flush,
29 StreamCallbacks stream_cb,
30 PcmParameters pcm_config)
31 : flush_(std::move(flush)),
32 stream_cb_(std::move(stream_cb)),
33 remote_delay_report_ms_(0),
34 total_bytes_processed_(0),
35 data_position_({}),
36 pcm_config_(std::move(pcm_config)),
37 start_request_state_(StartRequestState::IDLE){};
38
StartRequest()39 bool LeAudioTransport::StartRequest() {
40 SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME);
41 if (stream_cb_.on_resume_(true)) {
42 if (start_request_state_ == StartRequestState::CONFIRMED) {
43 log::info("Start completed.");
44 SetStartRequestState(StartRequestState::IDLE);
45 return true;
46 }
47
48 if (start_request_state_ == StartRequestState::CANCELED) {
49 log::info("Start request failed.");
50 SetStartRequestState(StartRequestState::IDLE);
51 return false;
52 }
53
54 log::info("Start pending.");
55 SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME);
56 return true;
57 }
58
59 log::error("Start request failed.");
60 SetStartRequestState(StartRequestState::IDLE);
61 return false;
62 }
63
SuspendRequest()64 bool LeAudioTransport::SuspendRequest() {
65 log::info("");
66 if (stream_cb_.on_suspend_()) {
67 flush_();
68 return true;
69 } else {
70 return false;
71 }
72 }
73
StopRequest()74 void LeAudioTransport::StopRequest() {
75 log::info("");
76 if (stream_cb_.on_suspend_()) {
77 flush_();
78 }
79 }
80
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_processed,timespec * data_position)81 bool LeAudioTransport::GetPresentationPosition(uint64_t* remote_delay_report_ns,
82 uint64_t* total_bytes_processed,
83 timespec* data_position) {
84 log::verbose("data={} byte(s), timestamp={}.{}s, delay report={} msec.",
85 total_bytes_processed_, data_position_.tv_sec,
86 data_position_.tv_nsec, remote_delay_report_ms_);
87 if (remote_delay_report_ns != nullptr) {
88 *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
89 }
90 if (total_bytes_processed != nullptr)
91 *total_bytes_processed = total_bytes_processed_;
92 if (data_position != nullptr) *data_position = data_position_;
93
94 return true;
95 }
96
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)97 void LeAudioTransport::SourceMetadataChanged(
98 const source_metadata_v7_t& source_metadata) {
99 auto track_count = source_metadata.track_count;
100
101 if (track_count == 0) {
102 log::warn(", invalid number of metadata changed tracks");
103 return;
104 }
105
106 stream_cb_.on_metadata_update_(source_metadata,
107 ::bluetooth::le_audio::DsaMode::DISABLED);
108 }
109
SinkMetadataChanged(const sink_metadata_v7_t & sink_metadata)110 void LeAudioTransport::SinkMetadataChanged(
111 const sink_metadata_v7_t& sink_metadata) {
112 auto track_count = sink_metadata.track_count;
113
114 if (track_count == 0) {
115 log::warn(", invalid number of metadata changed tracks");
116 return;
117 }
118
119 stream_cb_.on_sink_metadata_update_(sink_metadata);
120 }
121
ResetPresentationPosition()122 void LeAudioTransport::ResetPresentationPosition() {
123 log::verbose("called.");
124 remote_delay_report_ms_ = 0;
125 total_bytes_processed_ = 0;
126 data_position_ = {};
127 }
128
LogBytesProcessed(size_t bytes_processed)129 void LeAudioTransport::LogBytesProcessed(size_t bytes_processed) {
130 if (bytes_processed) {
131 total_bytes_processed_ += bytes_processed;
132 clock_gettime(CLOCK_MONOTONIC, &data_position_);
133 }
134 }
135
SetRemoteDelay(uint16_t delay_report_ms)136 void LeAudioTransport::SetRemoteDelay(uint16_t delay_report_ms) {
137 log::info("delay_report={} msec", delay_report_ms);
138 remote_delay_report_ms_ = delay_report_ms;
139 }
140
LeAudioGetSelectedHalPcmConfig()141 const PcmParameters& LeAudioTransport::LeAudioGetSelectedHalPcmConfig() {
142 return pcm_config_;
143 }
144
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)145 void LeAudioTransport::LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,
146 uint8_t bit_rate,
147 uint8_t channels_count,
148 uint32_t data_interval) {
149 pcm_config_.sample_rate = sample_rate_hz;
150 pcm_config_.bits_per_sample = bit_rate;
151 pcm_config_.channels_count = channels_count;
152 pcm_config_.data_interval_us = data_interval;
153 }
154
GetStartRequestState(void)155 StartRequestState LeAudioTransport::GetStartRequestState(void) {
156 return start_request_state_;
157 }
158
ClearStartRequestState(void)159 void LeAudioTransport::ClearStartRequestState(void) {
160 log::verbose("");
161 start_request_state_ = StartRequestState::IDLE;
162 remote_delay_report_ms_ = 0;
163 }
164
SetStartRequestState(StartRequestState state)165 void LeAudioTransport::SetStartRequestState(StartRequestState state) {
166 start_request_state_ = state;
167 }
168
get_source_default_pcm_parameters()169 static PcmParameters get_source_default_pcm_parameters() {
170 return PcmParameters{
171 .data_interval_us = 0,
172 .sample_rate = 16000,
173 .bits_per_sample = 16,
174 .channels_count = 1,
175 };
176 }
177
get_sink_default_pcm_parameters()178 static PcmParameters get_sink_default_pcm_parameters() {
179 return PcmParameters{
180 .data_interval_us = 0,
181 .sample_rate = 16000,
182 .bits_per_sample = 16,
183 .channels_count = 2,
184 };
185 }
186
LeAudioSinkTransport(StreamCallbacks stream_cb)187 LeAudioSinkTransport::LeAudioSinkTransport(StreamCallbacks stream_cb) {
188 std::function<void()> flush_sink = [&]() {
189 // TODO(b/331315361): investigate the effect of flushing the buffer
190 };
191
192 transport_ = new LeAudioTransport(flush_sink, std::move(stream_cb),
193 get_sink_default_pcm_parameters());
194 };
195
~LeAudioSinkTransport()196 LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; }
197
StartRequest()198 bool LeAudioSinkTransport::StartRequest() { return transport_->StartRequest(); }
199
SuspendRequest()200 bool LeAudioSinkTransport::SuspendRequest() {
201 return transport_->SuspendRequest();
202 }
203
StopRequest()204 void LeAudioSinkTransport::StopRequest() { transport_->StopRequest(); }
205
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)206 bool LeAudioSinkTransport::GetPresentationPosition(
207 uint64_t* remote_delay_report_ns, uint64_t* total_bytes_read,
208 timespec* data_position) {
209 return transport_->GetPresentationPosition(remote_delay_report_ns,
210 total_bytes_read, data_position);
211 }
212
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)213 void LeAudioSinkTransport::SourceMetadataChanged(
214 const source_metadata_v7_t& source_metadata) {
215 transport_->SourceMetadataChanged(source_metadata);
216 }
217
SinkMetadataChanged(const sink_metadata_v7_t & sink_metadata)218 void LeAudioSinkTransport::SinkMetadataChanged(
219 const sink_metadata_v7_t& sink_metadata) {
220 transport_->SinkMetadataChanged(sink_metadata);
221 }
222
ResetPresentationPosition()223 void LeAudioSinkTransport::ResetPresentationPosition() {
224 transport_->ResetPresentationPosition();
225 }
226
LogBytesRead(size_t bytes_read)227 void LeAudioSinkTransport::LogBytesRead(size_t bytes_read) {
228 transport_->LogBytesProcessed(bytes_read);
229 }
230
SetRemoteDelay(uint16_t delay_report_ms)231 void LeAudioSinkTransport::SetRemoteDelay(uint16_t delay_report_ms) {
232 transport_->SetRemoteDelay(delay_report_ms);
233 }
234
LeAudioGetSelectedHalPcmConfig()235 const PcmParameters& LeAudioSinkTransport::LeAudioGetSelectedHalPcmConfig() {
236 return transport_->LeAudioGetSelectedHalPcmConfig();
237 }
238
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)239 void LeAudioSinkTransport::LeAudioSetSelectedHalPcmConfig(
240 uint32_t sample_rate_hz, uint8_t bit_rate, uint8_t channels_count,
241 uint32_t data_interval) {
242 transport_->LeAudioSetSelectedHalPcmConfig(sample_rate_hz, bit_rate,
243 channels_count, data_interval);
244 }
245
GetStartRequestState(void)246 StartRequestState LeAudioSinkTransport::GetStartRequestState(void) {
247 return transport_->GetStartRequestState();
248 }
249
ClearStartRequestState(void)250 void LeAudioSinkTransport::ClearStartRequestState(void) {
251 log::verbose("");
252 transport_->ClearStartRequestState();
253 }
254
SetStartRequestState(StartRequestState state)255 void LeAudioSinkTransport::SetStartRequestState(StartRequestState state) {
256 transport_->SetStartRequestState(state);
257 }
258
LeAudioSourceTransport(StreamCallbacks stream_cb)259 LeAudioSourceTransport::LeAudioSourceTransport(StreamCallbacks stream_cb) {
260 std::function<void()> flush_source = [&]() {
261 // TODO(b/331315361): investigate the effect of flushing the buffer
262 };
263
264 transport_ = new LeAudioTransport(flush_source, std::move(stream_cb),
265 get_source_default_pcm_parameters());
266 };
267
~LeAudioSourceTransport()268 LeAudioSourceTransport::~LeAudioSourceTransport() { delete transport_; }
269
StartRequest()270 bool LeAudioSourceTransport::StartRequest() {
271 return transport_->StartRequest();
272 }
273
SuspendRequest()274 bool LeAudioSourceTransport::SuspendRequest() {
275 return transport_->SuspendRequest();
276 }
277
StopRequest()278 void LeAudioSourceTransport::StopRequest() { transport_->StopRequest(); }
279
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_written,timespec * data_position)280 bool LeAudioSourceTransport::GetPresentationPosition(
281 uint64_t* remote_delay_report_ns, uint64_t* total_bytes_written,
282 timespec* data_position) {
283 return transport_->GetPresentationPosition(
284 remote_delay_report_ns, total_bytes_written, data_position);
285 }
286
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)287 void LeAudioSourceTransport::SourceMetadataChanged(
288 const source_metadata_v7_t& source_metadata) {}
289
SinkMetadataChanged(const sink_metadata_v7_t & sink_metadata)290 void LeAudioSourceTransport::SinkMetadataChanged(
291 const sink_metadata_v7_t& sink_metadata) {
292 transport_->SinkMetadataChanged(sink_metadata);
293 }
294
ResetPresentationPosition()295 void LeAudioSourceTransport::ResetPresentationPosition() {
296 transport_->ResetPresentationPosition();
297 }
298
LogBytesWritten(size_t bytes_written)299 void LeAudioSourceTransport::LogBytesWritten(size_t bytes_written) {
300 transport_->LogBytesProcessed(bytes_written);
301 }
302
SetRemoteDelay(uint16_t delay_report_ms)303 void LeAudioSourceTransport::SetRemoteDelay(uint16_t delay_report_ms) {
304 transport_->SetRemoteDelay(delay_report_ms);
305 }
306
LeAudioGetSelectedHalPcmConfig()307 const PcmParameters& LeAudioSourceTransport::LeAudioGetSelectedHalPcmConfig() {
308 return transport_->LeAudioGetSelectedHalPcmConfig();
309 }
310
LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz,uint8_t bit_rate,uint8_t channels_count,uint32_t data_interval)311 void LeAudioSourceTransport::LeAudioSetSelectedHalPcmConfig(
312 uint32_t sample_rate_hz, uint8_t bit_rate, uint8_t channels_count,
313 uint32_t data_interval) {
314 transport_->LeAudioSetSelectedHalPcmConfig(sample_rate_hz, bit_rate,
315 channels_count, data_interval);
316 }
317
GetStartRequestState(void)318 StartRequestState LeAudioSourceTransport::GetStartRequestState(void) {
319 return transport_->GetStartRequestState();
320 }
321
ClearStartRequestState(void)322 void LeAudioSourceTransport::ClearStartRequestState(void) {
323 log::verbose("");
324 transport_->ClearStartRequestState();
325 }
326
SetStartRequestState(StartRequestState state)327 void LeAudioSourceTransport::SetStartRequestState(StartRequestState state) {
328 transport_->SetStartRequestState(state);
329 }
330 } // namespace le_audio
331 } // namespace host
332 } // namespace audio
333 } // namespace bluetooth
334