1 /******************************************************************************
3 * Copyright (C) 2009-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
20 /*****************************************************************************
24 * Description: Bluedroid AV implementation
26 *****************************************************************************/
28 #include <hardware/bluetooth.h>
29 #include <system/audio.h>
31 #include "hardware/bt_av.h"
33 #define LOG_TAG "bt_btif_av"
36 #include "btif_util.h"
37 #include "btif_profile_queue.h"
39 #include "btif_media.h"
40 #include "bta_av_api.h"
45 /*****************************************************************************
47 ******************************************************************************/
48 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
50 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
53 BTIF_AV_STATE_IDLE = 0x0,
54 BTIF_AV_STATE_OPENING,
56 BTIF_AV_STATE_STARTED,
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 */
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
70 /*****************************************************************************
71 ** Local type definitions
72 ******************************************************************************/
76 tBTA_AV_HNDL bta_handle;
78 btif_sm_handle_t sm_handle;
81 UINT8 peer_sep; /* sep type of peer device */
86 bt_bdaddr_t *target_bda;
88 } btif_av_connect_req_t;
94 } btif_av_sink_config_req_t;
96 /*****************************************************************************
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;
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))\
108 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
109 return BT_STATUS_NOT_READY;\
113 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
116 /* Helper macro to avoid code duplication in the state machine handlers */
117 #define CHECK_RC_EVENT(e, d) \
118 case BTA_AV_RC_OPEN_EVT: \
119 case BTA_AV_RC_CLOSE_EVT: \
120 case BTA_AV_REMOTE_CMD_EVT: \
121 case BTA_AV_VENDOR_CMD_EVT: \
122 case BTA_AV_META_MSG_EVT: \
123 case BTA_AV_RC_FEAT_EVT: \
124 case BTA_AV_REMOTE_RSP_EVT: \
126 btif_rc_handler(e, d);\
129 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
130 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
131 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
132 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
133 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
135 static const btif_sm_handler_t btif_av_state_handlers[] =
137 btif_av_state_idle_handler,
138 btif_av_state_opening_handler,
139 btif_av_state_opened_handler,
140 btif_av_state_started_handler,
141 btif_av_state_closing_handler
144 /*************************************************************************
146 *************************************************************************/
147 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
148 extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
149 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
151 /*****************************************************************************
152 ** Local helper functions
153 ******************************************************************************/
155 const char *dump_av_sm_state_name(btif_av_state_t state)
159 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
160 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
161 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
162 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
163 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
164 default: return "UNKNOWN_STATE";
168 const char *dump_av_sm_event_name(btif_av_sm_event_t event)
172 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
173 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
174 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
175 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
176 CASE_RETURN_STR(BTA_AV_START_EVT)
177 CASE_RETURN_STR(BTA_AV_STOP_EVT)
178 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
179 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
180 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
181 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
182 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
183 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
184 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
185 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
186 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
187 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
188 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
189 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
190 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
191 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
192 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
193 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
194 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
195 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
196 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
197 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
198 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
199 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
200 default: return "UNKNOWN_EVENT";
204 /****************************************************************************
205 ** Local helper functions
206 *****************************************************************************/
207 /*******************************************************************************
209 ** Function btif_initiate_av_open_tmr_hdlr
211 ** Description Timer to trigger AV open if the remote headset establishes
212 ** RC connection w/o AV connection. The timer is needed to IOP
213 ** with headsets that do establish AV after RC connection.
217 *******************************************************************************/
218 static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
222 btif_av_connect_req_t connect_req;
224 /* is there at least one RC connection - There should be */
225 if (btif_rc_get_connected_peer(peer_addr)) {
226 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
227 /* In case of AVRCP connection request, we will initiate SRC connection */
228 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
229 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
230 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
234 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
238 /*****************************************************************************
240 ******************************************************************************/
242 static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
244 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
245 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
246 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
247 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
251 static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
253 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
254 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
255 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
256 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
260 /*****************************************************************************
262 ** Function btif_av_state_idle_handler
264 ** Description State managing disconnected AV link
266 ** Returns TRUE if event was processed, FALSE otherwise
268 *******************************************************************************/
270 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
272 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
273 dump_av_sm_event_name(event), btif_av_cb.flags);
277 case BTIF_SM_ENTER_EVT:
278 /* clear the peer_bda */
279 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
280 btif_av_cb.flags = 0;
285 case BTIF_SM_EXIT_EVT:
288 case BTA_AV_ENABLE_EVT:
291 case BTA_AV_REGISTER_EVT:
292 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
295 case BTA_AV_PENDING_EVT:
296 case BTIF_AV_CONNECT_REQ_EVT:
298 if (event == BTIF_AV_CONNECT_REQ_EVT)
300 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
301 sizeof(bt_bdaddr_t));
302 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
303 TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid);
305 else if (event == BTA_AV_PENDING_EVT)
307 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
308 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
309 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE);
311 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
314 case BTA_AV_RC_OPEN_EVT:
315 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
316 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
317 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
318 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
319 * headsets, as some headsets initiate the AVRC connection first and then
320 * immediately initiate the AV connection
322 * TODO: We may need to do this only on an AVRCP Play. FixMe
325 BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
326 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
327 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
328 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
329 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
330 btif_rc_handler(event, p_data);
333 case BTA_AV_REMOTE_CMD_EVT:
334 case BTA_AV_VENDOR_CMD_EVT:
335 case BTA_AV_META_MSG_EVT:
336 case BTA_AV_RC_FEAT_EVT:
337 case BTA_AV_REMOTE_RSP_EVT:
338 btif_rc_handler(event, (tBTA_AV*)p_data);
341 case BTA_AV_RC_CLOSE_EVT:
342 if (tle_av_open_on_rc.in_use) {
343 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
344 btu_stop_timer(&tle_av_open_on_rc);
346 btif_rc_handler(event, p_data);
350 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
351 dump_av_sm_event_name(event));
357 /*****************************************************************************
359 ** Function btif_av_state_opening_handler
361 ** Description Intermediate state managing events during establishment
364 ** Returns TRUE if event was processed, FALSE otherwise
366 *******************************************************************************/
368 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
370 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
371 dump_av_sm_event_name(event), btif_av_cb.flags);
375 case BTIF_SM_ENTER_EVT:
376 /* inform the application that we are entering connecting state */
377 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
380 case BTIF_SM_EXIT_EVT:
383 case BTA_AV_REJECT_EVT:
384 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
385 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
386 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
389 case BTA_AV_OPEN_EVT:
391 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
392 btav_connection_state_t state;
393 btif_sm_state_t av_state;
394 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
395 p_bta_data->open.edr);
397 if (p_bta_data->open.status == BTA_AV_SUCCESS)
399 state = BTAV_CONNECTION_STATE_CONNECTED;
400 av_state = BTIF_AV_STATE_OPENED;
401 btif_av_cb.edr = p_bta_data->open.edr;
403 btif_av_cb.peer_sep = p_bta_data->open.sep;
404 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
408 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
409 p_bta_data->open.status );
410 state = BTAV_CONNECTION_STATE_DISCONNECTED;
411 av_state = BTIF_AV_STATE_IDLE;
414 /* inform the application of the event */
415 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
416 /* change state to open/idle based on the status */
417 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
418 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
420 /* if queued PLAY command, send it now */
421 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
422 (p_bta_data->open.status == BTA_AV_SUCCESS));
424 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
426 /* if queued PLAY command, send it now */
427 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
428 /* Bring up AVRCP connection too */
429 BTA_AvOpenRc(btif_av_cb.bta_handle);
431 btif_queue_advance();
434 case BTIF_AV_SINK_CONFIG_REQ_EVT:
436 btif_av_sink_config_req_t req;
437 // copy to avoid alignment problems
438 memcpy(&req, p_data, sizeof(req));
440 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
442 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
443 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
444 req.sample_rate, req.channel_count);
448 CHECK_RC_EVENT(event, p_data);
451 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
452 dump_av_sm_event_name(event));
460 /*****************************************************************************
462 ** Function btif_av_state_closing_handler
464 ** Description Intermediate state managing events during closing
467 ** Returns TRUE if event was processed, FALSE otherwise
469 *******************************************************************************/
471 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
473 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
474 dump_av_sm_event_name(event), btif_av_cb.flags);
478 case BTIF_SM_ENTER_EVT:
479 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
481 /* immediately stop transmission of frames */
482 btif_a2dp_set_tx_flush(TRUE);
483 /* wait for audioflinger to stop a2dp */
485 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
487 btif_a2dp_set_rx_flush(TRUE);
491 case BTA_AV_STOP_EVT:
492 case BTIF_AV_STOP_STREAM_REQ_EVT:
493 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
495 /* immediately flush any pending tx frames while suspend is pending */
496 btif_a2dp_set_tx_flush(TRUE);
498 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
500 btif_a2dp_set_rx_flush(TRUE);
503 btif_a2dp_on_stopped(NULL);
506 case BTIF_SM_EXIT_EVT:
509 case BTA_AV_CLOSE_EVT:
511 /* inform the application that we are disconnecting */
512 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
514 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
517 /* Handle the RC_CLOSE event for the cleanup */
518 case BTA_AV_RC_CLOSE_EVT:
519 btif_rc_handler(event, (tBTA_AV*)p_data);
523 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
524 dump_av_sm_event_name(event));
531 /*****************************************************************************
533 ** Function btif_av_state_opened_handler
535 ** Description Handles AV events while AVDTP is in OPEN state
537 ** Returns TRUE if event was processed, FALSE otherwise
539 *******************************************************************************/
541 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
543 tBTA_AV *p_av = (tBTA_AV*)p_data;
545 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
546 dump_av_sm_event_name(event), btif_av_cb.flags);
548 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
549 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
551 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
552 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
557 case BTIF_SM_ENTER_EVT:
558 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
559 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
562 case BTIF_SM_EXIT_EVT:
563 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
566 case BTIF_AV_START_STREAM_REQ_EVT:
567 if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
568 btif_a2dp_setup_codec();
570 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
573 case BTA_AV_START_EVT:
575 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
576 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
578 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
581 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
582 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
584 if (btif_a2dp_on_started(&p_av->start,
585 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
587 /* only clear pending flag after acknowledgement */
588 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
592 /* remain in open state if status failed */
593 if (p_av->start.status != BTA_AV_SUCCESS)
596 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
598 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
601 /* change state to started, send acknowledgement if start is pending */
602 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
603 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
604 btif_a2dp_on_started(NULL, TRUE);
605 /* pending start flag will be cleared when exit current state */
607 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
611 case BTIF_AV_DISCONNECT_REQ_EVT:
612 BTA_AvClose(btif_av_cb.bta_handle);
613 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
614 BTA_AvCloseRc(btif_av_cb.bta_handle);
617 /* inform the application that we are disconnecting */
618 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
621 case BTA_AV_CLOSE_EVT:
622 /* avdtp link is closed */
623 btif_a2dp_on_stopped(NULL);
625 /* inform the application that we are disconnected */
626 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
628 /* change state to idle, send acknowledgement if start is pending */
629 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
630 btif_a2dp_ack_fail();
631 /* pending start flag will be cleared when exit current state */
633 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
636 case BTA_AV_RECONFIG_EVT:
637 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
638 (p_av->reconfig.status == BTA_AV_SUCCESS))
640 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
643 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
645 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
646 btif_a2dp_ack_fail();
650 CHECK_RC_EVENT(event, p_data);
653 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
654 dump_av_sm_event_name(event));
661 /*****************************************************************************
663 ** Function btif_av_state_started_handler
665 ** Description Handles AV events while A2DP stream is started
667 ** Returns TRUE if event was processed, FALSE otherwise
669 *******************************************************************************/
671 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
673 tBTA_AV *p_av = (tBTA_AV*)p_data;
675 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
676 dump_av_sm_event_name(event), btif_av_cb.flags);
680 case BTIF_SM_ENTER_EVT:
682 /* we are again in started state, clear any remote suspend flags */
683 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
685 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
687 /* increase the a2dp consumer task priority temporarily when start
688 ** audio playing, to avoid overflow the audio packet queue. */
689 adjust_priority_a2dp(TRUE);
693 case BTIF_SM_EXIT_EVT:
694 /* restore the a2dp consumer task priority when stop audio playing. */
695 adjust_priority_a2dp(FALSE);
699 case BTIF_AV_START_STREAM_REQ_EVT:
700 /* we were remotely started, just ack back the local request */
701 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
702 btif_a2dp_on_started(NULL, TRUE);
705 /* fixme -- use suspend = true always to work around issue with BTA AV */
706 case BTIF_AV_STOP_STREAM_REQ_EVT:
707 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
709 /* set pending flag to ensure btif task is not trying to restart
710 stream while suspend is in progress */
711 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
713 /* if we were remotely suspended but suspend locally, local suspend
715 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
717 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
719 /* immediately stop transmission of frames while suspend is pending */
720 btif_a2dp_set_tx_flush(TRUE);
723 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
724 btif_a2dp_set_rx_flush(TRUE);
725 btif_a2dp_on_stopped(NULL);
731 case BTIF_AV_DISCONNECT_REQ_EVT:
733 /* request avdtp to close */
734 BTA_AvClose(btif_av_cb.bta_handle);
735 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
736 BTA_AvCloseRc(btif_av_cb.bta_handle);
739 /* inform the application that we are disconnecting */
740 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
742 /* wait in closing state until fully closed */
743 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
746 case BTA_AV_SUSPEND_EVT:
748 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
749 p_av->suspend.status, p_av->suspend.initiator);
751 /* a2dp suspended, stop media task until resumed */
752 btif_a2dp_on_suspended(&p_av->suspend);
754 /* if not successful, remain in current state */
755 if (p_av->suspend.status != BTA_AV_SUCCESS)
757 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
759 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
761 /* suspend failed, reset back tx flush state */
762 btif_a2dp_set_tx_flush(FALSE);
767 if (p_av->suspend.initiator != TRUE)
769 /* remote suspend, notify HAL and await audioflinger to
770 suspend/stop stream */
772 /* set remote suspend flag to block media task from restarting
773 stream only if we did not already initiate a local suspend */
774 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
775 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
777 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
781 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
784 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
786 /* suspend completed and state changed, clear pending status */
787 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
790 case BTA_AV_STOP_EVT:
792 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
793 btif_a2dp_on_stopped(&p_av->suspend);
795 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
797 /* if stop was successful, change state to open */
798 if (p_av->suspend.status == BTA_AV_SUCCESS)
799 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
803 case BTA_AV_CLOSE_EVT:
805 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
807 /* avdtp link is closed */
808 btif_a2dp_on_stopped(NULL);
810 /* inform the application that we are disconnected */
811 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
813 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
816 CHECK_RC_EVENT(event, p_data);
819 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
820 dump_av_sm_event_name(event));
827 /*****************************************************************************
828 ** Local event handlers
829 ******************************************************************************/
831 static void btif_av_handle_event(UINT16 event, char* p_param)
833 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
836 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
838 /* Switch to BTIF context */
839 btif_transfer_context(btif_av_handle_event, event,
840 (char*)p_data, sizeof(tBTA_AV), NULL);
843 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
845 btif_sm_state_t state;
847 tA2D_STATUS a2d_status;
848 tA2D_SBC_CIE sbc_cie;
849 btif_av_sink_config_req_t config_req;
851 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
853 state= btif_sm_get_state(btif_av_cb.sm_handle);
854 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
855 (state == BTIF_AV_STATE_OPENED) )
857 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
858 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
864 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
865 /* send a command to BT Media Task */
866 btif_reset_decoder((UINT8*)p_data);
868 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
869 if (a2d_status == A2D_SUCCESS) {
870 /* Switch to BTIF context */
871 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
872 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
873 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
874 (char*)&config_req, sizeof(config_req), NULL);
876 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
880 /*******************************************************************************
882 ** Function btif_av_init
884 ** Description Initializes btif AV if not already done
886 ** Returns bt_status_t
888 *******************************************************************************/
890 bt_status_t btif_av_init()
892 if (btif_av_cb.sm_handle == NULL)
894 if (!btif_a2dp_start_media_task())
895 return BT_STATUS_FAIL;
897 btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
898 #if (BTA_AV_SINK_INCLUDED == TRUE)
899 btif_enable_service(BTA_A2DP_SINK_SERVICE_ID);
902 /* Also initialize the AV state machine */
903 btif_av_cb.sm_handle =
904 btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
908 return BT_STATUS_SUCCESS;
911 return BT_STATUS_DONE;
914 /*******************************************************************************
918 ** Description Initializes the AV interface for source mode
920 ** Returns bt_status_t
922 *******************************************************************************/
924 static bt_status_t init_src(btav_callbacks_t* callbacks)
928 BTIF_TRACE_EVENT("%s", __FUNCTION__);
930 if (bt_av_sink_callbacks != NULL) {
931 // already did btif_av_init()
932 status = BT_STATUS_SUCCESS;
934 status = btif_av_init();
937 if (status == BT_STATUS_SUCCESS) {
938 bt_av_src_callbacks = callbacks;
944 /*******************************************************************************
946 ** Function init_sink
948 ** Description Initializes the AV interface for sink mode
950 ** Returns bt_status_t
952 *******************************************************************************/
954 static bt_status_t init_sink(btav_callbacks_t* callbacks)
958 BTIF_TRACE_EVENT("%s", __FUNCTION__);
960 if (bt_av_src_callbacks != NULL) {
961 // already did btif_av_init()
962 status = BT_STATUS_SUCCESS;
964 status = btif_av_init();
967 if (status == BT_STATUS_SUCCESS) {
968 bt_av_sink_callbacks = callbacks;
974 /*******************************************************************************
978 ** Description Establishes the AV signalling channel with the remote headset
980 ** Returns bt_status_t
982 *******************************************************************************/
984 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
986 btif_av_connect_req_t connect_req;
987 connect_req.target_bda = bd_addr;
988 connect_req.uuid = uuid;
989 BTIF_TRACE_EVENT("%s", __FUNCTION__);
991 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
993 return BT_STATUS_SUCCESS;
996 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
998 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1001 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1004 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1006 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1009 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1012 /*******************************************************************************
1014 ** Function disconnect
1016 ** Description Tears down the AV signalling channel with the remote headset
1018 ** Returns bt_status_t
1020 *******************************************************************************/
1021 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1023 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1027 /* Switch to BTIF context */
1028 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1029 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1032 /*******************************************************************************
1036 ** Description Shuts down the AV interface and does the cleanup
1040 *******************************************************************************/
1041 static void cleanup(void)
1043 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1045 btif_a2dp_stop_media_task();
1047 btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
1048 #if (BTA_AV_SINK_INCLUDED == TRUE)
1049 btif_disable_service(BTA_A2DP_SINK_SERVICE_ID);
1052 /* Also shut down the AV state machine */
1053 btif_sm_shutdown(btif_av_cb.sm_handle);
1054 btif_av_cb.sm_handle = NULL;
1057 static void cleanup_src(void) {
1058 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1060 if (bt_av_src_callbacks)
1062 bt_av_src_callbacks = NULL;
1063 if (bt_av_sink_callbacks == NULL)
1068 static void cleanup_sink(void) {
1069 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1071 if (bt_av_sink_callbacks)
1073 bt_av_sink_callbacks = NULL;
1074 if (bt_av_src_callbacks == NULL)
1079 static const btav_interface_t bt_av_src_interface = {
1080 sizeof(btav_interface_t),
1087 static const btav_interface_t bt_av_sink_interface = {
1088 sizeof(btav_interface_t),
1095 /*******************************************************************************
1097 ** Function btif_av_get_sm_handle
1099 ** Description Fetches current av SM handle
1103 *******************************************************************************/
1105 btif_sm_handle_t btif_av_get_sm_handle(void)
1107 return btif_av_cb.sm_handle;
1110 /*******************************************************************************
1112 ** Function btif_av_stream_ready
1114 ** Description Checks whether AV is ready for starting a stream
1118 *******************************************************************************/
1120 BOOLEAN btif_av_stream_ready(void)
1122 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1124 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1125 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1127 /* also make sure main adapter is enabled */
1128 if (btif_is_enabled() == 0)
1130 BTIF_TRACE_EVENT("main adapter not enabled");
1134 /* check if we are remotely suspended or stop is pending */
1135 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1138 return (state == BTIF_AV_STATE_OPENED);
1141 /*******************************************************************************
1143 ** Function btif_av_stream_started_ready
1145 ** Description Checks whether AV ready for media start in streaming state
1149 *******************************************************************************/
1151 BOOLEAN btif_av_stream_started_ready(void)
1153 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1155 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1156 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1158 /* disallow media task to start if we have pending actions */
1159 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1160 | BTIF_AV_FLAG_PENDING_STOP))
1163 return (state == BTIF_AV_STATE_STARTED);
1166 /*******************************************************************************
1168 ** Function btif_dispatch_sm_event
1170 ** Description Send event to AV statemachine
1174 *******************************************************************************/
1176 /* used to pass events to AV statemachine from other tasks */
1177 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1179 /* Switch to BTIF context */
1180 btif_transfer_context(btif_av_handle_event, event,
1181 (char*)p_data, len, NULL);
1184 /*******************************************************************************
1186 ** Function btif_av_execute_service
1188 ** Description Initializes/Shuts down the service
1190 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1192 *******************************************************************************/
1193 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1197 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1198 * handle this request in order to allow incoming connections to succeed.
1199 * We need to put this back once support for this is added */
1201 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1202 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1203 * be initiated by the app/audioflinger layers */
1204 #if (AVRC_METADATA_INCLUDED == TRUE)
1205 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1206 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1207 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1209 |BTA_AV_FEAT_ADV_CTRL
1213 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1216 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1219 BTA_AvDeregister(btif_av_cb.bta_handle);
1222 return BT_STATUS_SUCCESS;
1225 /*******************************************************************************
1227 ** Function btif_av_sink_execute_service
1229 ** Description Initializes/Shuts down the service
1231 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1233 *******************************************************************************/
1234 bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
1236 #if (BTA_AV_SINK_INCLUDED == TRUE)
1237 BTA_AvEnable_Sink(b_enable);
1239 return BT_STATUS_SUCCESS;
1242 /*******************************************************************************
1244 ** Function btif_av_get_src_interface
1246 ** Description Get the AV callback interface for A2DP source profile
1248 ** Returns btav_interface_t
1250 *******************************************************************************/
1251 const btav_interface_t *btif_av_get_src_interface(void)
1253 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1254 return &bt_av_src_interface;
1257 /*******************************************************************************
1259 ** Function btif_av_get_sink_interface
1261 ** Description Get the AV callback interface for A2DP sink profile
1263 ** Returns btav_interface_t
1265 *******************************************************************************/
1266 const btav_interface_t *btif_av_get_sink_interface(void)
1268 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1269 return &bt_av_sink_interface;
1272 /*******************************************************************************
1274 ** Function btif_av_is_connected
1276 ** Description Checks if av has a connected sink
1280 *******************************************************************************/
1281 BOOLEAN btif_av_is_connected(void)
1283 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1284 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1287 /*******************************************************************************
1289 ** Function btif_av_is_peer_edr
1291 ** Description Check if the connected a2dp device supports
1292 ** EDR or not. Only when connected this function
1293 ** will accurately provide a true capability of
1294 ** remote peer. If not connected it will always be false.
1296 ** Returns TRUE if remote device is capable of EDR
1298 *******************************************************************************/
1299 BOOLEAN btif_av_is_peer_edr(void)
1301 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);