OSDN Git Service

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