1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2012 Broadcom Corporation
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
19
20 /*****************************************************************************
21 *
22 * Filename: btif_av.c
23 *
24 * Description: Bluedroid AV implementation
25 *
26 *****************************************************************************/
27
28 #include <hardware/bluetooth.h>
29 #include <system/audio.h>
30 #include "hardware/bt_av.h"
31
32 #define LOG_TAG "BTIF_AV"
33
34 #include "btif_av.h"
35 #include "btif_util.h"
36 #include "btif_profile_queue.h"
37 #include "bta_api.h"
38 #include "btif_media.h"
39 #include "bta_av_api.h"
40 #include "gki.h"
41 #include "bd.h"
42 #include "btu.h"
43 #include "bt_utils.h"
44
45 /*****************************************************************************
46 ** Constants & Macros
47 ******************************************************************************/
48 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
49
50 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
51
52 typedef enum {
53 BTIF_AV_STATE_IDLE = 0x0,
54 BTIF_AV_STATE_OPENING,
55 BTIF_AV_STATE_OPENED,
56 BTIF_AV_STATE_STARTED,
57 BTIF_AV_STATE_CLOSING
58 } btif_av_state_t;
59
60 /* Should not need dedicated suspend state as actual actions are no
61 different than open state. Suspend flags are needed however to prevent
62 media task from trying to restart stream during remote suspend or while
63 we are in the process of a local suspend */
64
65 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
66 #define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
67 #define BTIF_AV_FLAG_PENDING_START 0x4
68 #define BTIF_AV_FLAG_PENDING_STOP 0x8
69
70 /*****************************************************************************
71 ** Local type definitions
72 ******************************************************************************/
73
74 typedef struct
75 {
76 tBTA_AV_HNDL bta_handle;
77 bt_bdaddr_t peer_bda;
78 btif_sm_handle_t sm_handle;
79 UINT8 flags;
80 tBTA_AV_EDR edr;
81 UINT8 peer_sep; /* sep type of peer device */
82 } btif_av_cb_t;
83
84 typedef struct
85 {
86 bt_bdaddr_t *target_bda;
87 uint16_t uuid;
88 } btif_av_connect_req_t;
89
90 typedef struct
91 {
92 int sample_rate;
93 int channel_count;
94 } btif_av_sink_config_req_t;
95
96 /*****************************************************************************
97 ** Static variables
98 ******************************************************************************/
99 static btav_callbacks_t *bt_av_src_callbacks = NULL;
100 static btav_callbacks_t *bt_av_sink_callbacks = NULL;
101 static btif_av_cb_t btif_av_cb;
102 static TIMER_LIST_ENT tle_av_open_on_rc;
103
104 /* both interface and media task needs to be ready to alloc incoming request */
105 #define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
106 || (btif_av_cb.sm_handle == NULL))\
107 {\
108 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
109 return BT_STATUS_NOT_READY;\
110 }\
111 else\
112 {\
113 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
114 }
115
116 /* Helper macro to avoid code duplication in the state machine handlers */
117 #define CHECK_RC_EVENT(e, d) \
118 case BTA_AV_RC_OPEN_EVT: \
119 case BTA_AV_RC_CLOSE_EVT: \
120 case BTA_AV_REMOTE_CMD_EVT: \
121 case BTA_AV_VENDOR_CMD_EVT: \
122 case BTA_AV_META_MSG_EVT: \
123 case BTA_AV_RC_FEAT_EVT: \
124 { \
125 btif_rc_handler(e, d);\
126 }break; \
127
128 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
129 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
130 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
131 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
132 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
133
134 static const btif_sm_handler_t btif_av_state_handlers[] =
135 {
136 btif_av_state_idle_handler,
137 btif_av_state_opening_handler,
138 btif_av_state_opened_handler,
139 btif_av_state_started_handler,
140 btif_av_state_closing_handler
141 };
142
143 /*************************************************************************
144 ** Extern functions
145 *************************************************************************/
146 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
147 extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
148 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
149
150 /*****************************************************************************
151 ** Local helper functions
152 ******************************************************************************/
153
dump_av_sm_state_name(btif_av_state_t state)154 const char *dump_av_sm_state_name(btif_av_state_t state)
155 {
156 switch (state)
157 {
158 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
159 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
160 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
161 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
162 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
163 default: return "UNKNOWN_STATE";
164 }
165 }
166
dump_av_sm_event_name(btif_av_sm_event_t event)167 const char *dump_av_sm_event_name(btif_av_sm_event_t event)
168 {
169 switch((int)event)
170 {
171 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
172 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
173 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
174 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
175 CASE_RETURN_STR(BTA_AV_START_EVT)
176 CASE_RETURN_STR(BTA_AV_STOP_EVT)
177 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
178 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
179 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
180 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
181 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
182 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
183 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
184 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
185 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
186 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
187 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
188 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
189 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
190 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
191 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
192 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
193 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
194 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
195 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
196 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
197 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
198 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
199 default: return "UNKNOWN_EVENT";
200 }
201 }
202
203 /****************************************************************************
204 ** Local helper functions
205 *****************************************************************************/
206 /*******************************************************************************
207 **
208 ** Function btif_initiate_av_open_tmr_hdlr
209 **
210 ** Description Timer to trigger AV open if the remote headset establishes
211 ** RC connection w/o AV connection. The timer is needed to IOP
212 ** with headsets that do establish AV after RC connection.
213 **
214 ** Returns void
215 **
216 *******************************************************************************/
btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT * tle)217 static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
218 {
219 BD_ADDR peer_addr;
220 UNUSED(tle);
221 btif_av_connect_req_t connect_req;
222 UNUSED(tle);
223 /* is there at least one RC connection - There should be */
224 if (btif_rc_get_connected_peer(peer_addr)) {
225 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
226 /* In case of AVRCP connection request, we will initiate SRC connection */
227 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
228 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
229 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
230 }
231 else
232 {
233 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
234 }
235 }
236
237 /*****************************************************************************
238 ** Static functions
239 ******************************************************************************/
240
btif_report_connection_state(btav_connection_state_t state,bt_bdaddr_t * bd_addr)241 static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
242 {
243 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
244 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
245 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
246 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
247 }
248 }
249
btif_report_audio_state(btav_audio_state_t state,bt_bdaddr_t * bd_addr)250 static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
251 {
252 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
253 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
254 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
255 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
256 }
257 }
258
259 /*****************************************************************************
260 **
261 ** Function btif_av_state_idle_handler
262 **
263 ** Description State managing disconnected AV link
264 **
265 ** Returns TRUE if event was processed, FALSE otherwise
266 **
267 *******************************************************************************/
268
btif_av_state_idle_handler(btif_sm_event_t event,void * p_data)269 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
270 {
271 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
272 dump_av_sm_event_name(event), btif_av_cb.flags);
273
274 switch (event)
275 {
276 case BTIF_SM_ENTER_EVT:
277 /* clear the peer_bda */
278 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
279 btif_av_cb.flags = 0;
280 btif_av_cb.edr = 0;
281 btif_a2dp_on_idle();
282 break;
283
284 case BTIF_SM_EXIT_EVT:
285 break;
286
287 case BTA_AV_ENABLE_EVT:
288 break;
289
290 case BTA_AV_REGISTER_EVT:
291 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
292 break;
293
294 case BTA_AV_PENDING_EVT:
295 case BTIF_AV_CONNECT_REQ_EVT:
296 {
297 if (event == BTIF_AV_CONNECT_REQ_EVT)
298 {
299 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
300 sizeof(bt_bdaddr_t));
301 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
302 TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid);
303 }
304 else if (event == BTA_AV_PENDING_EVT)
305 {
306 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
307 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
308 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE);
309 }
310 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
311 } break;
312
313 case BTA_AV_RC_OPEN_EVT:
314 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
315 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
316 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
317 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
318 * headsets, as some headsets initiate the AVRC connection first and then
319 * immediately initiate the AV connection
320 *
321 * TODO: We may need to do this only on an AVRCP Play. FixMe
322 */
323
324 BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
325 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
326 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
327 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
328 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
329 btif_rc_handler(event, p_data);
330 break;
331
332 case BTA_AV_REMOTE_CMD_EVT:
333 case BTA_AV_VENDOR_CMD_EVT:
334 case BTA_AV_META_MSG_EVT:
335 case BTA_AV_RC_FEAT_EVT:
336 btif_rc_handler(event, (tBTA_AV*)p_data);
337 break;
338
339 case BTA_AV_RC_CLOSE_EVT:
340 if (tle_av_open_on_rc.in_use) {
341 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
342 btu_stop_timer(&tle_av_open_on_rc);
343 }
344 btif_rc_handler(event, p_data);
345 break;
346
347 default:
348 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
349 dump_av_sm_event_name(event));
350 return FALSE;
351
352 }
353 return TRUE;
354 }
355 /*****************************************************************************
356 **
357 ** Function btif_av_state_opening_handler
358 **
359 ** Description Intermediate state managing events during establishment
360 ** of avdtp channel
361 **
362 ** Returns TRUE if event was processed, FALSE otherwise
363 **
364 *******************************************************************************/
365
btif_av_state_opening_handler(btif_sm_event_t event,void * p_data)366 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
367 {
368 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
369 dump_av_sm_event_name(event), btif_av_cb.flags);
370
371 switch (event)
372 {
373 case BTIF_SM_ENTER_EVT:
374 /* inform the application that we are entering connecting state */
375 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
376 break;
377
378 case BTIF_SM_EXIT_EVT:
379 break;
380
381 case BTA_AV_REJECT_EVT:
382 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
383 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
384 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
385 break;
386
387 case BTA_AV_OPEN_EVT:
388 {
389 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
390 btav_connection_state_t state;
391 btif_sm_state_t av_state;
392 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
393 p_bta_data->open.edr);
394
395 if (p_bta_data->open.status == BTA_AV_SUCCESS)
396 {
397 state = BTAV_CONNECTION_STATE_CONNECTED;
398 av_state = BTIF_AV_STATE_OPENED;
399 btif_av_cb.edr = p_bta_data->open.edr;
400
401 btif_av_cb.peer_sep = p_bta_data->open.sep;
402 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
403 }
404 else
405 {
406 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
407 p_bta_data->open.status );
408 state = BTAV_CONNECTION_STATE_DISCONNECTED;
409 av_state = BTIF_AV_STATE_IDLE;
410 }
411
412 /* inform the application of the event */
413 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
414 /* change state to open/idle based on the status */
415 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
416 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
417 {
418 /* if queued PLAY command, send it now */
419 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
420 (p_bta_data->open.status == BTA_AV_SUCCESS));
421 }
422 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
423 {
424 /* if queued PLAY command, send it now */
425 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
426 /* Bring up AVRCP connection too */
427 BTA_AvOpenRc(btif_av_cb.bta_handle);
428 }
429 btif_queue_advance();
430 } break;
431
432 case BTIF_AV_SINK_CONFIG_REQ_EVT:
433 {
434 btif_av_sink_config_req_t req;
435 // copy to avoid alignment problems
436 memcpy(&req, p_data, sizeof(req));
437
438 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
439 req.channel_count);
440 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
441 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
442 req.sample_rate, req.channel_count);
443 }
444 } break;
445
446 CHECK_RC_EVENT(event, p_data);
447
448 default:
449 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
450 dump_av_sm_event_name(event));
451 return FALSE;
452
453 }
454 return TRUE;
455 }
456
457
458 /*****************************************************************************
459 **
460 ** Function btif_av_state_closing_handler
461 **
462 ** Description Intermediate state managing events during closing
463 ** of avdtp channel
464 **
465 ** Returns TRUE if event was processed, FALSE otherwise
466 **
467 *******************************************************************************/
468
btif_av_state_closing_handler(btif_sm_event_t event,void * p_data)469 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
470 {
471 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
472 dump_av_sm_event_name(event), btif_av_cb.flags);
473
474 switch (event)
475 {
476 case BTIF_SM_ENTER_EVT:
477 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
478 {
479 /* immediately stop transmission of frames */
480 btif_a2dp_set_tx_flush(TRUE);
481 /* wait for audioflinger to stop a2dp */
482 }
483 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
484 {
485 btif_a2dp_set_rx_flush(TRUE);
486 }
487 break;
488
489 case BTA_AV_STOP_EVT:
490 case BTIF_AV_STOP_STREAM_REQ_EVT:
491 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
492 {
493 /* immediately flush any pending tx frames while suspend is pending */
494 btif_a2dp_set_tx_flush(TRUE);
495 }
496 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
497 {
498 btif_a2dp_set_rx_flush(TRUE);
499 }
500
501 btif_a2dp_on_stopped(NULL);
502 break;
503
504 case BTIF_SM_EXIT_EVT:
505 break;
506
507 case BTA_AV_CLOSE_EVT:
508
509 /* inform the application that we are disconnecting */
510 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
511
512 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
513 break;
514
515 /* Handle the RC_CLOSE event for the cleanup */
516 case BTA_AV_RC_CLOSE_EVT:
517 btif_rc_handler(event, (tBTA_AV*)p_data);
518 break;
519
520 default:
521 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
522 dump_av_sm_event_name(event));
523 return FALSE;
524 }
525 return TRUE;
526 }
527
528
529 /*****************************************************************************
530 **
531 ** Function btif_av_state_opened_handler
532 **
533 ** Description Handles AV events while AVDTP is in OPEN state
534 **
535 ** Returns TRUE if event was processed, FALSE otherwise
536 **
537 *******************************************************************************/
538
btif_av_state_opened_handler(btif_sm_event_t event,void * p_data)539 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
540 {
541 tBTA_AV *p_av = (tBTA_AV*)p_data;
542
543 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
544 dump_av_sm_event_name(event), btif_av_cb.flags);
545
546 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
547 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
548 {
549 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
550 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
551 }
552
553 switch (event)
554 {
555 case BTIF_SM_ENTER_EVT:
556 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
557 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
558 break;
559
560 case BTIF_SM_EXIT_EVT:
561 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
562 break;
563
564 case BTIF_AV_START_STREAM_REQ_EVT:
565 if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
566 btif_a2dp_setup_codec();
567 BTA_AvStart();
568 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
569 break;
570
571 case BTA_AV_START_EVT:
572 {
573 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
574 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
575
576 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
577 return TRUE;
578
579 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
580 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
581 {
582 if (btif_a2dp_on_started(&p_av->start,
583 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
584 {
585 /* only clear pending flag after acknowledgement */
586 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
587 }
588 }
589
590 /* remain in open state if status failed */
591 if (p_av->start.status != BTA_AV_SUCCESS)
592 return FALSE;
593
594 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
595 {
596 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
597 }
598
599 /* change state to started, send acknowledgement if start is pending */
600 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
601 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
602 btif_a2dp_on_started(NULL, TRUE);
603 /* pending start flag will be cleared when exit current state */
604 }
605 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
606
607 } break;
608
609 case BTIF_AV_DISCONNECT_REQ_EVT:
610 BTA_AvClose(btif_av_cb.bta_handle);
611 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
612 BTA_AvCloseRc(btif_av_cb.bta_handle);
613 }
614
615 /* inform the application that we are disconnecting */
616 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
617 break;
618
619 case BTA_AV_CLOSE_EVT:
620 /* avdtp link is closed */
621 btif_a2dp_on_stopped(NULL);
622
623 /* inform the application that we are disconnected */
624 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
625
626 /* change state to idle, send acknowledgement if start is pending */
627 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
628 btif_a2dp_ack_fail();
629 /* pending start flag will be cleared when exit current state */
630 }
631 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
632 break;
633
634 case BTA_AV_RECONFIG_EVT:
635 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
636 (p_av->reconfig.status == BTA_AV_SUCCESS))
637 {
638 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
639 BTA_AvStart();
640 }
641 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
642 {
643 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
644 btif_a2dp_ack_fail();
645 }
646 break;
647
648 CHECK_RC_EVENT(event, p_data);
649
650 default:
651 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
652 dump_av_sm_event_name(event));
653 return FALSE;
654
655 }
656 return TRUE;
657 }
658
659 /*****************************************************************************
660 **
661 ** Function btif_av_state_started_handler
662 **
663 ** Description Handles AV events while A2DP stream is started
664 **
665 ** Returns TRUE if event was processed, FALSE otherwise
666 **
667 *******************************************************************************/
668
btif_av_state_started_handler(btif_sm_event_t event,void * p_data)669 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
670 {
671 tBTA_AV *p_av = (tBTA_AV*)p_data;
672
673 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
674 dump_av_sm_event_name(event), btif_av_cb.flags);
675
676 switch (event)
677 {
678 case BTIF_SM_ENTER_EVT:
679
680 /* we are again in started state, clear any remote suspend flags */
681 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
682
683 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
684
685 /* increase the a2dp consumer task priority temporarily when start
686 ** audio playing, to avoid overflow the audio packet queue. */
687 adjust_priority_a2dp(TRUE);
688
689 break;
690
691 case BTIF_SM_EXIT_EVT:
692 /* restore the a2dp consumer task priority when stop audio playing. */
693 adjust_priority_a2dp(FALSE);
694
695 break;
696
697 case BTIF_AV_START_STREAM_REQ_EVT:
698 /* we were remotely started, just ack back the local request */
699 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
700 btif_a2dp_on_started(NULL, TRUE);
701 break;
702
703 /* fixme -- use suspend = true always to work around issue with BTA AV */
704 case BTIF_AV_STOP_STREAM_REQ_EVT:
705 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
706
707 /* set pending flag to ensure btif task is not trying to restart
708 stream while suspend is in progress */
709 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
710
711 /* if we were remotely suspended but suspend locally, local suspend
712 always overrides */
713 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
714
715 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
716 {
717 /* immediately stop transmission of frames while suspend is pending */
718 btif_a2dp_set_tx_flush(TRUE);
719 }
720
721 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
722 btif_a2dp_set_rx_flush(TRUE);
723 btif_a2dp_on_stopped(NULL);
724 }
725
726 BTA_AvStop(TRUE);
727 break;
728
729 case BTIF_AV_DISCONNECT_REQ_EVT:
730
731 /* request avdtp to close */
732 BTA_AvClose(btif_av_cb.bta_handle);
733 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
734 BTA_AvCloseRc(btif_av_cb.bta_handle);
735 }
736
737 /* inform the application that we are disconnecting */
738 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
739
740 /* wait in closing state until fully closed */
741 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
742 break;
743
744 case BTA_AV_SUSPEND_EVT:
745
746 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
747 p_av->suspend.status, p_av->suspend.initiator);
748
749 /* a2dp suspended, stop media task until resumed */
750 btif_a2dp_on_suspended(&p_av->suspend);
751
752 /* if not successful, remain in current state */
753 if (p_av->suspend.status != BTA_AV_SUCCESS)
754 {
755 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
756
757 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
758 {
759 /* suspend failed, reset back tx flush state */
760 btif_a2dp_set_tx_flush(FALSE);
761 }
762 return FALSE;
763 }
764
765 if (p_av->suspend.initiator != TRUE)
766 {
767 /* remote suspend, notify HAL and await audioflinger to
768 suspend/stop stream */
769
770 /* set remote suspend flag to block media task from restarting
771 stream only if we did not already initiate a local suspend */
772 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
773 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
774
775 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
776 }
777 else
778 {
779 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
780 }
781
782 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
783
784 /* suspend completed and state changed, clear pending status */
785 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
786 break;
787
788 case BTA_AV_STOP_EVT:
789
790 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
791 btif_a2dp_on_stopped(&p_av->suspend);
792
793 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
794
795 /* if stop was successful, change state to open */
796 if (p_av->suspend.status == BTA_AV_SUCCESS)
797 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
798
799 break;
800
801 case BTA_AV_CLOSE_EVT:
802
803 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
804
805 /* avdtp link is closed */
806 btif_a2dp_on_stopped(NULL);
807
808 /* inform the application that we are disconnected */
809 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
810
811 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
812 break;
813
814 CHECK_RC_EVENT(event, p_data);
815
816 default:
817 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
818 dump_av_sm_event_name(event));
819 return FALSE;
820
821 }
822 return TRUE;
823 }
824
825 /*****************************************************************************
826 ** Local event handlers
827 ******************************************************************************/
828
btif_av_handle_event(UINT16 event,char * p_param)829 static void btif_av_handle_event(UINT16 event, char* p_param)
830 {
831 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
832 }
833
bte_av_callback(tBTA_AV_EVT event,tBTA_AV * p_data)834 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
835 {
836 /* Switch to BTIF context */
837 btif_transfer_context(btif_av_handle_event, event,
838 (char*)p_data, sizeof(tBTA_AV), NULL);
839 }
840
bte_av_media_callback(tBTA_AV_EVT event,tBTA_AV_MEDIA * p_data)841 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
842 {
843 btif_sm_state_t state;
844 UINT8 que_len;
845 tA2D_STATUS a2d_status;
846 tA2D_SBC_CIE sbc_cie;
847 btif_av_sink_config_req_t config_req;
848
849 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
850 {
851 state= btif_sm_get_state(btif_av_cb.sm_handle);
852 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
853 (state == BTIF_AV_STATE_OPENED) )
854 {
855 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
856 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
857 }
858 else
859 return;
860 }
861
862 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
863 /* send a command to BT Media Task */
864 btif_reset_decoder((UINT8*)p_data);
865
866 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
867 if (a2d_status == A2D_SUCCESS) {
868 /* Switch to BTIF context */
869 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
870 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
871 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
872 (char*)&config_req, sizeof(config_req), NULL);
873 } else {
874 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
875 }
876 }
877 }
878 /*******************************************************************************
879 **
880 ** Function btif_av_init
881 **
882 ** Description Initializes btif AV if not already done
883 **
884 ** Returns bt_status_t
885 **
886 *******************************************************************************/
887
btif_av_init()888 bt_status_t btif_av_init()
889 {
890 if (btif_av_cb.sm_handle == NULL)
891 {
892 if (btif_a2dp_start_media_task() != GKI_SUCCESS)
893 return BT_STATUS_FAIL;
894
895 btif_enable_service(BTA_A2DP_SERVICE_ID);
896
897 /* Also initialize the AV state machine */
898 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
899
900 btif_a2dp_on_init();
901
902 return BT_STATUS_SUCCESS;
903 }
904
905 return BT_STATUS_DONE;
906 }
907
908 /*******************************************************************************
909 **
910 ** Function init_src
911 **
912 ** Description Initializes the AV interface for source mode
913 **
914 ** Returns bt_status_t
915 **
916 *******************************************************************************/
917
init_src(btav_callbacks_t * callbacks)918 static bt_status_t init_src(btav_callbacks_t* callbacks)
919 {
920 bt_status_t status;
921
922 BTIF_TRACE_EVENT("%s", __FUNCTION__);
923
924 if (bt_av_sink_callbacks != NULL) {
925 // already did btif_av_init()
926 status = BT_STATUS_SUCCESS;
927 } else {
928 status = btif_av_init();
929 }
930
931 if (status == BT_STATUS_SUCCESS) {
932 bt_av_src_callbacks = callbacks;
933 }
934
935 return status;
936 }
937
938 /*******************************************************************************
939 **
940 ** Function init_sink
941 **
942 ** Description Initializes the AV interface for sink mode
943 **
944 ** Returns bt_status_t
945 **
946 *******************************************************************************/
947
init_sink(btav_callbacks_t * callbacks)948 static bt_status_t init_sink(btav_callbacks_t* callbacks)
949 {
950 bt_status_t status;
951
952 BTIF_TRACE_EVENT("%s", __FUNCTION__);
953
954 if (bt_av_src_callbacks != NULL) {
955 // already did btif_av_init()
956 status = BT_STATUS_SUCCESS;
957 } else {
958 status = btif_av_init();
959 }
960
961 if (status == BT_STATUS_SUCCESS) {
962 bt_av_sink_callbacks = callbacks;
963 BTA_AvEnable_Sink(TRUE);
964 }
965
966 return status;
967 }
968
969 /*******************************************************************************
970 **
971 ** Function connect
972 **
973 ** Description Establishes the AV signalling channel with the remote headset
974 **
975 ** Returns bt_status_t
976 **
977 *******************************************************************************/
978
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)979 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
980 {
981 btif_av_connect_req_t connect_req;
982 connect_req.target_bda = bd_addr;
983 connect_req.uuid = uuid;
984 BTIF_TRACE_EVENT("%s", __FUNCTION__);
985
986 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
987
988 return BT_STATUS_SUCCESS;
989 }
990
src_connect_sink(bt_bdaddr_t * bd_addr)991 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
992 {
993 BTIF_TRACE_EVENT("%s", __FUNCTION__);
994 CHECK_BTAV_INIT();
995
996 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
997 }
998
sink_connect_src(bt_bdaddr_t * bd_addr)999 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1000 {
1001 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1002 CHECK_BTAV_INIT();
1003
1004 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1005 }
1006
1007 /*******************************************************************************
1008 **
1009 ** Function disconnect
1010 **
1011 ** Description Tears down the AV signalling channel with the remote headset
1012 **
1013 ** Returns bt_status_t
1014 **
1015 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)1016 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1017 {
1018 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1019
1020 CHECK_BTAV_INIT();
1021
1022 /* Switch to BTIF context */
1023 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1024 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1025 }
1026
1027 /*******************************************************************************
1028 **
1029 ** Function cleanup
1030 **
1031 ** Description Shuts down the AV interface and does the cleanup
1032 **
1033 ** Returns None
1034 **
1035 *******************************************************************************/
cleanup(void)1036 static void cleanup(void)
1037 {
1038 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1039
1040 btif_a2dp_stop_media_task();
1041
1042 btif_disable_service(BTA_A2DP_SERVICE_ID);
1043
1044 /* Also shut down the AV state machine */
1045 btif_sm_shutdown(btif_av_cb.sm_handle);
1046 btif_av_cb.sm_handle = NULL;
1047 }
1048
cleanup_src(void)1049 static void cleanup_src(void) {
1050 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1051
1052 if (bt_av_src_callbacks)
1053 {
1054 bt_av_src_callbacks = NULL;
1055 if (bt_av_sink_callbacks == NULL)
1056 cleanup();
1057 }
1058 }
1059
cleanup_sink(void)1060 static void cleanup_sink(void) {
1061 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1062
1063 if (bt_av_sink_callbacks)
1064 {
1065 bt_av_sink_callbacks = NULL;
1066 if (bt_av_src_callbacks == NULL)
1067 cleanup();
1068 }
1069 }
1070
1071 static const btav_interface_t bt_av_src_interface = {
1072 sizeof(btav_interface_t),
1073 init_src,
1074 src_connect_sink,
1075 disconnect,
1076 cleanup_src,
1077 };
1078
1079 static const btav_interface_t bt_av_sink_interface = {
1080 sizeof(btav_interface_t),
1081 init_sink,
1082 sink_connect_src,
1083 disconnect,
1084 cleanup_sink,
1085 };
1086
1087 /*******************************************************************************
1088 **
1089 ** Function btif_av_get_sm_handle
1090 **
1091 ** Description Fetches current av SM handle
1092 **
1093 ** Returns None
1094 **
1095 *******************************************************************************/
1096
btif_av_get_sm_handle(void)1097 btif_sm_handle_t btif_av_get_sm_handle(void)
1098 {
1099 return btif_av_cb.sm_handle;
1100 }
1101
1102 /*******************************************************************************
1103 **
1104 ** Function btif_av_stream_ready
1105 **
1106 ** Description Checks whether AV is ready for starting a stream
1107 **
1108 ** Returns None
1109 **
1110 *******************************************************************************/
1111
btif_av_stream_ready(void)1112 BOOLEAN btif_av_stream_ready(void)
1113 {
1114 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1115
1116 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1117 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1118
1119 /* also make sure main adapter is enabled */
1120 if (btif_is_enabled() == 0)
1121 {
1122 BTIF_TRACE_EVENT("main adapter not enabled");
1123 return FALSE;
1124 }
1125
1126 /* check if we are remotely suspended or stop is pending */
1127 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1128 return FALSE;
1129
1130 return (state == BTIF_AV_STATE_OPENED);
1131 }
1132
1133 /*******************************************************************************
1134 **
1135 ** Function btif_av_stream_started_ready
1136 **
1137 ** Description Checks whether AV ready for media start in streaming state
1138 **
1139 ** Returns None
1140 **
1141 *******************************************************************************/
1142
btif_av_stream_started_ready(void)1143 BOOLEAN btif_av_stream_started_ready(void)
1144 {
1145 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1146
1147 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1148 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1149
1150 /* disallow media task to start if we have pending actions */
1151 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1152 | BTIF_AV_FLAG_PENDING_STOP))
1153 return FALSE;
1154
1155 return (state == BTIF_AV_STATE_STARTED);
1156 }
1157
1158 /*******************************************************************************
1159 **
1160 ** Function btif_dispatch_sm_event
1161 **
1162 ** Description Send event to AV statemachine
1163 **
1164 ** Returns None
1165 **
1166 *******************************************************************************/
1167
1168 /* used to pass events to AV statemachine from other tasks */
btif_dispatch_sm_event(btif_av_sm_event_t event,void * p_data,int len)1169 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1170 {
1171 /* Switch to BTIF context */
1172 btif_transfer_context(btif_av_handle_event, event,
1173 (char*)p_data, len, NULL);
1174 }
1175
1176 /*******************************************************************************
1177 **
1178 ** Function btif_av_execute_service
1179 **
1180 ** Description Initializes/Shuts down the service
1181 **
1182 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1183 **
1184 *******************************************************************************/
btif_av_execute_service(BOOLEAN b_enable)1185 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1186 {
1187 if (b_enable)
1188 {
1189 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1190 * handle this request in order to allow incoming connections to succeed.
1191 * We need to put this back once support for this is added */
1192
1193 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1194 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1195 * be initiated by the app/audioflinger layers */
1196 #if (AVRC_METADATA_INCLUDED == TRUE)
1197 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1198 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1199 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1200 |BTA_AV_FEAT_RCCT
1201 |BTA_AV_FEAT_ADV_CTRL
1202 #endif
1203 ,bte_av_callback);
1204 #else
1205 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1206 bte_av_callback);
1207 #endif
1208 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1209 }
1210 else {
1211 BTA_AvDeregister(btif_av_cb.bta_handle);
1212 BTA_AvDisable();
1213 }
1214 return BT_STATUS_SUCCESS;
1215 }
1216
1217 /*******************************************************************************
1218 **
1219 ** Function btif_av_get_src_interface
1220 **
1221 ** Description Get the AV callback interface for A2DP source profile
1222 **
1223 ** Returns btav_interface_t
1224 **
1225 *******************************************************************************/
btif_av_get_src_interface(void)1226 const btav_interface_t *btif_av_get_src_interface(void)
1227 {
1228 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1229 return &bt_av_src_interface;
1230 }
1231
1232 /*******************************************************************************
1233 **
1234 ** Function btif_av_get_sink_interface
1235 **
1236 ** Description Get the AV callback interface for A2DP sink profile
1237 **
1238 ** Returns btav_interface_t
1239 **
1240 *******************************************************************************/
btif_av_get_sink_interface(void)1241 const btav_interface_t *btif_av_get_sink_interface(void)
1242 {
1243 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1244 return &bt_av_sink_interface;
1245 }
1246
1247 /*******************************************************************************
1248 **
1249 ** Function btif_av_is_connected
1250 **
1251 ** Description Checks if av has a connected sink
1252 **
1253 ** Returns BOOLEAN
1254 **
1255 *******************************************************************************/
btif_av_is_connected(void)1256 BOOLEAN btif_av_is_connected(void)
1257 {
1258 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1259 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1260 }
1261
1262 /*******************************************************************************
1263 **
1264 ** Function btif_av_is_peer_edr
1265 **
1266 ** Description Check if the connected a2dp device supports
1267 ** EDR or not. Only when connected this function
1268 ** will accurately provide a true capability of
1269 ** remote peer. If not connected it will always be false.
1270 **
1271 ** Returns TRUE if remote device is capable of EDR
1272 **
1273 *******************************************************************************/
btif_av_is_peer_edr(void)1274 BOOLEAN btif_av_is_peer_edr(void)
1275 {
1276 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1277
1278 if (btif_av_cb.edr)
1279 return TRUE;
1280 else
1281 return FALSE;
1282 }
1283
1284