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