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