OSDN Git Service

am d9e2d0f1: Bluetooth: Restarting PM timer during incoming rfcomm data.
[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 "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
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
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 *******************************************************************************/
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
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
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
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
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
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
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             {
567                 BTA_AvStart();
568                 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
569                 break;
570             }
571             btif_a2dp_setup_codec();
572             BTA_AvStart();
573             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
574             break;
575
576         case BTA_AV_START_EVT:
577         {
578             BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
579                 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
580
581             if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
582                 return TRUE;
583
584             /*  In case peer is A2DP SRC we do not want to ack commands on UIPC*/
585             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
586             {
587                 if (btif_a2dp_on_started(&p_av->start,
588                     ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
589                 {
590                     /* only clear pending flag after acknowledgement */
591                     btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
592                 }
593             }
594
595             /* remain in open state if status failed */
596             if (p_av->start.status != BTA_AV_SUCCESS)
597                 return FALSE;
598
599             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
600             {
601                 btif_a2dp_set_rx_flush(FALSE); /*  remove flush state, ready for streaming*/
602             }
603
604             /* change state to started, send acknowledgement if start is pending */
605             if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
606                 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
607                     btif_a2dp_on_started(NULL, TRUE);
608                 /* pending start flag will be cleared when exit current state */
609             }
610             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
611
612         } break;
613
614         case BTIF_AV_DISCONNECT_REQ_EVT:
615             BTA_AvClose(btif_av_cb.bta_handle);
616             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
617                 BTA_AvCloseRc(btif_av_cb.bta_handle);
618             }
619
620             /* inform the application that we are disconnecting */
621             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
622             break;
623
624         case BTA_AV_CLOSE_EVT:
625              /* avdtp link is closed */
626             btif_a2dp_on_stopped(NULL);
627
628             /* inform the application that we are disconnected */
629             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
630
631             /* change state to idle, send acknowledgement if start is pending */
632             if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
633                 btif_a2dp_ack_fail();
634                 /* pending start flag will be cleared when exit current state */
635             }
636             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
637             break;
638
639         case BTA_AV_RECONFIG_EVT:
640             if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
641                 (p_av->reconfig.status == BTA_AV_SUCCESS))
642             {
643                APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
644                BTA_AvStart();
645             }
646             else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
647             {
648                btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
649                btif_a2dp_ack_fail();
650             }
651             break;
652
653         CHECK_RC_EVENT(event, p_data);
654
655         default:
656             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
657                                dump_av_sm_event_name(event));
658             return FALSE;
659
660     }
661     return TRUE;
662 }
663
664 /*****************************************************************************
665 **
666 ** Function     btif_av_state_started_handler
667 **
668 ** Description  Handles AV events while A2DP stream is started
669 **
670 ** Returns      TRUE if event was processed, FALSE otherwise
671 **
672 *******************************************************************************/
673
674 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
675 {
676     tBTA_AV *p_av = (tBTA_AV*)p_data;
677
678     BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
679                      dump_av_sm_event_name(event), btif_av_cb.flags);
680
681     switch (event)
682     {
683         case BTIF_SM_ENTER_EVT:
684
685             /* we are again in started state, clear any remote suspend flags */
686             btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
687
688             btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
689
690             /* increase the a2dp consumer task priority temporarily when start
691             ** audio playing, to avoid overflow the audio packet queue. */
692             adjust_priority_a2dp(TRUE);
693
694             break;
695
696         case BTIF_SM_EXIT_EVT:
697             /* restore the a2dp consumer task priority when stop audio playing. */
698             adjust_priority_a2dp(FALSE);
699
700             break;
701
702         case BTIF_AV_START_STREAM_REQ_EVT:
703             /* we were remotely started, just ack back the local request */
704             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
705                 btif_a2dp_on_started(NULL, TRUE);
706             break;
707
708         /* fixme -- use suspend = true always to work around issue with BTA AV */
709         case BTIF_AV_STOP_STREAM_REQ_EVT:
710         case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
711
712             /* set pending flag to ensure btif task is not trying to restart
713                stream while suspend is in progress */
714             btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
715
716             /* if we were remotely suspended but suspend locally, local suspend
717                always overrides */
718             btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
719
720             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
721             {
722             /* immediately stop transmission of frames while suspend is pending */
723                 btif_a2dp_set_tx_flush(TRUE);
724             }
725
726             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
727                 btif_a2dp_set_rx_flush(TRUE);
728                 btif_a2dp_on_stopped(NULL);
729             }
730
731             BTA_AvStop(TRUE);
732             break;
733
734         case BTIF_AV_DISCONNECT_REQ_EVT:
735
736             /* request avdtp to close */
737             BTA_AvClose(btif_av_cb.bta_handle);
738             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
739                 BTA_AvCloseRc(btif_av_cb.bta_handle);
740             }
741
742             /* inform the application that we are disconnecting */
743             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
744
745             /* wait in closing state until fully closed */
746             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
747             break;
748
749         case BTA_AV_SUSPEND_EVT:
750
751             BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
752                  p_av->suspend.status, p_av->suspend.initiator);
753
754             /* a2dp suspended, stop media task until resumed */
755             btif_a2dp_on_suspended(&p_av->suspend);
756
757             /* if not successful, remain in current state */
758             if (p_av->suspend.status != BTA_AV_SUCCESS)
759             {
760                 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
761
762                if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
763                {
764                 /* suspend failed, reset back tx flush state */
765                     btif_a2dp_set_tx_flush(FALSE);
766                }
767                 return FALSE;
768             }
769
770             if (p_av->suspend.initiator != TRUE)
771             {
772                 /* remote suspend, notify HAL and await audioflinger to
773                    suspend/stop stream */
774
775                 /* set remote suspend flag to block media task from restarting
776                    stream only if we did not already initiate a local suspend */
777                 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
778                     btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
779
780                 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
781             }
782             else
783             {
784                 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
785             }
786
787             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
788
789             /* suspend completed and state changed, clear pending status */
790             btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
791             break;
792
793         case BTA_AV_STOP_EVT:
794
795             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
796             btif_a2dp_on_stopped(&p_av->suspend);
797
798             btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
799
800             /* if stop was successful, change state to open */
801             if (p_av->suspend.status == BTA_AV_SUCCESS)
802                 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
803
804             break;
805
806         case BTA_AV_CLOSE_EVT:
807
808              btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
809
810             /* avdtp link is closed */
811             btif_a2dp_on_stopped(NULL);
812
813             /* inform the application that we are disconnected */
814             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
815
816             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
817             break;
818
819         CHECK_RC_EVENT(event, p_data);
820
821         default:
822             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
823                                  dump_av_sm_event_name(event));
824             return FALSE;
825
826     }
827     return TRUE;
828 }
829
830 /*****************************************************************************
831 **  Local event handlers
832 ******************************************************************************/
833
834 static void btif_av_handle_event(UINT16 event, char* p_param)
835 {
836     btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
837 }
838
839 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
840 {
841     /* Switch to BTIF context */
842     btif_transfer_context(btif_av_handle_event, event,
843                           (char*)p_data, sizeof(tBTA_AV), NULL);
844 }
845
846 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
847 {
848     btif_sm_state_t state;
849     UINT8 que_len;
850     tA2D_STATUS a2d_status;
851     tA2D_SBC_CIE sbc_cie;
852     btif_av_sink_config_req_t config_req;
853
854     if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
855     {
856         state= btif_sm_get_state(btif_av_cb.sm_handle);
857         if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
858              (state == BTIF_AV_STATE_OPENED) )
859         {
860             que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
861             BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
862         }
863         else
864             return;
865     }
866
867     if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
868         /* send a command to BT Media Task */
869         btif_reset_decoder((UINT8*)p_data);
870
871         a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
872         if (a2d_status == A2D_SUCCESS) {
873             /* Switch to BTIF context */
874             config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
875             config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
876             btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
877                                      (char*)&config_req, sizeof(config_req), NULL);
878         } else {
879             APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
880         }
881     }
882 }
883 /*******************************************************************************
884 **
885 ** Function         btif_av_init
886 **
887 ** Description      Initializes btif AV if not already done
888 **
889 ** Returns          bt_status_t
890 **
891 *******************************************************************************/
892
893 bt_status_t btif_av_init()
894 {
895     btif_av_cb.sm_handle = NULL;
896
897     if (btif_av_cb.sm_handle == NULL)
898     {
899         if (btif_a2dp_start_media_task() != GKI_SUCCESS)
900             return BT_STATUS_FAIL;
901
902         btif_enable_service(BTA_A2DP_SERVICE_ID);
903
904         /* Also initialize the AV state machine */
905         btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
906
907         btif_a2dp_on_init();
908
909        return BT_STATUS_SUCCESS;
910     }
911
912     return BT_STATUS_DONE;
913 }
914
915 /*******************************************************************************
916 **
917 ** Function         init_src
918 **
919 ** Description      Initializes the AV interface for source mode
920 **
921 ** Returns          bt_status_t
922 **
923 *******************************************************************************/
924
925 static bt_status_t init_src(btav_callbacks_t* callbacks)
926 {
927     bt_status_t status;
928
929     BTIF_TRACE_EVENT("%s", __FUNCTION__);
930
931     if (bt_av_sink_callbacks != NULL) {
932         // already did btif_av_init()
933         status = BT_STATUS_SUCCESS;
934     } else {
935         status = btif_av_init();
936     }
937
938     if (status == BT_STATUS_SUCCESS) {
939         bt_av_src_callbacks = callbacks;
940     }
941
942     return status;
943 }
944
945 /*******************************************************************************
946 **
947 ** Function         init_sink
948 **
949 ** Description      Initializes the AV interface for sink mode
950 **
951 ** Returns          bt_status_t
952 **
953 *******************************************************************************/
954
955 static bt_status_t init_sink(btav_callbacks_t* callbacks)
956 {
957     bt_status_t status;
958
959     BTIF_TRACE_EVENT("%s", __FUNCTION__);
960
961     if (bt_av_src_callbacks != NULL) {
962         // already did btif_av_init()
963         status = BT_STATUS_SUCCESS;
964     } else {
965         status = btif_av_init();
966     }
967
968     if (status == BT_STATUS_SUCCESS) {
969         bt_av_sink_callbacks = callbacks;
970         BTA_AvEnable_Sink(TRUE);
971     }
972
973     return status;
974 }
975
976 /*******************************************************************************
977 **
978 ** Function         connect
979 **
980 ** Description      Establishes the AV signalling channel with the remote headset
981 **
982 ** Returns          bt_status_t
983 **
984 *******************************************************************************/
985
986 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
987 {
988     btif_av_connect_req_t connect_req;
989     connect_req.target_bda = bd_addr;
990     connect_req.uuid = uuid;
991     BTIF_TRACE_EVENT("%s", __FUNCTION__);
992
993     btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
994
995     return BT_STATUS_SUCCESS;
996 }
997
998 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
999 {
1000     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1001     CHECK_BTAV_INIT();
1002
1003     return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1004 }
1005
1006 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1007 {
1008     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1009     CHECK_BTAV_INIT();
1010
1011     return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1012 }
1013
1014 /*******************************************************************************
1015 **
1016 ** Function         disconnect
1017 **
1018 ** Description      Tears down the AV signalling channel with the remote headset
1019 **
1020 ** Returns          bt_status_t
1021 **
1022 *******************************************************************************/
1023 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1024 {
1025     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1026
1027     CHECK_BTAV_INIT();
1028
1029     /* Switch to BTIF context */
1030     return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1031                                  (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1032 }
1033
1034 /*******************************************************************************
1035 **
1036 ** Function         cleanup
1037 **
1038 ** Description      Shuts down the AV interface and does the cleanup
1039 **
1040 ** Returns          None
1041 **
1042 *******************************************************************************/
1043 static void cleanup(void)
1044 {
1045     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1046
1047     btif_a2dp_stop_media_task();
1048
1049     btif_disable_service(BTA_A2DP_SERVICE_ID);
1050
1051     /* Also shut down the AV state machine */
1052     btif_sm_shutdown(btif_av_cb.sm_handle);
1053     btif_av_cb.sm_handle = NULL;
1054 }
1055
1056 static void cleanup_src(void) {
1057     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1058
1059     if (bt_av_src_callbacks)
1060     {
1061         bt_av_src_callbacks = NULL;
1062         if (bt_av_sink_callbacks == NULL)
1063             cleanup();
1064     }
1065 }
1066
1067 static void cleanup_sink(void) {
1068     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1069
1070     if (bt_av_sink_callbacks)
1071     {
1072         bt_av_sink_callbacks = NULL;
1073         if (bt_av_src_callbacks == NULL)
1074             cleanup();
1075     }
1076 }
1077
1078 static const btav_interface_t bt_av_src_interface = {
1079     sizeof(btav_interface_t),
1080     init_src,
1081     src_connect_sink,
1082     disconnect,
1083     cleanup_src,
1084 };
1085
1086 static const btav_interface_t bt_av_sink_interface = {
1087     sizeof(btav_interface_t),
1088     init_sink,
1089     sink_connect_src,
1090     disconnect,
1091     cleanup_sink,
1092 };
1093
1094 /*******************************************************************************
1095 **
1096 ** Function         btif_av_get_sm_handle
1097 **
1098 ** Description      Fetches current av SM handle
1099 **
1100 ** Returns          None
1101 **
1102 *******************************************************************************/
1103
1104 btif_sm_handle_t btif_av_get_sm_handle(void)
1105 {
1106     return btif_av_cb.sm_handle;
1107 }
1108
1109 /*******************************************************************************
1110 **
1111 ** Function         btif_av_stream_ready
1112 **
1113 ** Description      Checks whether AV is ready for starting a stream
1114 **
1115 ** Returns          None
1116 **
1117 *******************************************************************************/
1118
1119 BOOLEAN btif_av_stream_ready(void)
1120 {
1121     btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1122
1123     BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1124                 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1125
1126     /* also make sure main adapter is enabled */
1127     if (btif_is_enabled() == 0)
1128     {
1129         BTIF_TRACE_EVENT("main adapter not enabled");
1130         return FALSE;
1131     }
1132
1133     /* check if we are remotely suspended or stop is pending */
1134     if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1135         return FALSE;
1136
1137     return (state == BTIF_AV_STATE_OPENED);
1138 }
1139
1140 /*******************************************************************************
1141 **
1142 ** Function         btif_av_stream_started_ready
1143 **
1144 ** Description      Checks whether AV ready for media start in streaming state
1145 **
1146 ** Returns          None
1147 **
1148 *******************************************************************************/
1149
1150 BOOLEAN btif_av_stream_started_ready(void)
1151 {
1152     btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1153
1154     BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1155                 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1156
1157     /* disallow media task to start if we have pending actions */
1158     if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1159         | BTIF_AV_FLAG_PENDING_STOP))
1160         return FALSE;
1161
1162     return (state == BTIF_AV_STATE_STARTED);
1163 }
1164
1165 /*******************************************************************************
1166 **
1167 ** Function         btif_dispatch_sm_event
1168 **
1169 ** Description      Send event to AV statemachine
1170 **
1171 ** Returns          None
1172 **
1173 *******************************************************************************/
1174
1175 /* used to pass events to AV statemachine from other tasks */
1176 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1177 {
1178     /* Switch to BTIF context */
1179     btif_transfer_context(btif_av_handle_event, event,
1180                           (char*)p_data, len, NULL);
1181 }
1182
1183 /*******************************************************************************
1184 **
1185 ** Function         btif_av_execute_service
1186 **
1187 ** Description      Initializes/Shuts down the service
1188 **
1189 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1190 **
1191 *******************************************************************************/
1192 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1193 {
1194      if (b_enable)
1195      {
1196          /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1197           * handle this request in order to allow incoming connections to succeed.
1198           * We need to put this back once support for this is added */
1199
1200          /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1201           * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1202           * be initiated by the app/audioflinger layers */
1203 #if (AVRC_METADATA_INCLUDED == TRUE)
1204          BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1205              BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1206 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1207              |BTA_AV_FEAT_RCCT
1208              |BTA_AV_FEAT_ADV_CTRL
1209 #endif
1210              ,bte_av_callback);
1211 #else
1212          BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1213                       bte_av_callback);
1214 #endif
1215          BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1216      }
1217      else {
1218          BTA_AvDeregister(btif_av_cb.bta_handle);
1219          BTA_AvDisable();
1220      }
1221      return BT_STATUS_SUCCESS;
1222 }
1223
1224 /*******************************************************************************
1225 **
1226 ** Function         btif_av_get_src_interface
1227 **
1228 ** Description      Get the AV callback interface for A2DP source profile
1229 **
1230 ** Returns          btav_interface_t
1231 **
1232 *******************************************************************************/
1233 const btav_interface_t *btif_av_get_src_interface(void)
1234 {
1235     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1236     return &bt_av_src_interface;
1237 }
1238
1239 /*******************************************************************************
1240 **
1241 ** Function         btif_av_get_sink_interface
1242 **
1243 ** Description      Get the AV callback interface for A2DP sink profile
1244 **
1245 ** Returns          btav_interface_t
1246 **
1247 *******************************************************************************/
1248 const btav_interface_t *btif_av_get_sink_interface(void)
1249 {
1250     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1251     return &bt_av_sink_interface;
1252 }
1253
1254 /*******************************************************************************
1255 **
1256 ** Function         btif_av_is_connected
1257 **
1258 ** Description      Checks if av has a connected sink
1259 **
1260 ** Returns          BOOLEAN
1261 **
1262 *******************************************************************************/
1263 BOOLEAN btif_av_is_connected(void)
1264 {
1265     btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1266     return ((state == BTIF_AV_STATE_OPENED) || (state ==  BTIF_AV_STATE_STARTED));
1267 }
1268
1269 /*******************************************************************************
1270 **
1271 ** Function         btif_av_is_peer_edr
1272 **
1273 ** Description      Check if the connected a2dp device supports
1274 **                  EDR or not. Only when connected this function
1275 **                  will accurately provide a true capability of
1276 **                  remote peer. If not connected it will always be false.
1277 **
1278 ** Returns          TRUE if remote device is capable of EDR
1279 **
1280 *******************************************************************************/
1281 BOOLEAN btif_av_is_peer_edr(void)
1282 {
1283     ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1284
1285     if (btif_av_cb.edr)
1286         return TRUE;
1287     else
1288         return FALSE;
1289 }
1290