1 /******************************************************************************
2 *
3 * Copyright 2016 The Android Open Source Project
4 * Copyright 2009-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 #define LOG_TAG "bt_btif_a2dp_control"
21
22 #include "btif_a2dp_control.h"
23
24 #include <base/logging.h>
25 #include <stdbool.h>
26 #include <stdint.h>
27
28 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
29 #include "btif_a2dp.h"
30 #include "btif_a2dp_sink.h"
31 #include "btif_a2dp_source.h"
32 #include "btif_av.h"
33 #include "btif_av_co.h"
34 #include "btif_hf.h"
35 #include "osi/include/osi.h"
36 #include "types/raw_address.h"
37 #include "uipc.h"
38
39 #define A2DP_DATA_READ_POLL_MS 10
40
41 struct {
42 uint64_t total_bytes_read = 0;
43 uint16_t audio_delay = 0;
44 struct timespec timestamp = {};
45 } delay_report_stats;
46
47 static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
48 static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
49
50 /* We can have max one command pending */
51 static tA2DP_CTRL_CMD a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
52 std::unique_ptr<tUIPC_STATE> a2dp_uipc = nullptr;
53
btif_a2dp_control_init(void)54 void btif_a2dp_control_init(void) {
55 a2dp_uipc = UIPC_Init();
56 UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, btif_a2dp_ctrl_cb, A2DP_CTRL_PATH);
57 }
58
btif_a2dp_control_cleanup(void)59 void btif_a2dp_control_cleanup(void) {
60 /* This calls blocks until UIPC is fully closed */
61 if (a2dp_uipc != nullptr) {
62 UIPC_Close(*a2dp_uipc, UIPC_CH_ID_ALL);
63 }
64 }
65
btif_a2dp_control_on_check_ready()66 static tA2DP_CTRL_ACK btif_a2dp_control_on_check_ready() {
67 if (btif_a2dp_source_media_task_is_shutting_down()) {
68 APPL_TRACE_WARNING(
69 "%s: A2DP command check ready while media task shutting down",
70 __func__);
71 return A2DP_CTRL_ACK_FAILURE;
72 }
73
74 /* check whether AV is ready to setup A2DP datapath */
75 if (btif_av_stream_ready() || btif_av_stream_started_ready()) {
76 return A2DP_CTRL_ACK_SUCCESS;
77 } else {
78 APPL_TRACE_WARNING(
79 "%s: A2DP command check ready while AV stream is not ready", __func__);
80 return A2DP_CTRL_ACK_FAILURE;
81 }
82 }
83
btif_a2dp_control_on_start()84 static tA2DP_CTRL_ACK btif_a2dp_control_on_start() {
85 /*
86 * Don't send START request to stack while we are in a call.
87 * Some headsets such as "Sony MW600", don't allow AVDTP START
88 * while in a call, and respond with BAD_STATE.
89 */
90 if (!bluetooth::headset::IsCallIdle()) {
91 APPL_TRACE_WARNING("%s: A2DP command start while call state is busy",
92 __func__);
93 return A2DP_CTRL_ACK_INCALL_FAILURE;
94 }
95
96 if (btif_av_stream_ready()) {
97 /* Setup audio data channel listener */
98 UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
99 A2DP_DATA_PATH);
100
101 /*
102 * Post start event and wait for audio path to open.
103 * If we are the source, the ACK will be sent after the start
104 * procedure is completed, othewise send it now.
105 */
106 btif_av_stream_start();
107 if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) return A2DP_CTRL_ACK_SUCCESS;
108 }
109
110 if (btif_av_stream_started_ready()) {
111 /*
112 * Already started, setup audio data channel listener and ACK
113 * back immediately.
114 */
115 UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
116 A2DP_DATA_PATH);
117 return A2DP_CTRL_ACK_SUCCESS;
118 }
119 APPL_TRACE_WARNING("%s: A2DP command start while AV stream is not ready",
120 __func__);
121 return A2DP_CTRL_ACK_FAILURE;
122 }
123
btif_a2dp_control_on_stop()124 static tA2DP_CTRL_ACK btif_a2dp_control_on_stop() {
125 btif_av_stream_stop(RawAddress::kEmpty);
126 return A2DP_CTRL_ACK_SUCCESS;
127 }
128
btif_a2dp_control_on_suspend()129 static void btif_a2dp_control_on_suspend() {
130 /* Local suspend */
131 if (btif_av_stream_started_ready()) {
132 btif_av_stream_suspend();
133 return;
134 }
135 /* If we are not in started state, just ack back ok and let
136 * audioflinger close the channel. This can happen if we are
137 * remotely suspended, clear REMOTE SUSPEND flag.
138 */
139 btif_av_clear_remote_suspend_flag();
140 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
141 }
142
btif_a2dp_control_on_get_input_audio_config()143 static void btif_a2dp_control_on_get_input_audio_config() {
144 tA2DP_SAMPLE_RATE sample_rate = btif_a2dp_sink_get_sample_rate();
145 tA2DP_CHANNEL_COUNT channel_count = btif_a2dp_sink_get_channel_count();
146
147 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
148 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
149 reinterpret_cast<uint8_t*>(&sample_rate),
150 sizeof(tA2DP_SAMPLE_RATE));
151 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, &channel_count,
152 sizeof(tA2DP_CHANNEL_COUNT));
153 }
154
btif_a2dp_control_on_get_output_audio_config()155 static void btif_a2dp_control_on_get_output_audio_config() {
156 btav_a2dp_codec_config_t codec_config;
157 btav_a2dp_codec_config_t codec_capability;
158 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
159 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
160 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
161 codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
162 codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
163 codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
164
165 A2dpCodecConfig* current_codec = bta_av_get_a2dp_current_codec();
166 if (current_codec != nullptr) {
167 codec_config = current_codec->getCodecConfig();
168 codec_capability = current_codec->getCodecCapability();
169 }
170
171 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
172 // Send the current codec config
173 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
174 reinterpret_cast<const uint8_t*>(&codec_config.sample_rate),
175 sizeof(btav_a2dp_codec_sample_rate_t));
176 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
177 reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample),
178 sizeof(btav_a2dp_codec_bits_per_sample_t));
179 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
180 reinterpret_cast<const uint8_t*>(&codec_config.channel_mode),
181 sizeof(btav_a2dp_codec_channel_mode_t));
182 // Send the current codec capability
183 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
184 reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate),
185 sizeof(btav_a2dp_codec_sample_rate_t));
186 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
187 reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample),
188 sizeof(btav_a2dp_codec_bits_per_sample_t));
189 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
190 reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode),
191 sizeof(btav_a2dp_codec_channel_mode_t));
192 }
193
btif_a2dp_control_on_set_output_audio_config()194 static void btif_a2dp_control_on_set_output_audio_config() {
195 btav_a2dp_codec_config_t codec_config;
196 codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
197 codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
198 codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
199
200 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
201 // Send the current codec config
202 if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL,
203 reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
204 sizeof(btav_a2dp_codec_sample_rate_t)) !=
205 sizeof(btav_a2dp_codec_sample_rate_t)) {
206 APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL", __func__);
207 return;
208 }
209 if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL,
210 reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
211 sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
212 sizeof(btav_a2dp_codec_bits_per_sample_t)) {
213 APPL_TRACE_ERROR("%s: Error reading bits per sample from audio HAL",
214 __func__);
215 return;
216 }
217 if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL,
218 reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
219 sizeof(btav_a2dp_codec_channel_mode_t)) !=
220 sizeof(btav_a2dp_codec_channel_mode_t)) {
221 APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL", __func__);
222 return;
223 }
224 APPL_TRACE_DEBUG(
225 "%s: A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: "
226 "sample_rate=0x%x bits_per_sample=0x%x "
227 "channel_mode=0x%x",
228 __func__, codec_config.sample_rate, codec_config.bits_per_sample,
229 codec_config.channel_mode);
230 btif_a2dp_source_feeding_update_req(codec_config);
231 }
232
btif_a2dp_control_on_get_presentation_position()233 static void btif_a2dp_control_on_get_presentation_position() {
234 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
235
236 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
237 (uint8_t*)&(delay_report_stats.total_bytes_read), sizeof(uint64_t));
238 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
239 (uint8_t*)&(delay_report_stats.audio_delay), sizeof(uint16_t));
240
241 uint32_t seconds = delay_report_stats.timestamp.tv_sec;
242 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&seconds,
243 sizeof(seconds));
244
245 uint32_t nsec = delay_report_stats.timestamp.tv_nsec;
246 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&nsec, sizeof(nsec));
247 }
248
btif_a2dp_recv_ctrl_data(void)249 static void btif_a2dp_recv_ctrl_data(void) {
250 tA2DP_CTRL_CMD cmd = A2DP_CTRL_CMD_NONE;
251 int n;
252
253 uint8_t read_cmd = 0; /* The read command size is one octet */
254 n = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, &read_cmd, 1);
255 cmd = static_cast<tA2DP_CTRL_CMD>(read_cmd);
256
257 /* detach on ctrl channel means audioflinger process was terminated */
258 if (n == 0) {
259 APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__);
260 UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL);
261 return;
262 }
263
264 // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it
265 // could be very chatty when audio is streaming.
266 if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) {
267 APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s", __func__,
268 audio_a2dp_hw_dump_ctrl_event(cmd));
269 } else {
270 APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__,
271 audio_a2dp_hw_dump_ctrl_event(cmd));
272 }
273
274 a2dp_cmd_pending = cmd;
275 switch (cmd) {
276 case A2DP_CTRL_CMD_CHECK_READY:
277 btif_a2dp_command_ack(btif_a2dp_control_on_check_ready());
278 break;
279
280 case A2DP_CTRL_CMD_START:
281 btif_a2dp_command_ack(btif_a2dp_control_on_start());
282 break;
283
284 case A2DP_CTRL_CMD_STOP:
285 btif_a2dp_command_ack(btif_a2dp_control_on_stop());
286 break;
287
288 case A2DP_CTRL_CMD_SUSPEND:
289 btif_a2dp_control_on_suspend();
290 break;
291
292 case A2DP_CTRL_GET_INPUT_AUDIO_CONFIG:
293 btif_a2dp_control_on_get_input_audio_config();
294 break;
295
296 case A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG:
297 btif_a2dp_control_on_get_output_audio_config();
298 break;
299
300 case A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG:
301 btif_a2dp_control_on_set_output_audio_config();
302 break;
303
304 case A2DP_CTRL_GET_PRESENTATION_POSITION:
305 btif_a2dp_control_on_get_presentation_position();
306 break;
307
308 default:
309 APPL_TRACE_ERROR("%s: UNSUPPORTED CMD (%d)", __func__, cmd);
310 btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
311 break;
312 }
313
314 // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it
315 // could be very chatty when audio is streaming.
316 if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) {
317 APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s DONE", __func__,
318 audio_a2dp_hw_dump_ctrl_event(cmd));
319 } else {
320 APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s DONE", __func__,
321 audio_a2dp_hw_dump_ctrl_event(cmd));
322 }
323 }
324
btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,tUIPC_EVENT event)325 static void btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,
326 tUIPC_EVENT event) {
327 // Don't log UIPC_RX_DATA_READY_EVT by default, because it
328 // could be very chatty when audio is streaming.
329 if (event == UIPC_RX_DATA_READY_EVT) {
330 APPL_TRACE_DEBUG("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__,
331 dump_uipc_event(event));
332 } else {
333 APPL_TRACE_WARNING("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__,
334 dump_uipc_event(event));
335 }
336
337 switch (event) {
338 case UIPC_OPEN_EVT:
339 break;
340
341 case UIPC_CLOSE_EVT:
342 /* restart ctrl server unless we are shutting down */
343 if (btif_a2dp_source_media_task_is_running())
344 UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, btif_a2dp_ctrl_cb,
345 A2DP_CTRL_PATH);
346 break;
347
348 case UIPC_RX_DATA_READY_EVT:
349 btif_a2dp_recv_ctrl_data();
350 break;
351
352 default:
353 APPL_TRACE_ERROR("%s: ### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###",
354 __func__, event);
355 break;
356 }
357 }
358
btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,tUIPC_EVENT event)359 static void btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,
360 tUIPC_EVENT event) {
361 APPL_TRACE_WARNING("%s: BTIF MEDIA (A2DP-DATA) EVENT %s", __func__,
362 dump_uipc_event(event));
363
364 switch (event) {
365 case UIPC_OPEN_EVT:
366 /*
367 * Read directly from media task from here on (keep callback for
368 * connection events.
369 */
370 UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO,
371 UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
372 UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
373 reinterpret_cast<void*>(A2DP_DATA_READ_POLL_MS));
374
375 if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
376 /* Start the media task to encode the audio */
377 btif_a2dp_source_start_audio_req();
378 }
379
380 /* ACK back when media task is fully started */
381 break;
382
383 case UIPC_CLOSE_EVT:
384 APPL_TRACE_EVENT("%s: ## AUDIO PATH DETACHED ##", __func__);
385 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
386 /* Post stop event and wait for audio path to stop */
387 btif_av_stream_stop(RawAddress::kEmpty);
388 break;
389
390 default:
391 APPL_TRACE_ERROR("%s: ### A2DP-DATA EVENT %d NOT HANDLED ###", __func__,
392 event);
393 break;
394 }
395 }
396
btif_a2dp_command_ack(tA2DP_CTRL_ACK status)397 void btif_a2dp_command_ack(tA2DP_CTRL_ACK status) {
398 uint8_t ack = status;
399
400 // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it
401 // could be very chatty when audio is streaming.
402 if (a2dp_cmd_pending == A2DP_CTRL_GET_PRESENTATION_POSITION) {
403 APPL_TRACE_DEBUG("%s: ## a2dp ack : %s, status %d ##", __func__,
404 audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status);
405 } else {
406 APPL_TRACE_WARNING("%s: ## a2dp ack : %s, status %d ##", __func__,
407 audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status);
408 }
409
410 /* Sanity check */
411 if (a2dp_cmd_pending == A2DP_CTRL_CMD_NONE) {
412 APPL_TRACE_ERROR("%s: warning : no command pending, ignore ack", __func__);
413 return;
414 }
415
416 /* Clear pending */
417 a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
418
419 /* Acknowledge start request */
420 if (a2dp_uipc != nullptr) {
421 UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack));
422 }
423 }
424
btif_a2dp_control_log_bytes_read(uint32_t bytes_read)425 void btif_a2dp_control_log_bytes_read(uint32_t bytes_read) {
426 delay_report_stats.total_bytes_read += bytes_read;
427 clock_gettime(CLOCK_MONOTONIC, &delay_report_stats.timestamp);
428 }
429
btif_a2dp_control_set_audio_delay(uint16_t delay)430 void btif_a2dp_control_set_audio_delay(uint16_t delay) {
431 APPL_TRACE_DEBUG("%s: DELAY: %.1f ms", __func__, (float)delay / 10);
432 delay_report_stats.audio_delay = delay;
433 }
434
btif_a2dp_control_reset_audio_delay(void)435 void btif_a2dp_control_reset_audio_delay(void) {
436 APPL_TRACE_DEBUG("%s", __func__);
437 delay_report_stats.audio_delay = 0;
438 delay_report_stats.total_bytes_read = 0;
439 delay_report_stats.timestamp = {};
440 }
441