• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_a2dp_source_is_streaming()) {
97     APPL_TRACE_WARNING("%s: A2DP command start while source is streaming",
98                        __func__);
99     return A2DP_CTRL_ACK_FAILURE;
100   }
101 
102   if (btif_av_stream_ready()) {
103     /* Setup audio data channel listener */
104     UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
105               A2DP_DATA_PATH);
106 
107     /*
108      * Post start event and wait for audio path to open.
109      * If we are the source, the ACK will be sent after the start
110      * procedure is completed, othewise send it now.
111      */
112     btif_av_stream_start();
113     if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) return A2DP_CTRL_ACK_SUCCESS;
114   }
115 
116   if (btif_av_stream_started_ready()) {
117     /*
118      * Already started, setup audio data channel listener and ACK
119      * back immediately.
120      */
121     UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
122               A2DP_DATA_PATH);
123     return A2DP_CTRL_ACK_SUCCESS;
124   }
125   APPL_TRACE_WARNING("%s: A2DP command start while AV stream is not ready",
126                      __func__);
127   return A2DP_CTRL_ACK_FAILURE;
128 }
129 
btif_a2dp_control_on_stop()130 static tA2DP_CTRL_ACK btif_a2dp_control_on_stop() {
131   if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
132       !btif_a2dp_source_is_streaming()) {
133     /* We are already stopped, just ack back */
134     return A2DP_CTRL_ACK_SUCCESS;
135   }
136   btif_av_stream_stop(RawAddress::kEmpty);
137   return A2DP_CTRL_ACK_SUCCESS;
138 }
139 
btif_a2dp_control_on_suspend()140 static void btif_a2dp_control_on_suspend() {
141   /* Local suspend */
142   if (btif_av_stream_started_ready()) {
143     btif_av_stream_suspend();
144     return;
145   }
146   /* If we are not in started state, just ack back ok and let
147    * audioflinger close the channel. This can happen if we are
148    * remotely suspended, clear REMOTE SUSPEND flag.
149    */
150   btif_av_clear_remote_suspend_flag();
151   btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
152 }
153 
btif_a2dp_control_on_get_input_audio_config()154 static void btif_a2dp_control_on_get_input_audio_config() {
155   tA2DP_SAMPLE_RATE sample_rate = btif_a2dp_sink_get_sample_rate();
156   tA2DP_CHANNEL_COUNT channel_count = btif_a2dp_sink_get_channel_count();
157 
158   btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
159   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
160             reinterpret_cast<uint8_t*>(&sample_rate),
161             sizeof(tA2DP_SAMPLE_RATE));
162   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, &channel_count,
163             sizeof(tA2DP_CHANNEL_COUNT));
164 }
165 
btif_a2dp_control_on_get_output_audio_config()166 static void btif_a2dp_control_on_get_output_audio_config() {
167   btav_a2dp_codec_config_t codec_config;
168   btav_a2dp_codec_config_t codec_capability;
169   codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
170   codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
171   codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
172   codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
173   codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
174   codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
175 
176   A2dpCodecConfig* current_codec = bta_av_get_a2dp_current_codec();
177   if (current_codec != nullptr) {
178     codec_config = current_codec->getCodecConfig();
179     codec_capability = current_codec->getCodecCapability();
180   }
181 
182   btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
183   // Send the current codec config
184   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
185             reinterpret_cast<const uint8_t*>(&codec_config.sample_rate),
186             sizeof(btav_a2dp_codec_sample_rate_t));
187   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
188             reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample),
189             sizeof(btav_a2dp_codec_bits_per_sample_t));
190   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
191             reinterpret_cast<const uint8_t*>(&codec_config.channel_mode),
192             sizeof(btav_a2dp_codec_channel_mode_t));
193   // Send the current codec capability
194   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
195             reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate),
196             sizeof(btav_a2dp_codec_sample_rate_t));
197   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
198             reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample),
199             sizeof(btav_a2dp_codec_bits_per_sample_t));
200   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
201             reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode),
202             sizeof(btav_a2dp_codec_channel_mode_t));
203 }
204 
btif_a2dp_control_on_set_output_audio_config()205 static void btif_a2dp_control_on_set_output_audio_config() {
206   btav_a2dp_codec_config_t codec_config;
207   codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
208   codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
209   codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
210 
211   btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
212   // Send the current codec config
213   if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL,
214                 reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
215                 sizeof(btav_a2dp_codec_sample_rate_t)) !=
216       sizeof(btav_a2dp_codec_sample_rate_t)) {
217     APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL", __func__);
218     return;
219   }
220   if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL,
221                 reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
222                 sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
223       sizeof(btav_a2dp_codec_bits_per_sample_t)) {
224     APPL_TRACE_ERROR("%s: Error reading bits per sample from audio HAL",
225                      __func__);
226     return;
227   }
228   if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL,
229                 reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
230                 sizeof(btav_a2dp_codec_channel_mode_t)) !=
231       sizeof(btav_a2dp_codec_channel_mode_t)) {
232     APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL", __func__);
233     return;
234   }
235   APPL_TRACE_DEBUG(
236       "%s: A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: "
237       "sample_rate=0x%x bits_per_sample=0x%x "
238       "channel_mode=0x%x",
239       __func__, codec_config.sample_rate, codec_config.bits_per_sample,
240       codec_config.channel_mode);
241   btif_a2dp_source_feeding_update_req(codec_config);
242 }
243 
btif_a2dp_control_on_get_presentation_position()244 static void btif_a2dp_control_on_get_presentation_position() {
245   btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
246 
247   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
248             (uint8_t*)&(delay_report_stats.total_bytes_read), sizeof(uint64_t));
249   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0,
250             (uint8_t*)&(delay_report_stats.audio_delay), sizeof(uint16_t));
251 
252   uint32_t seconds = delay_report_stats.timestamp.tv_sec;
253   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&seconds,
254             sizeof(seconds));
255 
256   uint32_t nsec = delay_report_stats.timestamp.tv_nsec;
257   UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&nsec, sizeof(nsec));
258 }
259 
btif_a2dp_recv_ctrl_data(void)260 static void btif_a2dp_recv_ctrl_data(void) {
261   tA2DP_CTRL_CMD cmd = A2DP_CTRL_CMD_NONE;
262   int n;
263 
264   uint8_t read_cmd = 0; /* The read command size is one octet */
265   n = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, &read_cmd, 1);
266   cmd = static_cast<tA2DP_CTRL_CMD>(read_cmd);
267 
268   /* detach on ctrl channel means audioflinger process was terminated */
269   if (n == 0) {
270     APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__);
271     UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL);
272     return;
273   }
274 
275   // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it
276   // could be very chatty when audio is streaming.
277   if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) {
278     APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s", __func__,
279                      audio_a2dp_hw_dump_ctrl_event(cmd));
280   } else {
281     APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__,
282                        audio_a2dp_hw_dump_ctrl_event(cmd));
283   }
284 
285   a2dp_cmd_pending = cmd;
286   switch (cmd) {
287     case A2DP_CTRL_CMD_CHECK_READY:
288       btif_a2dp_command_ack(btif_a2dp_control_on_check_ready());
289       break;
290 
291     case A2DP_CTRL_CMD_START:
292       btif_a2dp_command_ack(btif_a2dp_control_on_start());
293       break;
294 
295     case A2DP_CTRL_CMD_STOP:
296       btif_a2dp_command_ack(btif_a2dp_control_on_stop());
297       break;
298 
299     case A2DP_CTRL_CMD_SUSPEND:
300       btif_a2dp_control_on_suspend();
301       break;
302 
303     case A2DP_CTRL_GET_INPUT_AUDIO_CONFIG:
304       btif_a2dp_control_on_get_input_audio_config();
305       break;
306 
307     case A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG:
308       btif_a2dp_control_on_get_output_audio_config();
309       break;
310 
311     case A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG:
312       btif_a2dp_control_on_set_output_audio_config();
313       break;
314 
315     case A2DP_CTRL_GET_PRESENTATION_POSITION:
316       btif_a2dp_control_on_get_presentation_position();
317       break;
318 
319     default:
320       APPL_TRACE_ERROR("%s: UNSUPPORTED CMD (%d)", __func__, cmd);
321       btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
322       break;
323   }
324 
325   // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it
326   // could be very chatty when audio is streaming.
327   if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) {
328     APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s DONE", __func__,
329                      audio_a2dp_hw_dump_ctrl_event(cmd));
330   } else {
331     APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s DONE", __func__,
332                        audio_a2dp_hw_dump_ctrl_event(cmd));
333   }
334 }
335 
btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,tUIPC_EVENT event)336 static void btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,
337                               tUIPC_EVENT event) {
338   // Don't log UIPC_RX_DATA_READY_EVT by default, because it
339   // could be very chatty when audio is streaming.
340   if (event == UIPC_RX_DATA_READY_EVT) {
341     APPL_TRACE_DEBUG("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__,
342                      dump_uipc_event(event));
343   } else {
344     APPL_TRACE_WARNING("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__,
345                        dump_uipc_event(event));
346   }
347 
348   switch (event) {
349     case UIPC_OPEN_EVT:
350       break;
351 
352     case UIPC_CLOSE_EVT:
353       /* restart ctrl server unless we are shutting down */
354       if (btif_a2dp_source_media_task_is_running())
355         UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, btif_a2dp_ctrl_cb,
356                   A2DP_CTRL_PATH);
357       break;
358 
359     case UIPC_RX_DATA_READY_EVT:
360       btif_a2dp_recv_ctrl_data();
361       break;
362 
363     default:
364       APPL_TRACE_ERROR("%s: ### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###",
365                        __func__, event);
366       break;
367   }
368 }
369 
btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,tUIPC_EVENT event)370 static void btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,
371                               tUIPC_EVENT event) {
372   APPL_TRACE_WARNING("%s: BTIF MEDIA (A2DP-DATA) EVENT %s", __func__,
373                      dump_uipc_event(event));
374 
375   switch (event) {
376     case UIPC_OPEN_EVT:
377       /*
378        * Read directly from media task from here on (keep callback for
379        * connection events.
380        */
381       UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO,
382                  UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
383       UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
384                  reinterpret_cast<void*>(A2DP_DATA_READ_POLL_MS));
385 
386       if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
387         /* Start the media task to encode the audio */
388         btif_a2dp_source_start_audio_req();
389       }
390 
391       /* ACK back when media task is fully started */
392       break;
393 
394     case UIPC_CLOSE_EVT:
395       APPL_TRACE_EVENT("%s: ## AUDIO PATH DETACHED ##", __func__);
396       btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
397       /*
398        * Send stop request only if we are actively streaming and haven't
399        * received a stop request. Potentially, the audioflinger detached
400        * abnormally.
401        */
402       if (btif_a2dp_source_is_streaming()) {
403         /* Post stop event and wait for audio path to stop */
404         btif_av_stream_stop(RawAddress::kEmpty);
405       }
406       break;
407 
408     default:
409       APPL_TRACE_ERROR("%s: ### A2DP-DATA EVENT %d NOT HANDLED ###", __func__,
410                        event);
411       break;
412   }
413 }
414 
btif_a2dp_command_ack(tA2DP_CTRL_ACK status)415 void btif_a2dp_command_ack(tA2DP_CTRL_ACK status) {
416   uint8_t ack = status;
417 
418   // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it
419   // could be very chatty when audio is streaming.
420   if (a2dp_cmd_pending == A2DP_CTRL_GET_PRESENTATION_POSITION) {
421     APPL_TRACE_DEBUG("%s: ## a2dp ack : %s, status %d ##", __func__,
422                      audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status);
423   } else {
424     APPL_TRACE_WARNING("%s: ## a2dp ack : %s, status %d ##", __func__,
425                        audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status);
426   }
427 
428   /* Sanity check */
429   if (a2dp_cmd_pending == A2DP_CTRL_CMD_NONE) {
430     APPL_TRACE_ERROR("%s: warning : no command pending, ignore ack", __func__);
431     return;
432   }
433 
434   /* Clear pending */
435   a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
436 
437   /* Acknowledge start request */
438   if (a2dp_uipc != nullptr) {
439     UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack));
440   }
441 }
442 
btif_a2dp_control_log_bytes_read(uint32_t bytes_read)443 void btif_a2dp_control_log_bytes_read(uint32_t bytes_read) {
444   delay_report_stats.total_bytes_read += bytes_read;
445   clock_gettime(CLOCK_MONOTONIC, &delay_report_stats.timestamp);
446 }
447 
btif_a2dp_control_set_audio_delay(uint16_t delay)448 void btif_a2dp_control_set_audio_delay(uint16_t delay) {
449   APPL_TRACE_DEBUG("%s: DELAY: %.1f ms", __func__, (float)delay / 10);
450   delay_report_stats.audio_delay = delay;
451 }
452 
btif_a2dp_control_reset_audio_delay(void)453 void btif_a2dp_control_reset_audio_delay(void) {
454   APPL_TRACE_DEBUG("%s", __func__);
455   delay_report_stats.audio_delay = 0;
456   delay_report_stats.total_bytes_read = 0;
457   delay_report_stats.timestamp = {};
458 }
459