• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
50 typedef 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 
70 typedef 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 ******************************************************************************/
81 static btav_callbacks_t *bt_av_callbacks = NULL;
82 static btif_av_cb_t btif_av_cb;
83 static 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 }\
91 else\
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 
108 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
109 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
110 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
111 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
112 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
113 
114 static 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 *************************************************************************/
126 extern void btif_rc_init(void);
127 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
128 extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
129 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
130 
131 /*****************************************************************************
132 ** Local helper functions
133 ******************************************************************************/
134 
dump_av_sm_state_name(btif_av_state_t state)135 const 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 
dump_av_sm_event_name(btif_av_sm_event_t event)148 const 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 *******************************************************************************/
btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT * tle)199 static 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 
btif_av_state_idle_handler(btif_sm_event_t event,void * p_data)228 static 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 
btif_av_state_opening_handler(btif_sm_event_t event,void * p_data)321 static 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 
btif_av_state_closing_handler(btif_sm_event_t event,void * p_data)391 static 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 
btif_av_state_opened_handler(btif_sm_event_t event,void * p_data)449 static 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 
btif_av_state_started_handler(btif_sm_event_t event,void * p_data)534 static 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 
btif_av_handle_event(UINT16 event,char * p_param)670 static 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 
bte_av_callback(tBTA_AV_EVT event,tBTA_AV * p_data)675 static 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 
btif_av_init(void)692 bt_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 
init(btav_callbacks_t * callbacks)725 static 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 
connect_int(bt_bdaddr_t * bd_addr)750 static 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 
connect(bt_bdaddr_t * bd_addr)759 static 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 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)776 static 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 *******************************************************************************/
cleanup(void)796 static 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 
814 static 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 
btif_av_get_sm_handle(void)832 btif_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 
btif_av_stream_ready(void)847 BOOLEAN 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 
btif_av_stream_started_ready(void)878 BOOLEAN 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 */
btif_dispatch_sm_event(btif_av_sm_event_t event,void * p_data,int len)904 void 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 *******************************************************************************/
btif_av_execute_service(BOOLEAN b_enable)920 bt_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 *******************************************************************************/
btif_av_get_interface(void)951 const 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 *******************************************************************************/
btif_av_is_connected(void)966 BOOLEAN 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