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 "BTIF_AV"
36 #include "btif_util.h"
37 #include "btif_profile_queue.h"
39 #include "btif_media.h"
40 #include "bta_av_api.h"
46 /*****************************************************************************
48 ******************************************************************************/
49 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
51 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2
54 BTIF_AV_STATE_IDLE = 0x0,
55 BTIF_AV_STATE_OPENING,
57 BTIF_AV_STATE_STARTED,
61 /* Should not need dedicated suspend state as actual actions are no
62 different than open state. Suspend flags are needed however to prevent
63 media task from trying to restart stream during remote suspend or while
64 we are in the process of a local suspend */
66 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
67 #define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
68 #define BTIF_AV_FLAG_PENDING_START 0x4
69 #define BTIF_AV_FLAG_PENDING_STOP 0x8
71 /*****************************************************************************
72 ** Local type definitions
73 ******************************************************************************/
77 tBTA_AV_HNDL bta_handle;
79 btif_sm_handle_t sm_handle;
82 UINT8 peer_sep; /* sep type of peer device */
87 bt_bdaddr_t *target_bda;
89 } btif_av_connect_req_t;
95 } btif_av_sink_config_req_t;
97 /*****************************************************************************
99 ******************************************************************************/
100 static btav_callbacks_t *bt_av_src_callbacks = NULL;
101 static btav_callbacks_t *bt_av_sink_callbacks = NULL;
102 static btif_av_cb_t btif_av_cb;
103 static TIMER_LIST_ENT tle_av_open_on_rc;
105 /* both interface and media task needs to be ready to alloc incoming request */
106 #define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
107 || (btif_av_cb.sm_handle == NULL))\
109 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
110 return BT_STATUS_NOT_READY;\
114 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
117 /* Helper macro to avoid code duplication in the state machine handlers */
118 #define CHECK_RC_EVENT(e, d) \
119 case BTA_AV_RC_OPEN_EVT: \
120 case BTA_AV_RC_CLOSE_EVT: \
121 case BTA_AV_REMOTE_CMD_EVT: \
122 case BTA_AV_VENDOR_CMD_EVT: \
123 case BTA_AV_META_MSG_EVT: \
124 case BTA_AV_RC_FEAT_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 btif_rc_handler(event, (tBTA_AV*)p_data);
340 case BTA_AV_RC_CLOSE_EVT:
341 if (tle_av_open_on_rc.in_use) {
342 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
343 btu_stop_timer(&tle_av_open_on_rc);
345 btif_rc_handler(event, p_data);
349 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
350 dump_av_sm_event_name(event));
356 /*****************************************************************************
358 ** Function btif_av_state_opening_handler
360 ** Description Intermediate state managing events during establishment
363 ** Returns TRUE if event was processed, FALSE otherwise
365 *******************************************************************************/
367 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
369 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
370 dump_av_sm_event_name(event), btif_av_cb.flags);
374 case BTIF_SM_ENTER_EVT:
375 /* inform the application that we are entering connecting state */
376 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
379 case BTIF_SM_EXIT_EVT:
382 case BTA_AV_REJECT_EVT:
383 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
384 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
385 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
388 case BTA_AV_OPEN_EVT:
390 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
391 btav_connection_state_t state;
392 btif_sm_state_t av_state;
393 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
394 p_bta_data->open.edr);
396 if (p_bta_data->open.status == BTA_AV_SUCCESS)
398 state = BTAV_CONNECTION_STATE_CONNECTED;
399 av_state = BTIF_AV_STATE_OPENED;
400 btif_av_cb.edr = p_bta_data->open.edr;
402 btif_av_cb.peer_sep = p_bta_data->open.sep;
403 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
407 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
408 p_bta_data->open.status );
409 state = BTAV_CONNECTION_STATE_DISCONNECTED;
410 av_state = BTIF_AV_STATE_IDLE;
413 /* inform the application of the event */
414 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
415 /* change state to open/idle based on the status */
416 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
417 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
419 /* if queued PLAY command, send it now */
420 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
421 (p_bta_data->open.status == BTA_AV_SUCCESS));
423 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
425 /* if queued PLAY command, send it now */
426 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
427 /* Bring up AVRCP connection too */
428 BTA_AvOpenRc(btif_av_cb.bta_handle);
430 btif_queue_advance();
433 case BTIF_AV_SINK_CONFIG_REQ_EVT:
435 btif_av_sink_config_req_t req;
436 // copy to avoid alignment problems
437 memcpy(&req, p_data, sizeof(req));
439 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
441 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
442 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
443 req.sample_rate, req.channel_count);
447 CHECK_RC_EVENT(event, p_data);
450 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
451 dump_av_sm_event_name(event));
459 /*****************************************************************************
461 ** Function btif_av_state_closing_handler
463 ** Description Intermediate state managing events during closing
466 ** Returns TRUE if event was processed, FALSE otherwise
468 *******************************************************************************/
470 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
472 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
473 dump_av_sm_event_name(event), btif_av_cb.flags);
477 case BTIF_SM_ENTER_EVT:
478 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
480 /* immediately stop transmission of frames */
481 btif_a2dp_set_tx_flush(TRUE);
482 /* wait for audioflinger to stop a2dp */
484 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
486 btif_a2dp_set_rx_flush(TRUE);
490 case BTA_AV_STOP_EVT:
491 case BTIF_AV_STOP_STREAM_REQ_EVT:
492 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
494 /* immediately flush any pending tx frames while suspend is pending */
495 btif_a2dp_set_tx_flush(TRUE);
497 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
499 btif_a2dp_set_rx_flush(TRUE);
502 btif_a2dp_on_stopped(NULL);
505 case BTIF_SM_EXIT_EVT:
508 case BTA_AV_CLOSE_EVT:
510 /* inform the application that we are disconnecting */
511 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
513 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
516 /* Handle the RC_CLOSE event for the cleanup */
517 case BTA_AV_RC_CLOSE_EVT:
518 btif_rc_handler(event, (tBTA_AV*)p_data);
522 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
523 dump_av_sm_event_name(event));
530 /*****************************************************************************
532 ** Function btif_av_state_opened_handler
534 ** Description Handles AV events while AVDTP is in OPEN state
536 ** Returns TRUE if event was processed, FALSE otherwise
538 *******************************************************************************/
540 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
542 tBTA_AV *p_av = (tBTA_AV*)p_data;
544 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
545 dump_av_sm_event_name(event), btif_av_cb.flags);
547 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
548 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
550 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
551 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
556 case BTIF_SM_ENTER_EVT:
557 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
558 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
561 case BTIF_SM_EXIT_EVT:
562 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
565 case BTIF_AV_START_STREAM_REQ_EVT:
566 if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
567 btif_a2dp_setup_codec();
569 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
572 case BTA_AV_START_EVT:
574 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
575 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
577 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
580 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
581 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
583 if (btif_a2dp_on_started(&p_av->start,
584 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
586 /* only clear pending flag after acknowledgement */
587 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
591 /* remain in open state if status failed */
592 if (p_av->start.status != BTA_AV_SUCCESS)
595 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
597 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
600 /* change state to started, send acknowledgement if start is pending */
601 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
602 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
603 btif_a2dp_on_started(NULL, TRUE);
604 /* pending start flag will be cleared when exit current state */
606 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
610 case BTIF_AV_DISCONNECT_REQ_EVT:
611 BTA_AvClose(btif_av_cb.bta_handle);
612 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
613 BTA_AvCloseRc(btif_av_cb.bta_handle);
616 /* inform the application that we are disconnecting */
617 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
620 case BTA_AV_CLOSE_EVT:
621 /* avdtp link is closed */
622 btif_a2dp_on_stopped(NULL);
624 /* inform the application that we are disconnected */
625 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
627 /* change state to idle, send acknowledgement if start is pending */
628 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
629 btif_a2dp_ack_fail();
630 /* pending start flag will be cleared when exit current state */
632 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
635 case BTA_AV_RECONFIG_EVT:
636 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
637 (p_av->reconfig.status == BTA_AV_SUCCESS))
639 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
642 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
644 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
645 btif_a2dp_ack_fail();
649 CHECK_RC_EVENT(event, p_data);
652 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
653 dump_av_sm_event_name(event));
660 /*****************************************************************************
662 ** Function btif_av_state_started_handler
664 ** Description Handles AV events while A2DP stream is started
666 ** Returns TRUE if event was processed, FALSE otherwise
668 *******************************************************************************/
670 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
672 tBTA_AV *p_av = (tBTA_AV*)p_data;
674 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
675 dump_av_sm_event_name(event), btif_av_cb.flags);
679 case BTIF_SM_ENTER_EVT:
681 /* we are again in started state, clear any remote suspend flags */
682 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
684 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
686 /* increase the a2dp consumer task priority temporarily when start
687 ** audio playing, to avoid overflow the audio packet queue. */
688 adjust_priority_a2dp(TRUE);
692 case BTIF_SM_EXIT_EVT:
693 /* restore the a2dp consumer task priority when stop audio playing. */
694 adjust_priority_a2dp(FALSE);
698 case BTIF_AV_START_STREAM_REQ_EVT:
699 /* we were remotely started, just ack back the local request */
700 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
701 btif_a2dp_on_started(NULL, TRUE);
704 /* fixme -- use suspend = true always to work around issue with BTA AV */
705 case BTIF_AV_STOP_STREAM_REQ_EVT:
706 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
708 /* set pending flag to ensure btif task is not trying to restart
709 stream while suspend is in progress */
710 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
712 /* if we were remotely suspended but suspend locally, local suspend
714 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
716 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
718 /* immediately stop transmission of frames while suspend is pending */
719 btif_a2dp_set_tx_flush(TRUE);
722 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
723 btif_a2dp_set_rx_flush(TRUE);
724 btif_a2dp_on_stopped(NULL);
730 case BTIF_AV_DISCONNECT_REQ_EVT:
732 /* request avdtp to close */
733 BTA_AvClose(btif_av_cb.bta_handle);
734 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
735 BTA_AvCloseRc(btif_av_cb.bta_handle);
738 /* inform the application that we are disconnecting */
739 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
741 /* wait in closing state until fully closed */
742 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
745 case BTA_AV_SUSPEND_EVT:
747 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
748 p_av->suspend.status, p_av->suspend.initiator);
750 /* a2dp suspended, stop media task until resumed */
751 btif_a2dp_on_suspended(&p_av->suspend);
753 /* if not successful, remain in current state */
754 if (p_av->suspend.status != BTA_AV_SUCCESS)
756 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
758 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
760 /* suspend failed, reset back tx flush state */
761 btif_a2dp_set_tx_flush(FALSE);
766 if (p_av->suspend.initiator != TRUE)
768 /* remote suspend, notify HAL and await audioflinger to
769 suspend/stop stream */
771 /* set remote suspend flag to block media task from restarting
772 stream only if we did not already initiate a local suspend */
773 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
774 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
776 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
780 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
783 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
785 /* suspend completed and state changed, clear pending status */
786 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
789 case BTA_AV_STOP_EVT:
791 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
792 btif_a2dp_on_stopped(&p_av->suspend);
794 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
796 /* if stop was successful, change state to open */
797 if (p_av->suspend.status == BTA_AV_SUCCESS)
798 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
802 case BTA_AV_CLOSE_EVT:
804 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
806 /* avdtp link is closed */
807 btif_a2dp_on_stopped(NULL);
809 /* inform the application that we are disconnected */
810 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
812 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
815 CHECK_RC_EVENT(event, p_data);
818 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
819 dump_av_sm_event_name(event));
826 /*****************************************************************************
827 ** Local event handlers
828 ******************************************************************************/
830 static void btif_av_handle_event(UINT16 event, char* p_param)
832 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
835 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
837 /* Switch to BTIF context */
838 btif_transfer_context(btif_av_handle_event, event,
839 (char*)p_data, sizeof(tBTA_AV), NULL);
842 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
844 btif_sm_state_t state;
846 tA2D_STATUS a2d_status;
847 tA2D_SBC_CIE sbc_cie;
848 btif_av_sink_config_req_t config_req;
850 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
852 state= btif_sm_get_state(btif_av_cb.sm_handle);
853 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
854 (state == BTIF_AV_STATE_OPENED) )
856 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
857 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
863 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
864 /* send a command to BT Media Task */
865 btif_reset_decoder((UINT8*)p_data);
867 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
868 if (a2d_status == A2D_SUCCESS) {
869 /* Switch to BTIF context */
870 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
871 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
872 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
873 (char*)&config_req, sizeof(config_req), NULL);
875 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
879 /*******************************************************************************
881 ** Function btif_av_init
883 ** Description Initializes btif AV if not already done
885 ** Returns bt_status_t
887 *******************************************************************************/
889 bt_status_t btif_av_init()
891 if (btif_av_cb.sm_handle == NULL)
893 if (btif_a2dp_start_media_task() != GKI_SUCCESS)
894 return BT_STATUS_FAIL;
896 btif_enable_service(BTA_A2DP_SERVICE_ID);
898 /* Also initialize the AV state machine */
899 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
903 return BT_STATUS_SUCCESS;
906 return BT_STATUS_DONE;
909 /*******************************************************************************
913 ** Description Initializes the AV interface for source mode
915 ** Returns bt_status_t
917 *******************************************************************************/
919 static bt_status_t init_src(btav_callbacks_t* callbacks)
923 BTIF_TRACE_EVENT("%s", __FUNCTION__);
925 if (bt_av_sink_callbacks != NULL) {
926 // already did btif_av_init()
927 status = BT_STATUS_SUCCESS;
929 status = btif_av_init();
932 if (status == BT_STATUS_SUCCESS) {
933 bt_av_src_callbacks = callbacks;
939 /*******************************************************************************
941 ** Function init_sink
943 ** Description Initializes the AV interface for sink mode
945 ** Returns bt_status_t
947 *******************************************************************************/
949 static bt_status_t init_sink(btav_callbacks_t* callbacks)
953 BTIF_TRACE_EVENT("%s", __FUNCTION__);
955 if (bt_av_src_callbacks != NULL) {
956 // already did btif_av_init()
957 status = BT_STATUS_SUCCESS;
959 status = btif_av_init();
962 if (status == BT_STATUS_SUCCESS) {
963 bt_av_sink_callbacks = callbacks;
964 BTA_AvEnable_Sink(TRUE);
970 /*******************************************************************************
974 ** Description Establishes the AV signalling channel with the remote headset
976 ** Returns bt_status_t
978 *******************************************************************************/
980 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
982 btif_av_connect_req_t connect_req;
983 connect_req.target_bda = bd_addr;
984 connect_req.uuid = uuid;
985 BTIF_TRACE_EVENT("%s", __FUNCTION__);
987 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
989 return BT_STATUS_SUCCESS;
992 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
994 BTIF_TRACE_EVENT("%s", __FUNCTION__);
997 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1000 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1002 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1005 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1008 /*******************************************************************************
1010 ** Function disconnect
1012 ** Description Tears down the AV signalling channel with the remote headset
1014 ** Returns bt_status_t
1016 *******************************************************************************/
1017 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1019 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1023 /* Switch to BTIF context */
1024 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1025 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1028 /*******************************************************************************
1032 ** Description Shuts down the AV interface and does the cleanup
1036 *******************************************************************************/
1037 static void cleanup(void)
1039 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1041 btif_a2dp_stop_media_task();
1043 btif_disable_service(BTA_A2DP_SERVICE_ID);
1045 /* Also shut down the AV state machine */
1046 btif_sm_shutdown(btif_av_cb.sm_handle);
1047 btif_av_cb.sm_handle = NULL;
1050 static void cleanup_src(void) {
1051 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1053 if (bt_av_src_callbacks)
1055 bt_av_src_callbacks = NULL;
1056 if (bt_av_sink_callbacks == NULL)
1061 static void cleanup_sink(void) {
1062 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1064 if (bt_av_sink_callbacks)
1066 bt_av_sink_callbacks = NULL;
1067 if (bt_av_src_callbacks == NULL)
1072 static const btav_interface_t bt_av_src_interface = {
1073 sizeof(btav_interface_t),
1080 static const btav_interface_t bt_av_sink_interface = {
1081 sizeof(btav_interface_t),
1088 /*******************************************************************************
1090 ** Function btif_av_get_sm_handle
1092 ** Description Fetches current av SM handle
1096 *******************************************************************************/
1098 btif_sm_handle_t btif_av_get_sm_handle(void)
1100 return btif_av_cb.sm_handle;
1103 /*******************************************************************************
1105 ** Function btif_av_stream_ready
1107 ** Description Checks whether AV is ready for starting a stream
1111 *******************************************************************************/
1113 BOOLEAN btif_av_stream_ready(void)
1115 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1117 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1118 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1120 /* also make sure main adapter is enabled */
1121 if (btif_is_enabled() == 0)
1123 BTIF_TRACE_EVENT("main adapter not enabled");
1127 /* check if we are remotely suspended or stop is pending */
1128 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1131 return (state == BTIF_AV_STATE_OPENED);
1134 /*******************************************************************************
1136 ** Function btif_av_stream_started_ready
1138 ** Description Checks whether AV ready for media start in streaming state
1142 *******************************************************************************/
1144 BOOLEAN btif_av_stream_started_ready(void)
1146 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1148 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1149 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1151 /* disallow media task to start if we have pending actions */
1152 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1153 | BTIF_AV_FLAG_PENDING_STOP))
1156 return (state == BTIF_AV_STATE_STARTED);
1159 /*******************************************************************************
1161 ** Function btif_dispatch_sm_event
1163 ** Description Send event to AV statemachine
1167 *******************************************************************************/
1169 /* used to pass events to AV statemachine from other tasks */
1170 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1172 /* Switch to BTIF context */
1173 btif_transfer_context(btif_av_handle_event, event,
1174 (char*)p_data, len, NULL);
1177 /*******************************************************************************
1179 ** Function btif_av_execute_service
1181 ** Description Initializes/Shuts down the service
1183 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1185 *******************************************************************************/
1186 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1190 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1191 * handle this request in order to allow incoming connections to succeed.
1192 * We need to put this back once support for this is added */
1194 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1195 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1196 * be initiated by the app/audioflinger layers */
1197 #if (AVRC_METADATA_INCLUDED == TRUE)
1198 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1199 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1200 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1202 |BTA_AV_FEAT_ADV_CTRL
1206 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1209 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
1212 BTA_AvDeregister(btif_av_cb.bta_handle);
1215 return BT_STATUS_SUCCESS;
1218 /*******************************************************************************
1220 ** Function btif_av_get_src_interface
1222 ** Description Get the AV callback interface for A2DP source profile
1224 ** Returns btav_interface_t
1226 *******************************************************************************/
1227 const btav_interface_t *btif_av_get_src_interface(void)
1229 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1230 return &bt_av_src_interface;
1233 /*******************************************************************************
1235 ** Function btif_av_get_sink_interface
1237 ** Description Get the AV callback interface for A2DP sink profile
1239 ** Returns btav_interface_t
1241 *******************************************************************************/
1242 const btav_interface_t *btif_av_get_sink_interface(void)
1244 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1245 return &bt_av_sink_interface;
1248 /*******************************************************************************
1250 ** Function btif_av_is_connected
1252 ** Description Checks if av has a connected sink
1256 *******************************************************************************/
1257 BOOLEAN btif_av_is_connected(void)
1259 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1260 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1263 /*******************************************************************************
1265 ** Function btif_av_is_peer_edr
1267 ** Description Check if the connected a2dp device supports
1268 ** EDR or not. Only when connected this function
1269 ** will accurately provide a true capability of
1270 ** remote peer. If not connected it will always be false.
1272 ** Returns TRUE if remote device is capable of EDR
1274 *******************************************************************************/
1275 BOOLEAN btif_av_is_peer_edr(void)
1277 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);