1 /*
2 * Copyright 2021 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 "a2dp_encoding_host.h"
18
19 #include <bluetooth/log.h>
20 #include <grp.h>
21 #include <sys/stat.h>
22
23 #include <memory>
24 #include <vector>
25
26 #include "a2dp_encoding.h"
27 #include "btif/include/btif_a2dp_source.h"
28 #include "btif/include/btif_av.h"
29 #include "btif/include/btif_hf.h"
30 #include "os/log.h"
31 #include "stack/include/avdt_api.h"
32 #include "types/raw_address.h"
33 #include "udrv/include/uipc.h"
34
35 #define A2DP_DATA_READ_POLL_MS 10
36 #define A2DP_HOST_DATA_PATH "/var/run/bluetooth/audio/.a2dp_data"
37 // TODO(b/198260375): Make A2DP data owner group configurable.
38 #define A2DP_HOST_DATA_GROUP "bluetooth-audio"
39
40 namespace fmt {
41 template <>
42 struct formatter<tUIPC_EVENT> : enum_formatter<tUIPC_EVENT> {};
43 template <>
44 struct formatter<tA2DP_CTRL_CMD> : enum_formatter<tA2DP_CTRL_CMD> {};
45 } // namespace fmt
46
47 namespace {
48
49 std::unique_ptr<tUIPC_STATE> a2dp_uipc = nullptr;
50
btif_a2dp_data_cb(tUIPC_CH_ID ch_id,tUIPC_EVENT event)51 static void btif_a2dp_data_cb([[maybe_unused]] tUIPC_CH_ID ch_id,
52 tUIPC_EVENT event) {
53 bluetooth::log::warn("BTIF MEDIA (A2DP-DATA) EVENT {}",
54 dump_uipc_event(event));
55
56 switch (event) {
57 case UIPC_OPEN_EVT:
58 /*
59 * Read directly from media task from here on (keep callback for
60 * connection events.
61 */
62 UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO,
63 UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
64 UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
65 reinterpret_cast<void*>(A2DP_DATA_READ_POLL_MS));
66
67 // Will start audio on btif_a2dp_on_started
68
69 /* ACK back when media task is fully started */
70 break;
71
72 case UIPC_CLOSE_EVT:
73 /* Post stop event and wait for audio path to stop */
74 btif_av_stream_stop(RawAddress::kEmpty);
75 break;
76
77 default:
78 bluetooth::log::error("### A2DP-DATA EVENT {} NOT HANDLED ###", event);
79 break;
80 }
81 }
82
83 // If A2DP_HOST_DATA_GROUP exists we expect audio server and BT both are
84 // in this group therefore have access to A2DP socket. Otherwise audio
85 // server should be in the same group that BT stack runs with to access
86 // A2DP socket.
a2dp_data_path_open()87 static void a2dp_data_path_open() {
88 UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
89 A2DP_HOST_DATA_PATH);
90 struct group* grp = getgrnam(A2DP_HOST_DATA_GROUP);
91 chmod(A2DP_HOST_DATA_PATH, 0770);
92 if (grp) {
93 int res = chown(A2DP_HOST_DATA_PATH, -1, grp->gr_gid);
94 if (res == -1) {
95 bluetooth::log::error("failed: {}", strerror(errno));
96 }
97 }
98 }
99
100 tA2DP_CTRL_CMD a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
101 uint64_t total_bytes_read_;
102 timespec data_position_;
103 uint16_t remote_delay_report_;
104
105 } // namespace
106
107 namespace bluetooth {
108 namespace audio {
109 namespace a2dp {
110
111 // Invoked by audio server to set audio config (PCM for now)
SetAudioConfig(AudioConfig config)112 bool SetAudioConfig(AudioConfig config) {
113 btav_a2dp_codec_config_t codec_config;
114 codec_config.sample_rate = config.sample_rate;
115 codec_config.bits_per_sample = config.bits_per_sample;
116 codec_config.channel_mode = config.channel_mode;
117 btif_a2dp_source_feeding_update_req(codec_config);
118 return true;
119 }
120
121 // Invoked by audio server when it has audio data to stream.
StartRequest()122 bool StartRequest() {
123 // Reset total read bytes and timestamp to avoid confusing audio
124 // server at delay calculation.
125 total_bytes_read_ = 0;
126 data_position_ = {0, 0};
127
128 // Check if a previous request is not finished
129 if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
130 log::info("A2DP_CTRL_CMD_START in progress");
131 return false;
132 } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
133 log::warn("busy in pending_cmd={}", a2dp_pending_cmd_);
134 return false;
135 }
136
137 // Don't send START request to stack while we are in a call
138 if (!bluetooth::headset::IsCallIdle()) {
139 log::error("call state is busy");
140 return false;
141 }
142
143 if (btif_av_stream_started_ready(A2dpType::kSource)) {
144 // Already started, ACK back immediately.
145 a2dp_data_path_open();
146 return true;
147 }
148 if (btif_av_stream_ready(A2dpType::kSource)) {
149 a2dp_data_path_open();
150 /*
151 * Post start event and wait for audio path to open.
152 * If we are the source, the ACK will be sent after the start
153 * procedure is completed.
154 */
155 a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
156 btif_av_stream_start(A2dpType::kSource);
157 if (btif_av_get_peer_sep(A2dpType::kSource) != AVDT_TSEP_SRC) {
158 log::info("accepted");
159 return true; // NOTE: The request is placed, but could still fail.
160 }
161 a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
162 return true;
163 }
164 log::error("AV stream is not ready to start");
165 return false;
166 }
167
168 // Invoked by audio server when audio streaming is done.
StopRequest()169 bool StopRequest() {
170 if (btif_av_get_peer_sep(A2dpType::kSource) == AVDT_TSEP_SNK &&
171 !btif_av_stream_started_ready(A2dpType::kSource)) {
172 btif_av_clear_remote_suspend_flag(A2dpType::kSource);
173 return true;
174 }
175 log::info("handling");
176 a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
177 btif_av_stream_stop(RawAddress::kEmpty);
178 return true;
179 }
180
SuspendRequest()181 bool SuspendRequest() {
182 if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
183 log::warn("busy in pending_cmd={}", a2dp_pending_cmd_);
184 return false;
185 }
186 if (!btif_av_stream_started_ready(A2dpType::kSource)) {
187 log::warn("AV stream is not started");
188 return false;
189 }
190 log::info("handling");
191 a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
192 btif_av_stream_suspend();
193 return true;
194 }
195
196 // Invoked by audio server to check audio presentation position periodically.
GetPresentationPosition()197 PresentationPosition GetPresentationPosition() {
198 PresentationPosition presentation_position{
199 .remote_delay_report_ns = remote_delay_report_ * 100000u,
200 .total_bytes_read = total_bytes_read_,
201 .data_position = data_position_,
202 };
203 return presentation_position;
204 }
205
206 // delay reports from AVDTP is based on 1/10 ms (100us)
set_remote_delay(uint16_t delay_report)207 void set_remote_delay(uint16_t delay_report) {
208 remote_delay_report_ = delay_report;
209 }
210
211 // Inform audio server about offloading codec; not used for now
update_codec_offloading_capabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference,bool supports_a2dp_hw_offload_v2)212 bool update_codec_offloading_capabilities(
213 const std::vector<btav_a2dp_codec_config_t>& framework_preference,
214 bool supports_a2dp_hw_offload_v2) {
215 return false;
216 }
217
218 // Checking if new bluetooth_audio is enabled
is_hal_enabled()219 bool is_hal_enabled() { return true; }
220
221 // Check if new bluetooth_audio is running with offloading encoders
is_hal_offloading()222 bool is_hal_offloading() { return false; }
223
224 // Initialize BluetoothAudio HAL: openProvider
init(bluetooth::common::MessageLoopThread * message_loop)225 bool init(bluetooth::common::MessageLoopThread* message_loop) {
226 a2dp_uipc = UIPC_Init();
227 total_bytes_read_ = 0;
228 data_position_ = {};
229 remote_delay_report_ = 0;
230
231 return true;
232 }
233
234 // Clean up BluetoothAudio HAL
cleanup()235 void cleanup() {
236 end_session();
237
238 if (a2dp_uipc != nullptr) {
239 UIPC_Close(*a2dp_uipc, UIPC_CH_ID_ALL);
240 a2dp_uipc = nullptr;
241 }
242 }
243
244 // Set up the codec into BluetoothAudio HAL
setup_codec()245 bool setup_codec() {
246 // TODO: setup codec
247 return true;
248 }
249
start_session()250 void start_session() {
251 // TODO: Notify server; or do we handle it during connected?
252 }
253
end_session()254 void end_session() {
255 // TODO: Notify server; or do we handle it during disconnected?
256
257 // Reset remote delay. New value will be set when new session starts.
258 remote_delay_report_ = 0;
259
260 a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
261 }
262
set_audio_low_latency_mode_allowed(bool allowed)263 void set_audio_low_latency_mode_allowed(bool allowed){
264 }
265
266
ack_stream_started(const tA2DP_CTRL_ACK & ack)267 void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
268 a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
269 // TODO: Notify server
270 }
271
ack_stream_suspended(const tA2DP_CTRL_ACK & ack)272 void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
273 a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
274 // TODO: Notify server
275 }
276
277 // Read from the FMQ of BluetoothAudio HAL
read(uint8_t * p_buf,uint32_t len)278 size_t read(uint8_t* p_buf, uint32_t len) {
279 uint32_t bytes_read = 0;
280 if (a2dp_uipc == nullptr) {
281 return 0;
282 }
283 bytes_read = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, len);
284 total_bytes_read_ += bytes_read;
285 // MONOTONIC_RAW isn't affected by NTP, audio stack rely on this
286 // to get precise delay calculation.
287 clock_gettime(CLOCK_MONOTONIC_RAW, &data_position_);
288 return bytes_read;
289 }
290
291 // Check if OPUS codec is supported
is_opus_supported()292 bool is_opus_supported() { return true; }
293
294 namespace provider {
295
296 // Lookup the codec info in the list of supported offloaded sink codecs.
sink_codec_index(const uint8_t * p_codec_info)297 std::optional<btav_a2dp_codec_index_t> sink_codec_index(
298 const uint8_t* p_codec_info) {
299 return std::nullopt;
300 }
301
302 // Lookup the codec info in the list of supported offloaded source codecs.
source_codec_index(const uint8_t * p_codec_info)303 std::optional<btav_a2dp_codec_index_t> source_codec_index(
304 const uint8_t* p_codec_info) {
305 return std::nullopt;
306 }
307
308 // Return the name of the codec which is assigned to the input index.
309 // The codec index must be in the ranges
310 // BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
311 // BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
312 // Returns nullopt if the codec_index is not assigned or codec extensibility
313 // is not supported or enabled.
codec_index_str(btav_a2dp_codec_index_t codec_index)314 std::optional<const char*> codec_index_str(
315 btav_a2dp_codec_index_t codec_index) {
316 return std::nullopt;
317 }
318
319 // Return true if the codec is supported for the session type
320 // A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
supports_codec(btav_a2dp_codec_index_t codec_index)321 bool supports_codec(btav_a2dp_codec_index_t codec_index) { return false; }
322
323 // Return the A2DP capabilities for the selected codec.
codec_info(btav_a2dp_codec_index_t codec_index,uint64_t * codec_id,uint8_t * codec_info,btav_a2dp_codec_config_t * codec_config)324 bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id,
325 uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) {
326 return false;
327 }
328
329 // Query the codec selection fromt the audio HAL.
330 // The HAL is expected to pick the best audio configuration based on the
331 // discovered remote SEPs.
get_a2dp_configuration(RawAddress peer_address,std::vector<a2dp_remote_capabilities> const & remote_seps,btav_a2dp_codec_config_t const & user_preferences)332 std::optional<a2dp_configuration> get_a2dp_configuration(
333 RawAddress peer_address,
334 std::vector<a2dp_remote_capabilities> const& remote_seps,
335 btav_a2dp_codec_config_t const& user_preferences) {
336 return std::nullopt;
337 }
338
339 // Query the codec parameters from the audio HAL.
340 // The HAL performs a two part validation:
341 // - check if the configuration is valid
342 // - check if the configuration is supported by the audio provider
343 // In case any of these checks fails, the corresponding A2DP
344 // status is returned. If the configuration is valid and supported,
345 // A2DP_OK is returned.
parse_a2dp_configuration(btav_a2dp_codec_index_t codec_index,const uint8_t * codec_info,btav_a2dp_codec_config_t * codec_parameters,std::vector<uint8_t> * vendor_specific_parameters)346 tA2DP_STATUS parse_a2dp_configuration(
347 btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info,
348 btav_a2dp_codec_config_t* codec_parameters,
349 std::vector<uint8_t>* vendor_specific_parameters) {
350 return A2DP_FAIL;
351 }
352
353 } // namespace provider
354
355 } // namespace a2dp
356 } // namespace audio
357 } // namespace bluetooth
358