OSDN Git Service

am f29a2fb..e07ad10 from mirror-m-wireless-internal-release
[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 "bt_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 "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     case BTA_AV_REMOTE_RSP_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         case BTA_AV_REMOTE_RSP_EVT:
338             btif_rc_handler(event, (tBTA_AV*)p_data);
339             break;
340
341         case BTA_AV_RC_CLOSE_EVT:
342             if (tle_av_open_on_rc.in_use) {
343                 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
344                 btu_stop_timer(&tle_av_open_on_rc);
345             }
346             btif_rc_handler(event, p_data);
347             break;
348
349         default:
350             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
351                                 dump_av_sm_event_name(event));
352             return FALSE;
353
354     }
355     return TRUE;
356 }
357 /*****************************************************************************
358 **
359 ** Function        btif_av_state_opening_handler
360 **
361 ** Description     Intermediate state managing events during establishment
362 **                 of avdtp channel
363 **
364 ** Returns         TRUE if event was processed, FALSE otherwise
365 **
366 *******************************************************************************/
367
368 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
369 {
370     BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
371                      dump_av_sm_event_name(event), btif_av_cb.flags);
372
373     switch (event)
374     {
375         case BTIF_SM_ENTER_EVT:
376             /* inform the application that we are entering connecting state */
377             btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
378             break;
379
380         case BTIF_SM_EXIT_EVT:
381             break;
382
383         case BTA_AV_REJECT_EVT:
384             BTIF_TRACE_DEBUG(" Received  BTA_AV_REJECT_EVT ");
385             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
386             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
387             break;
388
389         case BTA_AV_OPEN_EVT:
390         {
391             tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
392             btav_connection_state_t state;
393             btif_sm_state_t av_state;
394             BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
395                                p_bta_data->open.edr);
396
397             if (p_bta_data->open.status == BTA_AV_SUCCESS)
398             {
399                  state = BTAV_CONNECTION_STATE_CONNECTED;
400                  av_state = BTIF_AV_STATE_OPENED;
401                  btif_av_cb.edr = p_bta_data->open.edr;
402
403                  btif_av_cb.peer_sep = p_bta_data->open.sep;
404                  btif_a2dp_set_peer_sep(p_bta_data->open.sep);
405             }
406             else
407             {
408                 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
409                                      p_bta_data->open.status );
410                 state = BTAV_CONNECTION_STATE_DISCONNECTED;
411                 av_state  = BTIF_AV_STATE_IDLE;
412             }
413
414             /* inform the application of the event */
415             btif_report_connection_state(state, &(btif_av_cb.peer_bda));
416             /* change state to open/idle based on the status */
417             btif_sm_change_state(btif_av_cb.sm_handle, av_state);
418             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
419             {
420                 /* if queued PLAY command,  send it now */
421                 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
422                                              (p_bta_data->open.status == BTA_AV_SUCCESS));
423             }
424             else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
425             {
426                 /* if queued PLAY command,  send it now */
427                 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
428                 /* Bring up AVRCP connection too */
429                 BTA_AvOpenRc(btif_av_cb.bta_handle);
430             }
431             btif_queue_advance();
432         } break;
433
434         case BTIF_AV_SINK_CONFIG_REQ_EVT:
435         {
436             btif_av_sink_config_req_t req;
437             // copy to avoid alignment problems
438             memcpy(&req, p_data, sizeof(req));
439
440             BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
441                     req.channel_count);
442             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
443                 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
444                         req.sample_rate, req.channel_count);
445             }
446         } break;
447
448         CHECK_RC_EVENT(event, p_data);
449
450         default:
451             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
452                                 dump_av_sm_event_name(event));
453             return FALSE;
454
455    }
456    return TRUE;
457 }
458
459
460 /*****************************************************************************
461 **
462 ** Function        btif_av_state_closing_handler
463 **
464 ** Description     Intermediate state managing events during closing
465 **                 of avdtp channel
466 **
467 ** Returns         TRUE if event was processed, FALSE otherwise
468 **
469 *******************************************************************************/
470
471 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
472 {
473     BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
474                      dump_av_sm_event_name(event), btif_av_cb.flags);
475
476     switch (event)
477     {
478         case BTIF_SM_ENTER_EVT:
479             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
480             {
481                 /* immediately stop transmission of frames */
482                 btif_a2dp_set_tx_flush(TRUE);
483                 /* wait for audioflinger to stop a2dp */
484             }
485             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
486             {
487                 btif_a2dp_set_rx_flush(TRUE);
488             }
489             break;
490
491         case BTA_AV_STOP_EVT:
492         case BTIF_AV_STOP_STREAM_REQ_EVT:
493             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
494             {
495               /* immediately flush any pending tx frames while suspend is pending */
496               btif_a2dp_set_tx_flush(TRUE);
497             }
498             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
499             {
500                 btif_a2dp_set_rx_flush(TRUE);
501             }
502
503             btif_a2dp_on_stopped(NULL);
504             break;
505
506         case BTIF_SM_EXIT_EVT:
507             break;
508
509         case BTA_AV_CLOSE_EVT:
510
511             /* inform the application that we are disconnecting */
512             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
513
514             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
515             break;
516
517         /* Handle the RC_CLOSE event for the cleanup */
518         case BTA_AV_RC_CLOSE_EVT:
519             btif_rc_handler(event, (tBTA_AV*)p_data);
520             break;
521
522         default:
523             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
524                                 dump_av_sm_event_name(event));
525             return FALSE;
526    }
527    return TRUE;
528 }
529
530
531 /*****************************************************************************
532 **
533 ** Function     btif_av_state_opened_handler
534 **
535 ** Description  Handles AV events while AVDTP is in OPEN state
536 **
537 ** Returns      TRUE if event was processed, FALSE otherwise
538 **
539 *******************************************************************************/
540
541 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
542 {
543     tBTA_AV *p_av = (tBTA_AV*)p_data;
544
545     BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
546                      dump_av_sm_event_name(event), btif_av_cb.flags);
547
548     if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
549          (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
550     {
551         BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
552         btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
553     }
554
555     switch (event)
556     {
557         case BTIF_SM_ENTER_EVT:
558             btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
559             btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
560             break;
561
562         case BTIF_SM_EXIT_EVT:
563             btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
564             break;
565
566         case BTIF_AV_START_STREAM_REQ_EVT:
567             if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
568                 btif_a2dp_setup_codec();
569             BTA_AvStart();
570             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
571             break;
572
573         case BTA_AV_START_EVT:
574         {
575             BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
576                 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
577
578             if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
579                 return TRUE;
580
581             /*  In case peer is A2DP SRC we do not want to ack commands on UIPC*/
582             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
583             {
584                 if (btif_a2dp_on_started(&p_av->start,
585                     ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
586                 {
587                     /* only clear pending flag after acknowledgement */
588                     btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
589                 }
590             }
591
592             /* remain in open state if status failed */
593             if (p_av->start.status != BTA_AV_SUCCESS)
594                 return FALSE;
595
596             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
597             {
598                 btif_a2dp_set_rx_flush(FALSE); /*  remove flush state, ready for streaming*/
599             }
600
601             /* change state to started, send acknowledgement if start is pending */
602             if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
603                 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
604                     btif_a2dp_on_started(NULL, TRUE);
605                 /* pending start flag will be cleared when exit current state */
606             }
607             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
608
609         } break;
610
611         case BTIF_AV_DISCONNECT_REQ_EVT:
612             BTA_AvClose(btif_av_cb.bta_handle);
613             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
614                 BTA_AvCloseRc(btif_av_cb.bta_handle);
615             }
616
617             /* inform the application that we are disconnecting */
618             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
619             break;
620
621         case BTA_AV_CLOSE_EVT:
622              /* avdtp link is closed */
623             btif_a2dp_on_stopped(NULL);
624
625             /* inform the application that we are disconnected */
626             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
627
628             /* change state to idle, send acknowledgement if start is pending */
629             if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
630                 btif_a2dp_ack_fail();
631                 /* pending start flag will be cleared when exit current state */
632             }
633             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
634             break;
635
636         case BTA_AV_RECONFIG_EVT:
637             if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
638                 (p_av->reconfig.status == BTA_AV_SUCCESS))
639             {
640                APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
641                BTA_AvStart();
642             }
643             else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
644             {
645                btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
646                btif_a2dp_ack_fail();
647             }
648             break;
649
650         CHECK_RC_EVENT(event, p_data);
651
652         default:
653             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
654                                dump_av_sm_event_name(event));
655             return FALSE;
656
657     }
658     return TRUE;
659 }
660
661 /*****************************************************************************
662 **
663 ** Function     btif_av_state_started_handler
664 **
665 ** Description  Handles AV events while A2DP stream is started
666 **
667 ** Returns      TRUE if event was processed, FALSE otherwise
668 **
669 *******************************************************************************/
670
671 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
672 {
673     tBTA_AV *p_av = (tBTA_AV*)p_data;
674
675     BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
676                      dump_av_sm_event_name(event), btif_av_cb.flags);
677
678     switch (event)
679     {
680         case BTIF_SM_ENTER_EVT:
681
682             /* we are again in started state, clear any remote suspend flags */
683             btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
684
685             btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
686
687             /* increase the a2dp consumer task priority temporarily when start
688             ** audio playing, to avoid overflow the audio packet queue. */
689             adjust_priority_a2dp(TRUE);
690
691             break;
692
693         case BTIF_SM_EXIT_EVT:
694             /* restore the a2dp consumer task priority when stop audio playing. */
695             adjust_priority_a2dp(FALSE);
696
697             break;
698
699         case BTIF_AV_START_STREAM_REQ_EVT:
700             /* we were remotely started, just ack back the local request */
701             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
702                 btif_a2dp_on_started(NULL, TRUE);
703             break;
704
705         /* fixme -- use suspend = true always to work around issue with BTA AV */
706         case BTIF_AV_STOP_STREAM_REQ_EVT:
707         case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
708
709             /* set pending flag to ensure btif task is not trying to restart
710                stream while suspend is in progress */
711             btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
712
713             /* if we were remotely suspended but suspend locally, local suspend
714                always overrides */
715             btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
716
717             if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
718             {
719             /* immediately stop transmission of frames while suspend is pending */
720                 btif_a2dp_set_tx_flush(TRUE);
721             }
722
723             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
724                 btif_a2dp_set_rx_flush(TRUE);
725                 btif_a2dp_on_stopped(NULL);
726             }
727
728             BTA_AvStop(TRUE);
729             break;
730
731         case BTIF_AV_DISCONNECT_REQ_EVT:
732
733             /* request avdtp to close */
734             BTA_AvClose(btif_av_cb.bta_handle);
735             if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
736                 BTA_AvCloseRc(btif_av_cb.bta_handle);
737             }
738
739             /* inform the application that we are disconnecting */
740             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
741
742             /* wait in closing state until fully closed */
743             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
744             break;
745
746         case BTA_AV_SUSPEND_EVT:
747
748             BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
749                  p_av->suspend.status, p_av->suspend.initiator);
750
751             /* a2dp suspended, stop media task until resumed */
752             btif_a2dp_on_suspended(&p_av->suspend);
753
754             /* if not successful, remain in current state */
755             if (p_av->suspend.status != BTA_AV_SUCCESS)
756             {
757                 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
758
759                if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
760                {
761                 /* suspend failed, reset back tx flush state */
762                     btif_a2dp_set_tx_flush(FALSE);
763                }
764                 return FALSE;
765             }
766
767             if (p_av->suspend.initiator != TRUE)
768             {
769                 /* remote suspend, notify HAL and await audioflinger to
770                    suspend/stop stream */
771
772                 /* set remote suspend flag to block media task from restarting
773                    stream only if we did not already initiate a local suspend */
774                 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
775                     btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
776
777                 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
778             }
779             else
780             {
781                 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
782             }
783
784             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
785
786             /* suspend completed and state changed, clear pending status */
787             btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
788             break;
789
790         case BTA_AV_STOP_EVT:
791
792             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
793             btif_a2dp_on_stopped(&p_av->suspend);
794
795             btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
796
797             /* if stop was successful, change state to open */
798             if (p_av->suspend.status == BTA_AV_SUCCESS)
799                 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
800
801             break;
802
803         case BTA_AV_CLOSE_EVT:
804
805              btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
806
807             /* avdtp link is closed */
808             btif_a2dp_on_stopped(NULL);
809
810             /* inform the application that we are disconnected */
811             btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
812
813             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
814             break;
815
816         CHECK_RC_EVENT(event, p_data);
817
818         default:
819             BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
820                                  dump_av_sm_event_name(event));
821             return FALSE;
822
823     }
824     return TRUE;
825 }
826
827 /*****************************************************************************
828 **  Local event handlers
829 ******************************************************************************/
830
831 static void btif_av_handle_event(UINT16 event, char* p_param)
832 {
833     btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
834 }
835
836 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
837 {
838     /* Switch to BTIF context */
839     btif_transfer_context(btif_av_handle_event, event,
840                           (char*)p_data, sizeof(tBTA_AV), NULL);
841 }
842
843 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
844 {
845     btif_sm_state_t state;
846     UINT8 que_len;
847     tA2D_STATUS a2d_status;
848     tA2D_SBC_CIE sbc_cie;
849     btif_av_sink_config_req_t config_req;
850
851     if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
852     {
853         state= btif_sm_get_state(btif_av_cb.sm_handle);
854         if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
855              (state == BTIF_AV_STATE_OPENED) )
856         {
857             que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
858             BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
859         }
860         else
861             return;
862     }
863
864     if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
865         /* send a command to BT Media Task */
866         btif_reset_decoder((UINT8*)p_data);
867
868         a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
869         if (a2d_status == A2D_SUCCESS) {
870             /* Switch to BTIF context */
871             config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
872             config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
873             btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
874                                      (char*)&config_req, sizeof(config_req), NULL);
875         } else {
876             APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
877         }
878     }
879 }
880 /*******************************************************************************
881 **
882 ** Function         btif_av_init
883 **
884 ** Description      Initializes btif AV if not already done
885 **
886 ** Returns          bt_status_t
887 **
888 *******************************************************************************/
889
890 bt_status_t btif_av_init()
891 {
892     if (btif_av_cb.sm_handle == NULL)
893     {
894         if (!btif_a2dp_start_media_task())
895             return BT_STATUS_FAIL;
896
897         btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
898 #if (BTA_AV_SINK_INCLUDED == TRUE)
899         btif_enable_service(BTA_A2DP_SINK_SERVICE_ID);
900 #endif
901
902         /* Also initialize the AV state machine */
903         btif_av_cb.sm_handle =
904                 btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
905
906         btif_a2dp_on_init();
907
908        return BT_STATUS_SUCCESS;
909     }
910
911     return BT_STATUS_DONE;
912 }
913
914 /*******************************************************************************
915 **
916 ** Function         init_src
917 **
918 ** Description      Initializes the AV interface for source mode
919 **
920 ** Returns          bt_status_t
921 **
922 *******************************************************************************/
923
924 static bt_status_t init_src(btav_callbacks_t* callbacks)
925 {
926     bt_status_t status;
927
928     BTIF_TRACE_EVENT("%s", __FUNCTION__);
929
930     if (bt_av_sink_callbacks != NULL) {
931         // already did btif_av_init()
932         status = BT_STATUS_SUCCESS;
933     } else {
934         status = btif_av_init();
935     }
936
937     if (status == BT_STATUS_SUCCESS) {
938         bt_av_src_callbacks = callbacks;
939     }
940
941     return status;
942 }
943
944 /*******************************************************************************
945 **
946 ** Function         init_sink
947 **
948 ** Description      Initializes the AV interface for sink mode
949 **
950 ** Returns          bt_status_t
951 **
952 *******************************************************************************/
953
954 static bt_status_t init_sink(btav_callbacks_t* callbacks)
955 {
956     bt_status_t status;
957
958     BTIF_TRACE_EVENT("%s", __FUNCTION__);
959
960     if (bt_av_src_callbacks != NULL) {
961         // already did btif_av_init()
962         status = BT_STATUS_SUCCESS;
963     } else {
964         status = btif_av_init();
965     }
966
967     if (status == BT_STATUS_SUCCESS) {
968         bt_av_sink_callbacks = callbacks;
969     }
970
971     return status;
972 }
973
974 /*******************************************************************************
975 **
976 ** Function         connect
977 **
978 ** Description      Establishes the AV signalling channel with the remote headset
979 **
980 ** Returns          bt_status_t
981 **
982 *******************************************************************************/
983
984 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
985 {
986     btif_av_connect_req_t connect_req;
987     connect_req.target_bda = bd_addr;
988     connect_req.uuid = uuid;
989     BTIF_TRACE_EVENT("%s", __FUNCTION__);
990
991     btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
992
993     return BT_STATUS_SUCCESS;
994 }
995
996 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
997 {
998     BTIF_TRACE_EVENT("%s", __FUNCTION__);
999     CHECK_BTAV_INIT();
1000
1001     return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1002 }
1003
1004 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1005 {
1006     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1007     CHECK_BTAV_INIT();
1008
1009     return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1010 }
1011
1012 /*******************************************************************************
1013 **
1014 ** Function         disconnect
1015 **
1016 ** Description      Tears down the AV signalling channel with the remote headset
1017 **
1018 ** Returns          bt_status_t
1019 **
1020 *******************************************************************************/
1021 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1022 {
1023     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1024
1025     CHECK_BTAV_INIT();
1026
1027     /* Switch to BTIF context */
1028     return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1029                                  (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1030 }
1031
1032 /*******************************************************************************
1033 **
1034 ** Function         cleanup
1035 **
1036 ** Description      Shuts down the AV interface and does the cleanup
1037 **
1038 ** Returns          None
1039 **
1040 *******************************************************************************/
1041 static void cleanup(void)
1042 {
1043     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1044
1045     btif_a2dp_stop_media_task();
1046
1047     btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
1048 #if (BTA_AV_SINK_INCLUDED == TRUE)
1049     btif_disable_service(BTA_A2DP_SINK_SERVICE_ID);
1050 #endif
1051
1052     /* Also shut down the AV state machine */
1053     btif_sm_shutdown(btif_av_cb.sm_handle);
1054     btif_av_cb.sm_handle = NULL;
1055 }
1056
1057 static void cleanup_src(void) {
1058     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1059
1060     if (bt_av_src_callbacks)
1061     {
1062         bt_av_src_callbacks = NULL;
1063         if (bt_av_sink_callbacks == NULL)
1064             cleanup();
1065     }
1066 }
1067
1068 static void cleanup_sink(void) {
1069     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1070
1071     if (bt_av_sink_callbacks)
1072     {
1073         bt_av_sink_callbacks = NULL;
1074         if (bt_av_src_callbacks == NULL)
1075             cleanup();
1076     }
1077 }
1078
1079 static const btav_interface_t bt_av_src_interface = {
1080     sizeof(btav_interface_t),
1081     init_src,
1082     src_connect_sink,
1083     disconnect,
1084     cleanup_src,
1085 };
1086
1087 static const btav_interface_t bt_av_sink_interface = {
1088     sizeof(btav_interface_t),
1089     init_sink,
1090     sink_connect_src,
1091     disconnect,
1092     cleanup_sink,
1093 };
1094
1095 /*******************************************************************************
1096 **
1097 ** Function         btif_av_get_sm_handle
1098 **
1099 ** Description      Fetches current av SM handle
1100 **
1101 ** Returns          None
1102 **
1103 *******************************************************************************/
1104
1105 btif_sm_handle_t btif_av_get_sm_handle(void)
1106 {
1107     return btif_av_cb.sm_handle;
1108 }
1109
1110 /*******************************************************************************
1111 **
1112 ** Function         btif_av_stream_ready
1113 **
1114 ** Description      Checks whether AV is ready for starting a stream
1115 **
1116 ** Returns          None
1117 **
1118 *******************************************************************************/
1119
1120 BOOLEAN btif_av_stream_ready(void)
1121 {
1122     btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1123
1124     BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1125                 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1126
1127     /* also make sure main adapter is enabled */
1128     if (btif_is_enabled() == 0)
1129     {
1130         BTIF_TRACE_EVENT("main adapter not enabled");
1131         return FALSE;
1132     }
1133
1134     /* check if we are remotely suspended or stop is pending */
1135     if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1136         return FALSE;
1137
1138     return (state == BTIF_AV_STATE_OPENED);
1139 }
1140
1141 /*******************************************************************************
1142 **
1143 ** Function         btif_av_stream_started_ready
1144 **
1145 ** Description      Checks whether AV ready for media start in streaming state
1146 **
1147 ** Returns          None
1148 **
1149 *******************************************************************************/
1150
1151 BOOLEAN btif_av_stream_started_ready(void)
1152 {
1153     btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1154
1155     BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1156                 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1157
1158     /* disallow media task to start if we have pending actions */
1159     if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1160         | BTIF_AV_FLAG_PENDING_STOP))
1161         return FALSE;
1162
1163     return (state == BTIF_AV_STATE_STARTED);
1164 }
1165
1166 /*******************************************************************************
1167 **
1168 ** Function         btif_dispatch_sm_event
1169 **
1170 ** Description      Send event to AV statemachine
1171 **
1172 ** Returns          None
1173 **
1174 *******************************************************************************/
1175
1176 /* used to pass events to AV statemachine from other tasks */
1177 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1178 {
1179     /* Switch to BTIF context */
1180     btif_transfer_context(btif_av_handle_event, event,
1181                           (char*)p_data, len, NULL);
1182 }
1183
1184 /*******************************************************************************
1185 **
1186 ** Function         btif_av_execute_service
1187 **
1188 ** Description      Initializes/Shuts down the service
1189 **
1190 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1191 **
1192 *******************************************************************************/
1193 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1194 {
1195      if (b_enable)
1196      {
1197          /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1198           * handle this request in order to allow incoming connections to succeed.
1199           * We need to put this back once support for this is added */
1200
1201          /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1202           * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1203           * be initiated by the app/audioflinger layers */
1204 #if (AVRC_METADATA_INCLUDED == TRUE)
1205          BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1206              BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1207 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1208              |BTA_AV_FEAT_RCCT
1209              |BTA_AV_FEAT_ADV_CTRL
1210 #endif
1211              ,bte_av_callback);
1212 #else
1213          BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1214                       bte_av_callback);
1215 #endif
1216          BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1217      }
1218      else {
1219          BTA_AvDeregister(btif_av_cb.bta_handle);
1220          BTA_AvDisable();
1221      }
1222      return BT_STATUS_SUCCESS;
1223 }
1224
1225 /*******************************************************************************
1226 **
1227 ** Function         btif_av_sink_execute_service
1228 **
1229 ** Description      Initializes/Shuts down the service
1230 **
1231 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1232 **
1233 *******************************************************************************/
1234 bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
1235 {
1236 #if (BTA_AV_SINK_INCLUDED == TRUE)
1237     BTA_AvEnable_Sink(b_enable);
1238 #endif
1239     return BT_STATUS_SUCCESS;
1240 }
1241
1242 /*******************************************************************************
1243 **
1244 ** Function         btif_av_get_src_interface
1245 **
1246 ** Description      Get the AV callback interface for A2DP source profile
1247 **
1248 ** Returns          btav_interface_t
1249 **
1250 *******************************************************************************/
1251 const btav_interface_t *btif_av_get_src_interface(void)
1252 {
1253     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1254     return &bt_av_src_interface;
1255 }
1256
1257 /*******************************************************************************
1258 **
1259 ** Function         btif_av_get_sink_interface
1260 **
1261 ** Description      Get the AV callback interface for A2DP sink profile
1262 **
1263 ** Returns          btav_interface_t
1264 **
1265 *******************************************************************************/
1266 const btav_interface_t *btif_av_get_sink_interface(void)
1267 {
1268     BTIF_TRACE_EVENT("%s", __FUNCTION__);
1269     return &bt_av_sink_interface;
1270 }
1271
1272 /*******************************************************************************
1273 **
1274 ** Function         btif_av_is_connected
1275 **
1276 ** Description      Checks if av has a connected sink
1277 **
1278 ** Returns          BOOLEAN
1279 **
1280 *******************************************************************************/
1281 BOOLEAN btif_av_is_connected(void)
1282 {
1283     btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1284     return ((state == BTIF_AV_STATE_OPENED) || (state ==  BTIF_AV_STATE_STARTED));
1285 }
1286
1287 /*******************************************************************************
1288 **
1289 ** Function         btif_av_is_peer_edr
1290 **
1291 ** Description      Check if the connected a2dp device supports
1292 **                  EDR or not. Only when connected this function
1293 **                  will accurately provide a true capability of
1294 **                  remote peer. If not connected it will always be false.
1295 **
1296 ** Returns          TRUE if remote device is capable of EDR
1297 **
1298 *******************************************************************************/
1299 BOOLEAN btif_av_is_peer_edr(void)
1300 {
1301     ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1302
1303     if (btif_av_cb.edr)
1304         return TRUE;
1305     else
1306         return FALSE;
1307 }
1308