btif_av.c revision 5738f83aeb59361a0a2eda2460113f6dc9194271
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 "hardware/bt_av.h"
30
31#define LOG_TAG "BTIF_AV"
32
33#include "btif_av.h"
34#include "btif_util.h"
35#include "btif_profile_queue.h"
36#include "bta_api.h"
37#include "btif_media.h"
38#include "bta_av_api.h"
39#include "gki.h"
40#include "bd.h"
41#include "btu.h"
42
43/*****************************************************************************
44**  Constants & Macros
45******************************************************************************/
46#define BTIF_AV_SERVICE_NAME "Advanced Audio"
47
48#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS  2
49
50typedef enum {
51    BTIF_AV_STATE_IDLE = 0x0,
52    BTIF_AV_STATE_OPENING,
53    BTIF_AV_STATE_OPENED,
54    BTIF_AV_STATE_STARTED,
55    BTIF_AV_STATE_CLOSING
56} btif_av_state_t;
57
58/* Should not need dedicated suspend state as actual actions are no
59   different than open state. Suspend flags are needed however to prevent
60   media task from trying to restart stream during remote suspend or while
61   we are in the process of a local suspend */
62
63#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
64#define BTIF_AV_FLAG_REMOTE_SUSPEND        0x2
65
66/*****************************************************************************
67**  Local type definitions
68******************************************************************************/
69
70typedef struct
71{
72    tBTA_AV_HNDL bta_handle;
73    bt_bdaddr_t peer_bda;
74    btif_sm_handle_t sm_handle;
75    UINT8 flags;
76} btif_av_cb_t;
77
78/*****************************************************************************
79**  Static variables
80******************************************************************************/
81static btav_callbacks_t *bt_av_callbacks = NULL;
82static btif_av_cb_t btif_av_cb;
83static TIMER_LIST_ENT tle_av_open_on_rc;
84
85/* both interface and media task needs to be ready to alloc incoming request */
86#define CHECK_BTAV_INIT() if ((bt_av_callbacks == NULL) || (btif_av_cb.sm_handle == NULL))\
87{\
88     BTIF_TRACE_WARNING1("%s: BTAV not initialized", __FUNCTION__);\
89     return BT_STATUS_NOT_READY;\
90}\
91else\
92{\
93     BTIF_TRACE_EVENT1("%s", __FUNCTION__);\
94}
95
96/* Helper macro to avoid code duplication in the state machine handlers */
97#define CHECK_RC_EVENT(e, d) \
98    case BTA_AV_RC_OPEN_EVT: \
99    case BTA_AV_RC_CLOSE_EVT: \
100    case BTA_AV_REMOTE_CMD_EVT: \
101    case BTA_AV_VENDOR_CMD_EVT: \
102    case BTA_AV_META_MSG_EVT: \
103    case BTA_AV_RC_FEAT_EVT: \
104    { \
105         btif_rc_handler(e, d);\
106    }break; \
107
108static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
109static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
110static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
111static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
112static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
113
114static const btif_sm_handler_t btif_av_state_handlers[] =
115{
116    btif_av_state_idle_handler,
117    btif_av_state_opening_handler,
118    btif_av_state_opened_handler,
119    btif_av_state_started_handler,
120    btif_av_state_closing_handler
121};
122
123/*************************************************************************
124** Extern functions
125*************************************************************************/
126extern void btif_rc_init(void);
127extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
128extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
129extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
130
131/*****************************************************************************
132** Local helper functions
133******************************************************************************/
134
135const char *dump_av_sm_state_name(btif_av_state_t state)
136{
137    switch (state)
138    {
139        CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
140        CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
141        CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
142        CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
143        CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
144        default: return "UNKNOWN_STATE";
145    }
146}
147
148const char *dump_av_sm_event_name(btif_av_sm_event_t event)
149{
150    switch((int)event)
151    {
152        CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
153        CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
154        CASE_RETURN_STR(BTA_AV_OPEN_EVT)
155        CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
156        CASE_RETURN_STR(BTA_AV_START_EVT)
157        CASE_RETURN_STR(BTA_AV_STOP_EVT)
158        CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
159        CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
160        CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
161        CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
162        CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
163        CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
164        CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
165        CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
166        CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
167        CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
168        CASE_RETURN_STR(BTA_AV_PENDING_EVT)
169        CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
170        CASE_RETURN_STR(BTA_AV_REJECT_EVT)
171        CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
172        CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
173        CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
174        CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
175        CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
176        CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
177        CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
178        CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
179        CASE_RETURN_STR(BTIF_AV_RECONFIGURE_REQ_EVT)
180
181        default: return "UNKNOWN_EVENT";
182   }
183}
184
185/****************************************************************************
186**  Local helper functions
187*****************************************************************************/
188/*******************************************************************************
189**
190** Function         btif_initiate_av_open_tmr_hdlr
191**
192** Description      Timer to trigger AV open if the remote headset establishes
193**                  RC connection w/o AV connection. The timer is needed to IOP
194**                  with headsets that do establish AV after RC connection.
195**
196** Returns          void
197**
198*******************************************************************************/
199static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
200{
201    BD_ADDR peer_addr;
202
203    /* is there at least one RC connection - There should be */
204    if (btif_rc_get_connected_peer(peer_addr)) {
205       BTIF_TRACE_DEBUG1("%s Issuing connect to the remote RC peer", __FUNCTION__);
206       btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (void*)&peer_addr);
207    }
208    else
209    {
210        BTIF_TRACE_ERROR1("%s No connected RC peers", __FUNCTION__);
211    }
212}
213
214/*****************************************************************************
215**  Static functions
216******************************************************************************/
217
218/*****************************************************************************
219**
220** Function		btif_av_state_idle_handler
221**
222** Description  State managing disconnected AV link
223**
224** Returns      TRUE if event was processed, FALSE otherwise
225**
226*******************************************************************************/
227
228static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
229{
230    BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__,
231                     dump_av_sm_event_name(event), btif_av_cb.flags);
232
233    switch (event)
234    {
235        case BTIF_SM_ENTER_EVT:
236            /* clear the peer_bda */
237            memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
238            btif_av_cb.flags = 0;
239            btif_a2dp_on_idle();
240            break;
241
242        case BTIF_SM_EXIT_EVT:
243            break;
244
245        case BTA_AV_ENABLE_EVT:
246            break;
247
248        case BTA_AV_REGISTER_EVT:
249            btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
250            break;
251
252        case BTA_AV_PENDING_EVT:
253        case BTIF_AV_CONNECT_REQ_EVT:
254        {
255             if (event == BTIF_AV_CONNECT_REQ_EVT)
256             {
257                 memcpy(&btif_av_cb.peer_bda, (bt_bdaddr_t*)p_data, sizeof(bt_bdaddr_t));
258             }
259             else if (event == BTA_AV_PENDING_EVT)
260             {
261                  bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
262             }
263             BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
264                    TRUE, BTA_SEC_NONE);
265             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
266        } break;
267
268        case BTA_AV_RC_OPEN_EVT:
269            /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
270             * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
271             * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
272             * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
273             * headsets, as some headsets initiate the AVRC connection first and then
274             * immediately initiate the AV connection
275             *
276             * TODO: We may need to do this only on an AVRCP Play. FixMe
277             */
278
279            BTIF_TRACE_DEBUG0("BTA_AV_RC_OPEN_EVT received w/o AV");
280            memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
281            tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
282            btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
283                            BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
284            btif_rc_handler(event, p_data);
285            break;
286
287        case BTA_AV_REMOTE_CMD_EVT:
288        case BTA_AV_VENDOR_CMD_EVT:
289        case BTA_AV_META_MSG_EVT:
290        case BTA_AV_RC_FEAT_EVT:
291            btif_rc_handler(event, (tBTA_AV*)p_data);
292            break;
293
294        case BTA_AV_RC_CLOSE_EVT:
295            if (tle_av_open_on_rc.in_use) {
296                BTIF_TRACE_DEBUG0("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
297                btu_stop_timer(&tle_av_open_on_rc);
298            }
299            btif_rc_handler(event, p_data);
300            break;
301
302        default:
303            BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__,
304                                dump_av_sm_event_name(event));
305            return FALSE;
306
307    }
308    return TRUE;
309}
310/*****************************************************************************
311**
312** Function        btif_av_state_opening_handler
313**
314** Description     Intermediate state managing events during establishment
315**                 of avdtp channel
316**
317** Returns         TRUE if event was processed, FALSE otherwise
318**
319*******************************************************************************/
320
321static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
322{
323    BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__,
324                     dump_av_sm_event_name(event), btif_av_cb.flags);
325
326    switch (event)
327    {
328        case BTIF_SM_ENTER_EVT:
329            /* inform the application that we are entering connecting state */
330            HAL_CBACK(bt_av_callbacks, connection_state_cb,
331                      BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
332            break;
333
334        case BTIF_SM_EXIT_EVT:
335            break;
336
337        case BTA_AV_OPEN_EVT:
338        {
339            tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
340            btav_connection_state_t state;
341            btif_sm_state_t av_state;
342            BTIF_TRACE_DEBUG1("status:%d", p_bta_data->open.status);
343
344            if (p_bta_data->open.status == BTA_AV_SUCCESS)
345            {
346                 state = BTAV_CONNECTION_STATE_CONNECTED;
347                 av_state = BTIF_AV_STATE_OPENED;
348            }
349            else
350            {
351                BTIF_TRACE_WARNING1("BTA_AV_OPEN_EVT::FAILED status: %d",
352                                     p_bta_data->open.status );
353                state = BTAV_CONNECTION_STATE_DISCONNECTED;
354                av_state  = BTIF_AV_STATE_IDLE;
355            }
356
357            /* inform the application of the event */
358            HAL_CBACK(bt_av_callbacks, connection_state_cb,
359                             state, &(btif_av_cb.peer_bda));
360            /* change state to open/idle based on the status */
361            btif_sm_change_state(btif_av_cb.sm_handle, av_state);
362            /* if queued PLAY command,  send it now */
363            btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
364                                             (p_bta_data->open.status == BTA_AV_SUCCESS));
365            btif_queue_advance();
366        } break;
367
368        CHECK_RC_EVENT(event, p_data);
369
370        default:
371            BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__,
372                                dump_av_sm_event_name(event));
373            return FALSE;
374
375   }
376   return TRUE;
377}
378
379
380/*****************************************************************************
381**
382** Function        btif_av_state_closing_handler
383**
384** Description     Intermediate state managing events during closing
385**                 of avdtp channel
386**
387** Returns         TRUE if event was processed, FALSE otherwise
388**
389*******************************************************************************/
390
391static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
392{
393    BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__,
394                     dump_av_sm_event_name(event), btif_av_cb.flags);
395
396    switch (event)
397    {
398        case BTIF_SM_ENTER_EVT:
399
400            /* immediately stop transmission of frames */
401            btif_a2dp_set_tx_flush(TRUE);
402            /* wait for audioflinger to stop a2dp */
403            break;
404
405        case BTIF_AV_STOP_STREAM_REQ_EVT:
406              /* immediately flush any pending tx frames while suspend is pending */
407              btif_a2dp_set_tx_flush(TRUE);
408
409              btif_a2dp_on_stopped(NULL);
410
411              break;
412
413        case BTIF_SM_EXIT_EVT:
414            break;
415
416        case BTA_AV_CLOSE_EVT:
417
418            /* inform the application that we are disconnecting */
419            HAL_CBACK(bt_av_callbacks, connection_state_cb,
420                BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
421
422            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
423            break;
424
425        /* Handle the RC_CLOSE event for the cleanup */
426        case BTA_AV_RC_CLOSE_EVT:
427            btif_rc_handler(event, (tBTA_AV*)p_data);
428            break;
429
430        default:
431            BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__,
432                                dump_av_sm_event_name(event));
433            return FALSE;
434   }
435   return TRUE;
436}
437
438
439/*****************************************************************************
440**
441** Function     btif_av_state_opened_handler
442**
443** Description  Handles AV events while AVDTP is in OPEN state
444**
445** Returns      TRUE if event was processed, FALSE otherwise
446**
447*******************************************************************************/
448
449static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
450{
451    tBTA_AV *p_av = (tBTA_AV*)p_data;
452
453    BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__,
454                     dump_av_sm_event_name(event), btif_av_cb.flags);
455
456    if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
457         (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
458    {
459        BTIF_TRACE_EVENT1("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
460        btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
461    }
462
463    switch (event)
464    {
465        case BTIF_SM_ENTER_EVT:
466            btif_media_check_iop_exceptions(btif_av_cb.peer_bda.address);
467            break;
468
469        case BTIF_SM_EXIT_EVT:
470            break;
471
472        case BTIF_AV_START_STREAM_REQ_EVT:
473            btif_a2dp_setup_codec();
474            BTA_AvStart();
475            break;
476
477        case BTA_AV_START_EVT:
478        {
479            BTIF_TRACE_EVENT3("BTA_AV_START_EVT status %d, suspending %d, init %d",
480                p_av->start.status, p_av->start.suspending, p_av->start.initiator);
481
482            if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
483                return TRUE;
484
485            btif_a2dp_on_started(&p_av->start);
486
487            /* remain in open state if status failed */
488            if (p_av->start.status != BTA_AV_SUCCESS)
489                return FALSE;
490
491            /* change state to started */
492            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
493
494        } break;
495
496        case BTIF_AV_DISCONNECT_REQ_EVT:
497            BTA_AvClose(btif_av_cb.bta_handle);
498
499            /* inform the application that we are disconnecting */
500            HAL_CBACK(bt_av_callbacks, connection_state_cb,
501               BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
502            break;
503
504        case BTA_AV_CLOSE_EVT:
505
506            /* inform the application that we are disconnected */
507            HAL_CBACK(bt_av_callbacks, connection_state_cb,
508                BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
509
510            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
511            break;
512
513        CHECK_RC_EVENT(event, p_data);
514
515        default:
516            BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__,
517                               dump_av_sm_event_name(event));
518            return FALSE;
519
520    }
521    return TRUE;
522}
523
524/*****************************************************************************
525**
526** Function     btif_av_state_started_handler
527**
528** Description  Handles AV events while A2DP stream is started
529**
530** Returns      TRUE if event was processed, FALSE otherwise
531**
532*******************************************************************************/
533
534static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
535{
536    tBTA_AV *p_av = (tBTA_AV*)p_data;
537
538    BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__,
539                     dump_av_sm_event_name(event), btif_av_cb.flags);
540
541    switch (event)
542    {
543        case BTIF_SM_ENTER_EVT:
544
545            /* we are again in started state, clear any remote suspend flags */
546            btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
547
548            HAL_CBACK(bt_av_callbacks, audio_state_cb,
549                BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
550            break;
551
552        case BTIF_SM_EXIT_EVT:
553            break;
554
555        /* fixme -- use suspend = true always to work around issue with BTA AV */
556        case BTIF_AV_STOP_STREAM_REQ_EVT:
557        case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
558
559            /* set pending flag to ensure btif task is not trying to restart
560               stream while suspend is in progress */
561            btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
562
563            /* if we were remotely suspended but suspend locally, local suspend
564               always overrides */
565            btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
566
567            /* immediately stop transmission of frames while suspend is pending */
568            btif_a2dp_set_tx_flush(TRUE);
569
570            BTA_AvStop(TRUE);
571            break;
572
573        case BTIF_AV_DISCONNECT_REQ_EVT:
574
575            /* request avdtp to close */
576            BTA_AvClose(btif_av_cb.bta_handle);
577
578            /* inform the application that we are disconnecting */
579            HAL_CBACK(bt_av_callbacks, connection_state_cb,
580                BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
581
582            /* wait in closing state until fully closed */
583            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
584            break;
585
586        case BTA_AV_SUSPEND_EVT:
587
588            BTIF_TRACE_EVENT2("BTA_AV_SUSPEND_EVT status %d, init %d",
589                 p_av->suspend.status, p_av->suspend.initiator);
590
591            /* a2dp suspended, stop media task until resumed */
592            btif_a2dp_on_suspended(&p_av->suspend);
593
594            /* if not successful, remain in current state */
595            if (p_av->suspend.status != BTA_AV_SUCCESS)
596            {
597                btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
598
599                /* suspend failed, reset back tx flush state */
600                btif_a2dp_set_tx_flush(FALSE);
601                return FALSE;
602            }
603
604            if (p_av->suspend.initiator != TRUE)
605            {
606                /* remote suspend, notify HAL and await audioflinger to
607                   suspend/stop stream */
608
609                /* set remote suspend flag to block media task from restarting
610                   stream only if we did not already initiate a local suspend */
611                if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
612                    btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
613
614                HAL_CBACK(bt_av_callbacks, audio_state_cb,
615                        BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
616            }
617            else
618            {
619                HAL_CBACK(bt_av_callbacks, audio_state_cb,
620                        BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
621            }
622
623            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
624
625            /* suspend completed and state changed, clear pending status */
626            btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
627            break;
628
629        case BTA_AV_STOP_EVT:
630
631            btif_a2dp_on_stopped(&p_av->suspend);
632
633            HAL_CBACK(bt_av_callbacks, audio_state_cb,
634                      BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
635
636            /* if stop was successful, change state to open */
637            if (p_av->suspend.status == BTA_AV_SUCCESS)
638                btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
639
640            break;
641
642        case BTA_AV_CLOSE_EVT:
643
644            /* avdtp link is closed */
645
646            btif_a2dp_on_stopped(NULL);
647
648            /* inform the application that we are disconnected */
649            HAL_CBACK(bt_av_callbacks, connection_state_cb,
650                BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
651
652            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
653            break;
654
655        CHECK_RC_EVENT(event, p_data);
656
657        default:
658            BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__,
659                                 dump_av_sm_event_name(event));
660            return FALSE;
661
662    }
663    return TRUE;
664}
665
666/*****************************************************************************
667**  Local event handlers
668******************************************************************************/
669
670static void btif_av_handle_event(UINT16 event, char* p_param)
671{
672    btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
673}
674
675static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
676{
677    /* Switch to BTIF context */
678    btif_transfer_context(btif_av_handle_event, event,
679                          (char*)p_data, sizeof(tBTA_AV), NULL);
680}
681
682/*******************************************************************************
683**
684** Function         btif_av_init
685**
686** Description      Initializes btif AV if not already done
687**
688** Returns          bt_status_t
689**
690*******************************************************************************/
691
692bt_status_t btif_av_init(void)
693{
694    if (btif_av_cb.sm_handle == NULL)
695    {
696        if (btif_a2dp_start_media_task() != GKI_SUCCESS)
697            return BT_STATUS_FAIL;
698
699        btif_enable_service(BTA_A2DP_SERVICE_ID);
700
701        /* Initialize the AVRC CB */
702        btif_rc_init();
703
704        /* Also initialize the AV state machine */
705        btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
706
707        btif_a2dp_on_init();
708
709        return BT_STATUS_SUCCESS;
710    }
711
712    return BT_STATUS_DONE;
713}
714
715/*******************************************************************************
716**
717** Function         init
718**
719** Description      Initializes the AV interface
720**
721** Returns          bt_status_t
722**
723*******************************************************************************/
724
725static bt_status_t init(btav_callbacks_t* callbacks )
726{
727    int status;
728
729    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
730
731    if (bt_av_callbacks)
732        return BT_STATUS_DONE;
733
734    bt_av_callbacks = callbacks;
735    btif_av_cb.sm_handle = NULL;
736
737    return btif_av_init();
738}
739
740/*******************************************************************************
741**
742** Function         connect
743**
744** Description      Establishes the AV signalling channel with the remote headset
745**
746** Returns          bt_status_t
747**
748*******************************************************************************/
749
750static bt_status_t connect_int(bt_bdaddr_t *bd_addr)
751{
752    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
753
754    btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)bd_addr);
755
756    return BT_STATUS_SUCCESS;
757}
758
759static bt_status_t connect(bt_bdaddr_t *bd_addr)
760{
761    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
762    CHECK_BTAV_INIT();
763
764    return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
765}
766
767/*******************************************************************************
768**
769** Function         disconnect
770**
771** Description      Tears down the AV signalling channel with the remote headset
772**
773** Returns          bt_status_t
774**
775*******************************************************************************/
776static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
777{
778    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
779
780    CHECK_BTAV_INIT();
781
782    /* Switch to BTIF context */
783    return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
784                                 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
785}
786
787/*******************************************************************************
788**
789** Function         cleanup
790**
791** Description      Shuts down the AV interface and does the cleanup
792**
793** Returns          None
794**
795*******************************************************************************/
796static void cleanup(void)
797{
798    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
799
800    if (bt_av_callbacks)
801    {
802        btif_a2dp_stop_media_task();
803
804        btif_disable_service(BTA_A2DP_SERVICE_ID);
805        bt_av_callbacks = NULL;
806
807        /* Also shut down the AV state machine */
808        btif_sm_shutdown(btif_av_cb.sm_handle);
809        btif_av_cb.sm_handle = NULL;
810    }
811    return;
812}
813
814static const btav_interface_t bt_av_interface = {
815    sizeof(btav_interface_t),
816    init,
817    connect,
818    disconnect,
819    cleanup,
820};
821
822/*******************************************************************************
823**
824** Function         btif_av_get_sm_handle
825**
826** Description      Fetches current av SM handle
827**
828** Returns          None
829**
830*******************************************************************************/
831
832btif_sm_handle_t btif_av_get_sm_handle(void)
833{
834    return btif_av_cb.sm_handle;
835}
836
837/*******************************************************************************
838**
839** Function         btif_av_stream_ready
840**
841** Description      Checks whether AV is ready for starting a stream
842**
843** Returns          None
844**
845*******************************************************************************/
846
847BOOLEAN btif_av_stream_ready(void)
848{
849    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
850
851    BTIF_TRACE_DEBUG3("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
852                btif_av_cb.sm_handle, state, btif_av_cb.flags);
853
854    /* also make sure main adapter is enabled */
855    if (btif_is_enabled() == 0)
856    {
857        BTIF_TRACE_EVENT0("main adapter not enabled");
858        return FALSE;
859    }
860
861    /* check if we are remotely suspended */
862    if (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND)
863        return FALSE;
864
865    return (state == BTIF_AV_STATE_OPENED);
866}
867
868/*******************************************************************************
869**
870** Function         btif_av_stream_started_ready
871**
872** Description      Checks whether AV ready for media start in streaming state
873**
874** Returns          None
875**
876*******************************************************************************/
877
878BOOLEAN btif_av_stream_started_ready(void)
879{
880    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
881
882    BTIF_TRACE_DEBUG3("btif_av_stream_started : sm hdl %d, state %d, flags %x",
883                btif_av_cb.sm_handle, state, btif_av_cb.flags);
884
885    /* don't allow media task to start if we are suspending or
886       remotely suspended (not yet changed state) */
887    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND))
888        return FALSE;
889
890    return (state == BTIF_AV_STATE_STARTED);
891}
892
893/*******************************************************************************
894**
895** Function         btif_dispatch_sm_event
896**
897** Description      Send event to AV statemachine
898**
899** Returns          None
900**
901*******************************************************************************/
902
903/* used to pass events to AV statemachine from other tasks */
904void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
905{
906    /* Switch to BTIF context */
907    btif_transfer_context(btif_av_handle_event, event,
908                          (char*)p_data, len, NULL);
909}
910
911/*******************************************************************************
912**
913** Function         btif_av_execute_service
914**
915** Description      Initializes/Shuts down the service
916**
917** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
918**
919*******************************************************************************/
920bt_status_t btif_av_execute_service(BOOLEAN b_enable)
921{
922     if (b_enable)
923     {
924         /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
925          * handle this request in order to allow incoming connections to succeed.
926          * We need to put this back once support for this is added */
927
928         /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
929          * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
930          * be initiated by the app/audioflinger layers */
931         BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
932                      bte_av_callback);
933         BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0);
934     }
935     else {
936         BTA_AvDeregister(btif_av_cb.bta_handle);
937         BTA_AvDisable();
938     }
939     return BT_STATUS_SUCCESS;
940}
941
942/*******************************************************************************
943**
944** Function         btif_av_get_interface
945**
946** Description      Get the AV callback interface
947**
948** Returns          btav_interface_t
949**
950*******************************************************************************/
951const btav_interface_t *btif_av_get_interface(void)
952{
953    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
954    return &bt_av_interface;
955}
956
957/*******************************************************************************
958**
959** Function         btif_av_is_rc_open_without_a2dp
960**
961** Description      Checks if GAVDTP Open notification to app is pending (2 second timer)
962**
963** Returns          boolean
964**
965*******************************************************************************/
966BOOLEAN btif_av_is_connected(void)
967{
968    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
969    return ((state == BTIF_AV_STATE_OPENED) || (state ==  BTIF_AV_STATE_STARTED));
970}
971