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>
30 #include "hardware/bt_av.h"
32 #define LOG_TAG "BTIF_AV"
35 #include "btif_util.h"
36 #include "btif_profile_queue.h"
38 #include "btif_media.h"
39 #include "bta_av_api.h"
44 /*****************************************************************************
46 ******************************************************************************/
47 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
49 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
52 BTIF_AV_STATE_IDLE = 0x0,
53 BTIF_AV_STATE_OPENING,
55 BTIF_AV_STATE_STARTED,
59 /* Should not need dedicated suspend state as actual actions are no
60 different than open state. Suspend flags are needed however to prevent
61 media task from trying to restart stream during remote suspend or while
62 we are in the process of a local suspend */
64 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
65 #define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
66 #define BTIF_AV_FLAG_PENDING_START 0x4
67 #define BTIF_AV_FLAG_PENDING_STOP 0x8
69 /*****************************************************************************
70 ** Local type definitions
71 ******************************************************************************/
75 tBTA_AV_HNDL bta_handle;
77 btif_sm_handle_t sm_handle;
80 UINT8 peer_sep; /* sep type of peer device */
85 bt_bdaddr_t *target_bda;
87 } btif_av_connect_req_t;
93 } btif_av_sink_config_req_t;
95 /*****************************************************************************
97 ******************************************************************************/
98 static btav_callbacks_t *bt_av_src_callbacks = NULL;
99 static btav_callbacks_t *bt_av_sink_callbacks = NULL;
100 static btif_av_cb_t btif_av_cb;
101 static TIMER_LIST_ENT tle_av_open_on_rc;
103 /* both interface and media task needs to be ready to alloc incoming request */
104 #define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
105 || (btif_av_cb.sm_handle == NULL))\
107 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
108 return BT_STATUS_NOT_READY;\
112 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
115 /* Helper macro to avoid code duplication in the state machine handlers */
116 #define CHECK_RC_EVENT(e, d) \
117 case BTA_AV_RC_OPEN_EVT: \
118 case BTA_AV_RC_CLOSE_EVT: \
119 case BTA_AV_REMOTE_CMD_EVT: \
120 case BTA_AV_VENDOR_CMD_EVT: \
121 case BTA_AV_META_MSG_EVT: \
122 case BTA_AV_RC_FEAT_EVT: \
124 btif_rc_handler(e, d);\
127 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
128 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
129 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
130 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
131 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
133 static const btif_sm_handler_t btif_av_state_handlers[] =
135 btif_av_state_idle_handler,
136 btif_av_state_opening_handler,
137 btif_av_state_opened_handler,
138 btif_av_state_started_handler,
139 btif_av_state_closing_handler
142 /*************************************************************************
144 *************************************************************************/
145 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
146 extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
147 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
149 /*****************************************************************************
150 ** Local helper functions
151 ******************************************************************************/
153 const char *dump_av_sm_state_name(btif_av_state_t state)
157 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
158 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
159 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
160 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
161 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
162 default: return "UNKNOWN_STATE";
166 const char *dump_av_sm_event_name(btif_av_sm_event_t event)
170 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
171 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
172 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
173 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
174 CASE_RETURN_STR(BTA_AV_START_EVT)
175 CASE_RETURN_STR(BTA_AV_STOP_EVT)
176 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
177 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
178 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
179 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
180 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
181 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
182 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
183 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
184 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
185 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
186 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
187 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
188 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
189 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
190 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
191 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
192 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
193 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
194 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
195 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
196 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
197 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
198 default: return "UNKNOWN_EVENT";
202 /****************************************************************************
203 ** Local helper functions
204 *****************************************************************************/
205 /*******************************************************************************
207 ** Function btif_initiate_av_open_tmr_hdlr
209 ** Description Timer to trigger AV open if the remote headset establishes
210 ** RC connection w/o AV connection. The timer is needed to IOP
211 ** with headsets that do establish AV after RC connection.
215 *******************************************************************************/
216 static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
220 btif_av_connect_req_t connect_req;
222 /* is there at least one RC connection - There should be */
223 if (btif_rc_get_connected_peer(peer_addr)) {
224 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
225 /* In case of AVRCP connection request, we will initiate SRC connection */
226 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
227 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
228 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
232 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
236 /*****************************************************************************
238 ******************************************************************************/
240 static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
242 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
243 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
244 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
245 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
249 static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
251 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
252 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
253 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) {
254 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
258 /*****************************************************************************
260 ** Function btif_av_state_idle_handler
262 ** Description State managing disconnected AV link
264 ** Returns TRUE if event was processed, FALSE otherwise
266 *******************************************************************************/
268 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
270 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
271 dump_av_sm_event_name(event), btif_av_cb.flags);
275 case BTIF_SM_ENTER_EVT:
276 /* clear the peer_bda */
277 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
278 btif_av_cb.flags = 0;
283 case BTIF_SM_EXIT_EVT:
286 case BTA_AV_ENABLE_EVT:
289 case BTA_AV_REGISTER_EVT:
290 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
293 case BTA_AV_PENDING_EVT:
294 case BTIF_AV_CONNECT_REQ_EVT:
296 if (event == BTIF_AV_CONNECT_REQ_EVT)
298 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
299 sizeof(bt_bdaddr_t));
300 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
301 TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid);
303 else if (event == BTA_AV_PENDING_EVT)
305 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
306 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
307 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE);
309 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
312 case BTA_AV_RC_OPEN_EVT:
313 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
314 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
315 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
316 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
317 * headsets, as some headsets initiate the AVRC connection first and then
318 * immediately initiate the AV connection
320 * TODO: We may need to do this only on an AVRCP Play. FixMe
323 BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
324 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
325 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
326 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
327 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
328 btif_rc_handler(event, p_data);
331 case BTA_AV_REMOTE_CMD_EVT:
332 case BTA_AV_VENDOR_CMD_EVT:
333 case BTA_AV_META_MSG_EVT:
334 case BTA_AV_RC_FEAT_EVT:
335 btif_rc_handler(event, (tBTA_AV*)p_data);
338 case BTA_AV_RC_CLOSE_EVT:
339 if (tle_av_open_on_rc.in_use) {
340 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
341 btu_stop_timer(&tle_av_open_on_rc);
343 btif_rc_handler(event, p_data);
347 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
348 dump_av_sm_event_name(event));
354 /*****************************************************************************
356 ** Function btif_av_state_opening_handler
358 ** Description Intermediate state managing events during establishment
361 ** Returns TRUE if event was processed, FALSE otherwise
363 *******************************************************************************/
365 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
367 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
368 dump_av_sm_event_name(event), btif_av_cb.flags);
372 case BTIF_SM_ENTER_EVT:
373 /* inform the application that we are entering connecting state */
374 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
377 case BTIF_SM_EXIT_EVT:
380 case BTA_AV_REJECT_EVT:
381 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
382 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
383 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
386 case BTA_AV_OPEN_EVT:
388 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
389 btav_connection_state_t state;
390 btif_sm_state_t av_state;
391 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
392 p_bta_data->open.edr);
394 if (p_bta_data->open.status == BTA_AV_SUCCESS)
396 state = BTAV_CONNECTION_STATE_CONNECTED;
397 av_state = BTIF_AV_STATE_OPENED;
398 btif_av_cb.edr = p_bta_data->open.edr;
400 btif_av_cb.peer_sep = p_bta_data->open.sep;
401 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
405 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
406 p_bta_data->open.status );
407 state = BTAV_CONNECTION_STATE_DISCONNECTED;
408 av_state = BTIF_AV_STATE_IDLE;
411 /* inform the application of the event */
412 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
413 /* change state to open/idle based on the status */
414 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
415 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
417 /* if queued PLAY command, send it now */
418 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
419 (p_bta_data->open.status == BTA_AV_SUCCESS));
421 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
423 /* if queued PLAY command, send it now */
424 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
425 /* Bring up AVRCP connection too */
426 BTA_AvOpenRc(btif_av_cb.bta_handle);
428 btif_queue_advance();
431 case BTIF_AV_SINK_CONFIG_REQ_EVT:
433 btif_av_sink_config_req_t req;
434 // copy to avoid alignment problems
435 memcpy(&req, p_data, sizeof(req));
437 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
439 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
440 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
441 req.sample_rate, req.channel_count);
445 CHECK_RC_EVENT(event, p_data);
448 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
449 dump_av_sm_event_name(event));
457 /*****************************************************************************
459 ** Function btif_av_state_closing_handler
461 ** Description Intermediate state managing events during closing
464 ** Returns TRUE if event was processed, FALSE otherwise
466 *******************************************************************************/
468 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
470 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
471 dump_av_sm_event_name(event), btif_av_cb.flags);
475 case BTIF_SM_ENTER_EVT:
476 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
478 /* immediately stop transmission of frames */
479 btif_a2dp_set_tx_flush(TRUE);
480 /* wait for audioflinger to stop a2dp */
482 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
484 btif_a2dp_set_rx_flush(TRUE);
488 case BTA_AV_STOP_EVT:
489 case BTIF_AV_STOP_STREAM_REQ_EVT:
490 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
492 /* immediately flush any pending tx frames while suspend is pending */
493 btif_a2dp_set_tx_flush(TRUE);
495 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
497 btif_a2dp_set_rx_flush(TRUE);
500 btif_a2dp_on_stopped(NULL);
503 case BTIF_SM_EXIT_EVT:
506 case BTA_AV_CLOSE_EVT:
508 /* inform the application that we are disconnecting */
509 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
511 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
514 /* Handle the RC_CLOSE event for the cleanup */
515 case BTA_AV_RC_CLOSE_EVT:
516 btif_rc_handler(event, (tBTA_AV*)p_data);
520 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
521 dump_av_sm_event_name(event));
528 /*****************************************************************************
530 ** Function btif_av_state_opened_handler
532 ** Description Handles AV events while AVDTP is in OPEN state
534 ** Returns TRUE if event was processed, FALSE otherwise
536 *******************************************************************************/
538 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
540 tBTA_AV *p_av = (tBTA_AV*)p_data;
542 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
543 dump_av_sm_event_name(event), btif_av_cb.flags);
545 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
546 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
548 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
549 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
554 case BTIF_SM_ENTER_EVT:
555 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
556 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
559 case BTIF_SM_EXIT_EVT:
560 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
563 case BTIF_AV_START_STREAM_REQ_EVT:
564 if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
565 btif_a2dp_setup_codec();
567 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
570 case BTA_AV_START_EVT:
572 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
573 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
575 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
578 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
579 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
581 if (btif_a2dp_on_started(&p_av->start,
582 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
584 /* only clear pending flag after acknowledgement */
585 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
589 /* remain in open state if status failed */
590 if (p_av->start.status != BTA_AV_SUCCESS)
593 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
595 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
598 /* change state to started, send acknowledgement if start is pending */
599 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
600 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
601 btif_a2dp_on_started(NULL, TRUE);
602 /* pending start flag will be cleared when exit current state */
604 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
608 case BTIF_AV_DISCONNECT_REQ_EVT:
609 BTA_AvClose(btif_av_cb.bta_handle);
610 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
611 BTA_AvCloseRc(btif_av_cb.bta_handle);
614 /* inform the application that we are disconnecting */
615 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
618 case BTA_AV_CLOSE_EVT:
619 /* avdtp link is closed */
620 btif_a2dp_on_stopped(NULL);
622 /* inform the application that we are disconnected */
623 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
625 /* change state to idle, send acknowledgement if start is pending */
626 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
627 btif_a2dp_ack_fail();
628 /* pending start flag will be cleared when exit current state */
630 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
633 case BTA_AV_RECONFIG_EVT:
634 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
635 (p_av->reconfig.status == BTA_AV_SUCCESS))
637 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
640 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
642 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
643 btif_a2dp_ack_fail();
647 CHECK_RC_EVENT(event, p_data);
650 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
651 dump_av_sm_event_name(event));
658 /*****************************************************************************
660 ** Function btif_av_state_started_handler
662 ** Description Handles AV events while A2DP stream is started
664 ** Returns TRUE if event was processed, FALSE otherwise
666 *******************************************************************************/
668 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
670 tBTA_AV *p_av = (tBTA_AV*)p_data;
672 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
673 dump_av_sm_event_name(event), btif_av_cb.flags);
677 case BTIF_SM_ENTER_EVT:
679 /* we are again in started state, clear any remote suspend flags */
680 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
682 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
684 /* increase the a2dp consumer task priority temporarily when start
685 ** audio playing, to avoid overflow the audio packet queue. */
686 adjust_priority_a2dp(TRUE);
690 case BTIF_SM_EXIT_EVT:
691 /* restore the a2dp consumer task priority when stop audio playing. */
692 adjust_priority_a2dp(FALSE);
696 case BTIF_AV_START_STREAM_REQ_EVT:
697 /* we were remotely started, just ack back the local request */
698 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
699 btif_a2dp_on_started(NULL, TRUE);
702 /* fixme -- use suspend = true always to work around issue with BTA AV */
703 case BTIF_AV_STOP_STREAM_REQ_EVT:
704 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
706 /* set pending flag to ensure btif task is not trying to restart
707 stream while suspend is in progress */
708 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
710 /* if we were remotely suspended but suspend locally, local suspend
712 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
714 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
716 /* immediately stop transmission of frames while suspend is pending */
717 btif_a2dp_set_tx_flush(TRUE);
720 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
721 btif_a2dp_set_rx_flush(TRUE);
722 btif_a2dp_on_stopped(NULL);
728 case BTIF_AV_DISCONNECT_REQ_EVT:
730 /* request avdtp to close */
731 BTA_AvClose(btif_av_cb.bta_handle);
732 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
733 BTA_AvCloseRc(btif_av_cb.bta_handle);
736 /* inform the application that we are disconnecting */
737 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
739 /* wait in closing state until fully closed */
740 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
743 case BTA_AV_SUSPEND_EVT:
745 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
746 p_av->suspend.status, p_av->suspend.initiator);
748 /* a2dp suspended, stop media task until resumed */
749 btif_a2dp_on_suspended(&p_av->suspend);
751 /* if not successful, remain in current state */
752 if (p_av->suspend.status != BTA_AV_SUCCESS)
754 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
756 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
758 /* suspend failed, reset back tx flush state */
759 btif_a2dp_set_tx_flush(FALSE);
764 if (p_av->suspend.initiator != TRUE)
766 /* remote suspend, notify HAL and await audioflinger to
767 suspend/stop stream */
769 /* set remote suspend flag to block media task from restarting
770 stream only if we did not already initiate a local suspend */
771 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
772 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
774 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
778 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
781 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
783 /* suspend completed and state changed, clear pending status */
784 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
787 case BTA_AV_STOP_EVT:
789 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
790 btif_a2dp_on_stopped(&p_av->suspend);
792 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
794 /* if stop was successful, change state to open */
795 if (p_av->suspend.status == BTA_AV_SUCCESS)
796 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
800 case BTA_AV_CLOSE_EVT:
802 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
804 /* avdtp link is closed */
805 btif_a2dp_on_stopped(NULL);
807 /* inform the application that we are disconnected */
808 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
810 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
813 CHECK_RC_EVENT(event, p_data);
816 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
817 dump_av_sm_event_name(event));
824 /*****************************************************************************
825 ** Local event handlers
826 ******************************************************************************/
828 static void btif_av_handle_event(UINT16 event, char* p_param)
830 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
833 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
835 /* Switch to BTIF context */
836 btif_transfer_context(btif_av_handle_event, event,
837 (char*)p_data, sizeof(tBTA_AV), NULL);
840 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
842 btif_sm_state_t state;
844 tA2D_STATUS a2d_status;
845 tA2D_SBC_CIE sbc_cie;
846 btif_av_sink_config_req_t config_req;
848 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
850 state= btif_sm_get_state(btif_av_cb.sm_handle);
851 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
852 (state == BTIF_AV_STATE_OPENED) )
854 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
855 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
861 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
862 /* send a command to BT Media Task */
863 btif_reset_decoder((UINT8*)p_data);
865 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
866 if (a2d_status == A2D_SUCCESS) {
867 /* Switch to BTIF context */
868 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
869 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
870 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
871 (char*)&config_req, sizeof(config_req), NULL);
873 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
877 /*******************************************************************************
879 ** Function btif_av_init
881 ** Description Initializes btif AV if not already done
883 ** Returns bt_status_t
885 *******************************************************************************/
887 bt_status_t btif_av_init()
889 if (btif_av_cb.sm_handle == NULL)
891 if (btif_a2dp_start_media_task() != GKI_SUCCESS)
892 return BT_STATUS_FAIL;
894 btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
896 /* Also initialize the AV state machine */
897 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
901 return BT_STATUS_SUCCESS;
904 return BT_STATUS_DONE;
907 /*******************************************************************************
911 ** Description Initializes the AV interface for source mode
913 ** Returns bt_status_t
915 *******************************************************************************/
917 static bt_status_t init_src(btav_callbacks_t* callbacks)
921 BTIF_TRACE_EVENT("%s", __FUNCTION__);
923 if (bt_av_sink_callbacks != NULL) {
924 // already did btif_av_init()
925 status = BT_STATUS_SUCCESS;
927 status = btif_av_init();
930 if (status == BT_STATUS_SUCCESS) {
931 bt_av_src_callbacks = callbacks;
937 /*******************************************************************************
939 ** Function init_sink
941 ** Description Initializes the AV interface for sink mode
943 ** Returns bt_status_t
945 *******************************************************************************/
947 static bt_status_t init_sink(btav_callbacks_t* callbacks)
951 BTIF_TRACE_EVENT("%s", __FUNCTION__);
953 if (bt_av_src_callbacks != NULL) {
954 // already did btif_av_init()
955 status = BT_STATUS_SUCCESS;
957 status = btif_av_init();
960 if (status == BT_STATUS_SUCCESS) {
961 bt_av_sink_callbacks = callbacks;
962 BTA_AvEnable_Sink(TRUE);
968 /*******************************************************************************
972 ** Description Establishes the AV signalling channel with the remote headset
974 ** Returns bt_status_t
976 *******************************************************************************/
978 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
980 btif_av_connect_req_t connect_req;
981 connect_req.target_bda = bd_addr;
982 connect_req.uuid = uuid;
983 BTIF_TRACE_EVENT("%s", __FUNCTION__);
985 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
987 return BT_STATUS_SUCCESS;
990 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
992 BTIF_TRACE_EVENT("%s", __FUNCTION__);
995 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
998 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1000 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1003 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1006 /*******************************************************************************
1008 ** Function disconnect
1010 ** Description Tears down the AV signalling channel with the remote headset
1012 ** Returns bt_status_t
1014 *******************************************************************************/
1015 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1017 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1021 /* Switch to BTIF context */
1022 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1023 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1026 /*******************************************************************************
1030 ** Description Shuts down the AV interface and does the cleanup
1034 *******************************************************************************/
1035 static void cleanup(void)
1037 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1039 btif_a2dp_stop_media_task();
1041 btif_disable_service(BTA_A2DP_SERVICE_ID);
1043 /* Also shut down the AV state machine */
1044 btif_sm_shutdown(btif_av_cb.sm_handle);
1045 btif_av_cb.sm_handle = NULL;
1048 static void cleanup_src(void) {
1049 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1051 if (bt_av_src_callbacks)
1053 bt_av_src_callbacks = NULL;
1054 if (bt_av_sink_callbacks == NULL)
1059 static void cleanup_sink(void) {
1060 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1062 if (bt_av_sink_callbacks)
1064 bt_av_sink_callbacks = NULL;
1065 if (bt_av_src_callbacks == NULL)
1070 static const btav_interface_t bt_av_src_interface = {
1071 sizeof(btav_interface_t),
1078 static const btav_interface_t bt_av_sink_interface = {
1079 sizeof(btav_interface_t),
1086 /*******************************************************************************
1088 ** Function btif_av_get_sm_handle
1090 ** Description Fetches current av SM handle
1094 *******************************************************************************/
1096 btif_sm_handle_t btif_av_get_sm_handle(void)
1098 return btif_av_cb.sm_handle;
1101 /*******************************************************************************
1103 ** Function btif_av_stream_ready
1105 ** Description Checks whether AV is ready for starting a stream
1109 *******************************************************************************/
1111 BOOLEAN btif_av_stream_ready(void)
1113 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1115 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1116 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1118 /* also make sure main adapter is enabled */
1119 if (btif_is_enabled() == 0)
1121 BTIF_TRACE_EVENT("main adapter not enabled");
1125 /* check if we are remotely suspended or stop is pending */
1126 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1129 return (state == BTIF_AV_STATE_OPENED);
1132 /*******************************************************************************
1134 ** Function btif_av_stream_started_ready
1136 ** Description Checks whether AV ready for media start in streaming state
1140 *******************************************************************************/
1142 BOOLEAN btif_av_stream_started_ready(void)
1144 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1146 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1147 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1149 /* disallow media task to start if we have pending actions */
1150 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1151 | BTIF_AV_FLAG_PENDING_STOP))
1154 return (state == BTIF_AV_STATE_STARTED);
1157 /*******************************************************************************
1159 ** Function btif_dispatch_sm_event
1161 ** Description Send event to AV statemachine
1165 *******************************************************************************/
1167 /* used to pass events to AV statemachine from other tasks */
1168 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1170 /* Switch to BTIF context */
1171 btif_transfer_context(btif_av_handle_event, event,
1172 (char*)p_data, len, NULL);
1175 /*******************************************************************************
1177 ** Function btif_av_execute_service
1179 ** Description Initializes/Shuts down the service
1181 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1183 *******************************************************************************/
1184 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1188 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1189 * handle this request in order to allow incoming connections to succeed.
1190 * We need to put this back once support for this is added */
1192 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1193 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1194 * be initiated by the app/audioflinger layers */
1195 #if (AVRC_METADATA_INCLUDED == TRUE)
1196 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1197 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1198 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1200 |BTA_AV_FEAT_ADV_CTRL
1204 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1207 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1210 BTA_AvDeregister(btif_av_cb.bta_handle);
1213 return BT_STATUS_SUCCESS;
1216 /*******************************************************************************
1218 ** Function btif_av_get_src_interface
1220 ** Description Get the AV callback interface for A2DP source profile
1222 ** Returns btav_interface_t
1224 *******************************************************************************/
1225 const btav_interface_t *btif_av_get_src_interface(void)
1227 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1228 return &bt_av_src_interface;
1231 /*******************************************************************************
1233 ** Function btif_av_get_sink_interface
1235 ** Description Get the AV callback interface for A2DP sink profile
1237 ** Returns btav_interface_t
1239 *******************************************************************************/
1240 const btav_interface_t *btif_av_get_sink_interface(void)
1242 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1243 return &bt_av_sink_interface;
1246 /*******************************************************************************
1248 ** Function btif_av_is_connected
1250 ** Description Checks if av has a connected sink
1254 *******************************************************************************/
1255 BOOLEAN btif_av_is_connected(void)
1257 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1258 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1261 /*******************************************************************************
1263 ** Function btif_av_is_peer_edr
1265 ** Description Check if the connected a2dp device supports
1266 ** EDR or not. Only when connected this function
1267 ** will accurately provide a true capability of
1268 ** remote peer. If not connected it will always be false.
1270 ** Returns TRUE if remote device is capable of EDR
1272 *******************************************************************************/
1273 BOOLEAN btif_av_is_peer_edr(void)
1275 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);