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