OSDN Git Service

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