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 ******************************************************************************/
19 #define LOG_TAG "btif_av"
26 #include <system/audio.h>
27 #include <hardware/bluetooth.h>
28 #include <hardware/bt_av.h>
32 #include "btif_media.h"
33 #include "btif_profile_queue.h"
34 #include "btif_util.h"
36 #include "bt_common.h"
37 #include "osi/include/allocator.h"
39 /*****************************************************************************
41 ******************************************************************************/
42 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
43 #define BTIF_AVK_SERVICE_NAME "Advanced Audio Sink"
45 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_MS (2 * 1000)
48 BTIF_AV_STATE_IDLE = 0x0,
49 BTIF_AV_STATE_OPENING,
51 BTIF_AV_STATE_STARTED,
55 /* Should not need dedicated suspend state as actual actions are no
56 different than open state. Suspend flags are needed however to prevent
57 media task from trying to restart stream during remote suspend or while
58 we are in the process of a local suspend */
60 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
61 #define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
62 #define BTIF_AV_FLAG_PENDING_START 0x4
63 #define BTIF_AV_FLAG_PENDING_STOP 0x8
65 /*****************************************************************************
66 ** Local type definitions
67 ******************************************************************************/
71 tBTA_AV_HNDL bta_handle;
73 btif_sm_handle_t sm_handle;
76 UINT8 peer_sep; /* sep type of peer device */
81 bt_bdaddr_t *target_bda;
83 } btif_av_connect_req_t;
90 } btif_av_sink_config_req_t;
92 /*****************************************************************************
94 ******************************************************************************/
95 static btav_callbacks_t *bt_av_src_callbacks = NULL;
96 static btav_callbacks_t *bt_av_sink_callbacks = NULL;
97 static btif_av_cb_t btif_av_cb = {0, {{0}}, 0, 0, 0, 0};
98 static alarm_t *av_open_on_rc_timer = NULL;
100 /* both interface and media task needs to be ready to alloc incoming request */
101 #define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
102 || (btif_av_cb.sm_handle == NULL))\
104 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
105 return BT_STATUS_NOT_READY;\
109 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
112 /* Helper macro to avoid code duplication in the state machine handlers */
113 #define CHECK_RC_EVENT(e, d) \
114 case BTA_AV_RC_OPEN_EVT: \
115 case BTA_AV_RC_CLOSE_EVT: \
116 case BTA_AV_REMOTE_CMD_EVT: \
117 case BTA_AV_VENDOR_CMD_EVT: \
118 case BTA_AV_META_MSG_EVT: \
119 case BTA_AV_RC_FEAT_EVT: \
120 case BTA_AV_REMOTE_RSP_EVT: \
122 btif_rc_handler(e, d);\
125 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
126 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
127 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
128 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
129 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
131 static const btif_sm_handler_t btif_av_state_handlers[] =
133 btif_av_state_idle_handler,
134 btif_av_state_opening_handler,
135 btif_av_state_opened_handler,
136 btif_av_state_started_handler,
137 btif_av_state_closing_handler
140 static void btif_av_event_free_data(btif_sm_event_t event, void *p_data);
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 UINT8 btif_rc_get_connected_peer_handle(void);
148 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
150 extern fixed_queue_t *btu_general_alarm_queue;
152 /*****************************************************************************
153 ** Local helper functions
154 ******************************************************************************/
156 const char *dump_av_sm_state_name(btif_av_state_t state)
160 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
161 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
162 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
163 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
164 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
165 default: return "UNKNOWN_STATE";
169 const char *dump_av_sm_event_name(btif_av_sm_event_t event)
173 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
174 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
175 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
176 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
177 CASE_RETURN_STR(BTA_AV_START_EVT)
178 CASE_RETURN_STR(BTA_AV_STOP_EVT)
179 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
180 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
181 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
182 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
183 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
184 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
185 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
186 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
187 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
188 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
189 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
190 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
191 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
192 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
193 CASE_RETURN_STR(BTA_AV_OFFLOAD_START_RSP_EVT)
194 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
195 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
196 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
197 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
198 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
199 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
200 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
201 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
202 CASE_RETURN_STR(BTIF_AV_OFFLOAD_START_REQ_EVT)
203 #ifdef USE_AUDIO_TRACK
204 CASE_RETURN_STR(BTIF_AV_SINK_FOCUS_REQ_EVT)
206 default: return "UNKNOWN_EVENT";
210 /****************************************************************************
211 ** Local helper functions
212 *****************************************************************************/
213 /*******************************************************************************
215 ** Function btif_initiate_av_open_timer_timeout
217 ** Description Timer to trigger AV open if the remote headset establishes
218 ** RC connection w/o AV connection. The timer is needed to IOP
219 ** with headsets that do establish AV after RC connection.
223 *******************************************************************************/
224 static void btif_initiate_av_open_timer_timeout(UNUSED_ATTR void *data)
227 btif_av_connect_req_t connect_req;
229 /* is there at least one RC connection - There should be */
230 if (btif_rc_get_connected_peer(peer_addr)) {
231 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
232 /* In case of AVRCP connection request, we will initiate SRC connection */
233 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
234 if(bt_av_sink_callbacks != NULL)
235 connect_req.uuid = UUID_SERVCLASS_AUDIO_SINK;
236 else if(bt_av_src_callbacks != NULL)
237 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
238 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
242 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
246 /*****************************************************************************
248 ******************************************************************************/
250 /*******************************************************************************
252 ** Function btif_report_connection_state
254 ** Description Updates the components via the callbacks about the connection
255 ** state of a2dp connection.
259 *******************************************************************************/
260 static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
262 if (bt_av_sink_callbacks != NULL) {
263 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
264 } else if (bt_av_src_callbacks != NULL) {
265 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
269 /*******************************************************************************
271 ** Function btif_report_audio_state
273 ** Description Updates the components via the callbacks about the audio
274 ** state of a2dp connection. The state is updated when either
275 ** the remote ends starts streaming (started state) or whenever
276 ** it transitions out of started state (to opened or streaming)
281 *******************************************************************************/
282 static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
284 if (bt_av_sink_callbacks != NULL) {
285 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
286 } else if (bt_av_src_callbacks != NULL) {
287 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
291 /*****************************************************************************
293 ** Function btif_av_state_idle_handler
295 ** Description State managing disconnected AV link
297 ** Returns TRUE if event was processed, FALSE otherwise
299 *******************************************************************************/
301 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
303 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
304 dump_av_sm_event_name(event), btif_av_cb.flags);
308 case BTIF_SM_ENTER_EVT:
309 /* clear the peer_bda */
310 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
311 btif_av_cb.flags = 0;
316 case BTIF_SM_EXIT_EVT:
319 case BTA_AV_ENABLE_EVT:
322 case BTA_AV_REGISTER_EVT:
323 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
326 case BTA_AV_PENDING_EVT:
327 case BTIF_AV_CONNECT_REQ_EVT:
329 if (event == BTIF_AV_CONNECT_REQ_EVT)
331 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
332 sizeof(bt_bdaddr_t));
333 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
334 TRUE, BTA_SEC_AUTHENTICATE, ((btif_av_connect_req_t*)p_data)->uuid);
336 else if (event == BTA_AV_PENDING_EVT)
338 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
339 if (bt_av_src_callbacks != NULL)
341 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
342 TRUE, BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
344 if (bt_av_sink_callbacks != NULL)
346 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
347 TRUE, BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SINK);
350 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
353 case BTA_AV_RC_OPEN_EVT:
354 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
355 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
356 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
357 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
358 * headsets, as some headsets initiate the AVRC connection first and then
359 * immediately initiate the AV connection
361 * TODO: We may need to do this only on an AVRCP Play. FixMe
364 BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
365 alarm_set_on_queue(av_open_on_rc_timer,
366 BTIF_TIMEOUT_AV_OPEN_ON_RC_MS,
367 btif_initiate_av_open_timer_timeout, NULL,
368 btu_general_alarm_queue);
369 btif_rc_handler(event, p_data);
373 * In case Signalling channel is not down
374 * and remote started Streaming Procedure
375 * we have to handle config and open event in
376 * idle_state. We hit these scenarios while running
377 * PTS test case for AVRCP Controller
379 case BTIF_AV_SINK_CONFIG_REQ_EVT:
381 btif_av_sink_config_req_t req;
382 // copy to avoid alignment problems
383 memcpy(&req, p_data, sizeof(req));
385 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
387 if (bt_av_sink_callbacks != NULL) {
388 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(req.peer_bd),
389 req.sample_rate, req.channel_count);
393 case BTA_AV_OPEN_EVT:
395 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
396 btav_connection_state_t state;
397 btif_sm_state_t av_state;
398 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
399 p_bta_data->open.edr);
401 if (p_bta_data->open.status == BTA_AV_SUCCESS)
403 state = BTAV_CONNECTION_STATE_CONNECTED;
404 av_state = BTIF_AV_STATE_OPENED;
405 btif_av_cb.edr = p_bta_data->open.edr;
407 btif_av_cb.peer_sep = p_bta_data->open.sep;
408 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
412 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
413 p_bta_data->open.status );
414 state = BTAV_CONNECTION_STATE_DISCONNECTED;
415 av_state = BTIF_AV_STATE_IDLE;
418 /* inform the application of the event */
419 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
420 /* change state to open/idle based on the status */
421 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
422 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
424 /* if queued PLAY command, send it now */
425 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
426 (p_bta_data->open.status == BTA_AV_SUCCESS));
428 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
430 /* if queued PLAY command, send it now */
431 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
432 /* Bring up AVRCP connection too */
433 BTA_AvOpenRc(btif_av_cb.bta_handle);
435 btif_queue_advance();
438 case BTA_AV_REMOTE_CMD_EVT:
439 case BTA_AV_VENDOR_CMD_EVT:
440 case BTA_AV_META_MSG_EVT:
441 case BTA_AV_RC_FEAT_EVT:
442 case BTA_AV_REMOTE_RSP_EVT:
443 btif_rc_handler(event, (tBTA_AV*)p_data);
446 case BTA_AV_RC_CLOSE_EVT:
447 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
448 alarm_cancel(av_open_on_rc_timer);
449 btif_rc_handler(event, p_data);
452 case BTIF_AV_OFFLOAD_START_REQ_EVT:
453 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE");
454 btif_a2dp_on_offload_started(BTA_AV_FAIL);
458 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
459 dump_av_sm_event_name(event));
466 /*****************************************************************************
468 ** Function btif_av_state_opening_handler
470 ** Description Intermediate state managing events during establishment
473 ** Returns TRUE if event was processed, FALSE otherwise
475 *******************************************************************************/
477 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
479 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
480 dump_av_sm_event_name(event), btif_av_cb.flags);
484 case BTIF_SM_ENTER_EVT:
485 /* inform the application that we are entering connecting state */
486 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
489 case BTIF_SM_EXIT_EVT:
492 case BTA_AV_REJECT_EVT:
493 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
494 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
495 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
498 case BTA_AV_OPEN_EVT:
500 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
501 btav_connection_state_t state;
502 btif_sm_state_t av_state;
503 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
504 p_bta_data->open.edr);
506 if (p_bta_data->open.status == BTA_AV_SUCCESS)
508 state = BTAV_CONNECTION_STATE_CONNECTED;
509 av_state = BTIF_AV_STATE_OPENED;
510 btif_av_cb.edr = p_bta_data->open.edr;
512 btif_av_cb.peer_sep = p_bta_data->open.sep;
513 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
517 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
518 p_bta_data->open.status );
520 if ((btif_rc_get_connected_peer(peer_addr))
521 &&(!bdcmp(btif_av_cb.peer_bda.address, peer_addr)))
524 * Disconnect AVRCP connection, if
525 * A2DP conneciton failed, for any reason
527 BTIF_TRACE_WARNING(" Disconnecting AVRCP ");
528 BTA_AvCloseRc(btif_rc_get_connected_peer_handle());
530 state = BTAV_CONNECTION_STATE_DISCONNECTED;
531 av_state = BTIF_AV_STATE_IDLE;
534 /* inform the application of the event */
535 btif_report_connection_state(state, &(btif_av_cb.peer_bda));
536 /* change state to open/idle based on the status */
537 btif_sm_change_state(btif_av_cb.sm_handle, av_state);
538 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
540 /* if queued PLAY command, send it now */
541 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
542 (p_bta_data->open.status == BTA_AV_SUCCESS));
544 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
546 /* if queued PLAY command, send it now */
547 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
548 /* Bring up AVRCP connection too */
549 BTA_AvOpenRc(btif_av_cb.bta_handle);
551 btif_queue_advance();
554 case BTIF_AV_SINK_CONFIG_REQ_EVT:
556 btif_av_sink_config_req_t req;
557 // copy to avoid alignment problems
558 memcpy(&req, p_data, sizeof(req));
560 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
562 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
563 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
564 req.sample_rate, req.channel_count);
568 case BTIF_AV_CONNECT_REQ_EVT:
569 // Check for device, if same device which moved to opening then ignore callback
570 if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
571 sizeof(btif_av_cb.peer_bda)) == 0)
573 BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req", __func__);
574 btif_queue_advance();
579 BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request", __func__);
580 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t*)p_data);
581 btif_queue_advance();
585 case BTA_AV_PENDING_EVT:
586 // Check for device, if same device which moved to opening then ignore callback
587 if (memcmp (((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb.peer_bda),
588 sizeof(btif_av_cb.peer_bda)) == 0)
590 BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req", __func__);
595 BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request", __func__);
596 BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
600 case BTIF_AV_OFFLOAD_START_REQ_EVT:
601 btif_a2dp_on_offload_started(BTA_AV_FAIL);
602 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING");
605 case BTA_AV_CLOSE_EVT:
606 btif_a2dp_on_stopped(NULL);
607 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
608 &(btif_av_cb.peer_bda));
609 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
612 CHECK_RC_EVENT(event, p_data);
615 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
616 dump_av_sm_event_name(event));
623 /*****************************************************************************
625 ** Function btif_av_state_closing_handler
627 ** Description Intermediate state managing events during closing
630 ** Returns TRUE if event was processed, FALSE otherwise
632 *******************************************************************************/
634 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
636 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
637 dump_av_sm_event_name(event), btif_av_cb.flags);
641 case BTIF_SM_ENTER_EVT:
642 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
644 /* immediately stop transmission of frames */
645 btif_a2dp_set_tx_flush(TRUE);
646 /* wait for audioflinger to stop a2dp */
648 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
650 btif_a2dp_set_rx_flush(TRUE);
654 case BTA_AV_STOP_EVT:
655 case BTIF_AV_STOP_STREAM_REQ_EVT:
656 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
658 /* immediately flush any pending tx frames while suspend is pending */
659 btif_a2dp_set_tx_flush(TRUE);
661 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
663 btif_a2dp_set_rx_flush(TRUE);
666 btif_a2dp_on_stopped(NULL);
669 case BTIF_SM_EXIT_EVT:
672 case BTA_AV_CLOSE_EVT:
674 /* inform the application that we are disconnecting */
675 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
677 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
680 /* Handle the RC_CLOSE event for the cleanup */
681 case BTA_AV_RC_CLOSE_EVT:
682 btif_rc_handler(event, (tBTA_AV*)p_data);
685 case BTIF_AV_OFFLOAD_START_REQ_EVT:
686 btif_a2dp_on_offload_started(BTA_AV_FAIL);
687 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing");
691 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
692 dump_av_sm_event_name(event));
698 /*****************************************************************************
700 ** Function btif_av_state_opened_handler
702 ** Description Handles AV events while AVDTP is in OPEN state
704 ** Returns TRUE if event was processed, FALSE otherwise
706 *******************************************************************************/
708 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
710 tBTA_AV *p_av = (tBTA_AV*)p_data;
712 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
713 dump_av_sm_event_name(event), btif_av_cb.flags);
715 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
716 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
718 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
719 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
724 case BTIF_SM_ENTER_EVT:
725 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
726 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
729 case BTIF_SM_EXIT_EVT:
730 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
733 case BTIF_AV_START_STREAM_REQ_EVT:
734 if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
735 btif_a2dp_setup_codec();
737 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
740 case BTA_AV_START_EVT:
742 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
743 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
745 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
748 /* if remote tries to start a2dp when DUT is a2dp source
749 * then suspend. In case a2dp is sink and call is active
750 * then disconnect the AVDTP channel
752 if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START))
754 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
756 BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!", __FUNCTION__);
757 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
761 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
762 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
764 if (btif_a2dp_on_started(&p_av->start,
765 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
767 /* only clear pending flag after acknowledgement */
768 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
772 /* remain in open state if status failed */
773 if (p_av->start.status != BTA_AV_SUCCESS)
776 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
778 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
781 /* change state to started, send acknowledgement if start is pending */
782 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
783 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
784 btif_a2dp_on_started(NULL, TRUE);
785 /* pending start flag will be cleared when exit current state */
787 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
791 case BTIF_AV_DISCONNECT_REQ_EVT:
792 BTA_AvClose(btif_av_cb.bta_handle);
793 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
794 BTA_AvCloseRc(btif_av_cb.bta_handle);
797 /* inform the application that we are disconnecting */
798 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
801 case BTA_AV_CLOSE_EVT:
802 /* avdtp link is closed */
803 btif_a2dp_on_stopped(NULL);
805 /* inform the application that we are disconnected */
806 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
808 /* change state to idle, send acknowledgement if start is pending */
809 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
810 btif_a2dp_ack_fail();
811 /* pending start flag will be cleared when exit current state */
813 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
816 case BTA_AV_RECONFIG_EVT:
817 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
818 (p_av->reconfig.status == BTA_AV_SUCCESS))
820 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
823 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
825 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
826 btif_a2dp_ack_fail();
830 case BTIF_AV_CONNECT_REQ_EVT:
831 if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
832 sizeof(btif_av_cb.peer_bda)) == 0)
834 BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device", __func__);
838 BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req", __func__);
839 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
840 (bt_bdaddr_t*)p_data);
842 btif_queue_advance();
845 case BTIF_AV_OFFLOAD_START_REQ_EVT:
846 btif_a2dp_on_offload_started(BTA_AV_FAIL);
847 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened");
850 CHECK_RC_EVENT(event, p_data);
853 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
854 dump_av_sm_event_name(event));
861 /*****************************************************************************
863 ** Function btif_av_state_started_handler
865 ** Description Handles AV events while A2DP stream is started
867 ** Returns TRUE if event was processed, FALSE otherwise
869 *******************************************************************************/
871 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
873 tBTA_AV *p_av = (tBTA_AV*)p_data;
875 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
876 dump_av_sm_event_name(event), btif_av_cb.flags);
880 case BTIF_SM_ENTER_EVT:
882 /* we are again in started state, clear any remote suspend flags */
883 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
886 * Report to components above that we have entered the streaming
887 * stage, this should usually be followed by focus grant.
888 * see update_audio_focus_state()
890 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
892 /* increase the a2dp consumer task priority temporarily when start
893 ** audio playing, to avoid overflow the audio packet queue. */
894 adjust_priority_a2dp(TRUE);
898 case BTIF_SM_EXIT_EVT:
899 /* restore the a2dp consumer task priority when stop audio playing. */
900 adjust_priority_a2dp(FALSE);
904 case BTIF_AV_START_STREAM_REQ_EVT:
905 /* we were remotely started, just ack back the local request */
906 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
907 btif_a2dp_on_started(NULL, TRUE);
910 /* fixme -- use suspend = true always to work around issue with BTA AV */
911 case BTIF_AV_STOP_STREAM_REQ_EVT:
912 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
914 /* set pending flag to ensure btif task is not trying to restart
915 stream while suspend is in progress */
916 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
918 /* if we were remotely suspended but suspend locally, local suspend
920 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
922 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
924 /* immediately stop transmission of frames while suspend is pending */
925 btif_a2dp_set_tx_flush(TRUE);
928 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
929 btif_a2dp_set_rx_flush(TRUE);
930 btif_a2dp_on_stopped(NULL);
936 case BTIF_AV_DISCONNECT_REQ_EVT:
938 /* request avdtp to close */
939 BTA_AvClose(btif_av_cb.bta_handle);
940 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
941 BTA_AvCloseRc(btif_av_cb.bta_handle);
944 /* inform the application that we are disconnecting */
945 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
947 /* wait in closing state until fully closed */
948 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
951 case BTA_AV_SUSPEND_EVT:
953 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
954 p_av->suspend.status, p_av->suspend.initiator);
956 /* a2dp suspended, stop media task until resumed */
957 btif_a2dp_on_suspended(&p_av->suspend);
959 /* if not successful, remain in current state */
960 if (p_av->suspend.status != BTA_AV_SUCCESS)
962 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
964 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
966 /* suspend failed, reset back tx flush state */
967 btif_a2dp_set_tx_flush(FALSE);
972 if (p_av->suspend.initiator != TRUE)
974 /* remote suspend, notify HAL and await audioflinger to
975 suspend/stop stream */
977 /* set remote suspend flag to block media task from restarting
978 stream only if we did not already initiate a local suspend */
979 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
980 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
982 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
986 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
989 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
991 /* suspend completed and state changed, clear pending status */
992 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
995 case BTA_AV_STOP_EVT:
997 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
998 btif_a2dp_on_stopped(&p_av->suspend);
1000 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
1002 /* if stop was successful, change state to open */
1003 if (p_av->suspend.status == BTA_AV_SUCCESS)
1004 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
1008 case BTA_AV_CLOSE_EVT:
1010 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
1012 /* avdtp link is closed */
1013 btif_a2dp_on_stopped(NULL);
1015 /* inform the application that we are disconnected */
1016 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
1018 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
1021 case BTIF_AV_OFFLOAD_START_REQ_EVT:
1022 BTA_AvOffloadStart(btif_av_cb.bta_handle);
1025 case BTA_AV_OFFLOAD_START_RSP_EVT:
1027 btif_a2dp_on_offload_started(p_av->status);
1030 CHECK_RC_EVENT(event, p_data);
1033 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
1034 dump_av_sm_event_name(event));
1041 /*****************************************************************************
1042 ** Local event handlers
1043 ******************************************************************************/
1045 static void btif_av_handle_event(UINT16 event, char* p_param)
1049 case BTIF_AV_CLEANUP_REQ_EVT:
1050 BTIF_TRACE_EVENT("%s: BTIF_AV_CLEANUP_REQ_EVT", __FUNCTION__);
1051 btif_a2dp_stop_media_task();
1055 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
1056 btif_av_event_free_data(event, p_param);
1060 void btif_av_event_deep_copy(UINT16 event, char *p_dest, char *p_src)
1062 tBTA_AV *av_src = (tBTA_AV *)p_src;
1063 tBTA_AV *av_dest = (tBTA_AV *)p_dest;
1065 // First copy the structure
1066 maybe_non_aligned_memcpy(av_dest, av_src, sizeof(*av_src));
1070 case BTA_AV_META_MSG_EVT:
1071 if (av_src->meta_msg.p_data && av_src->meta_msg.len)
1073 av_dest->meta_msg.p_data = osi_calloc(av_src->meta_msg.len);
1074 memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data,
1075 av_src->meta_msg.len);
1078 if (av_src->meta_msg.p_msg)
1080 av_dest->meta_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
1081 memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg,
1084 if (av_src->meta_msg.p_msg->vendor.p_vendor_data &&
1085 av_src->meta_msg.p_msg->vendor.vendor_len)
1087 av_dest->meta_msg.p_msg->vendor.p_vendor_data = osi_calloc(
1088 av_src->meta_msg.p_msg->vendor.vendor_len);
1089 memcpy(av_dest->meta_msg.p_msg->vendor.p_vendor_data,
1090 av_src->meta_msg.p_msg->vendor.p_vendor_data,
1091 av_src->meta_msg.p_msg->vendor.vendor_len);
1101 static void btif_av_event_free_data(btif_sm_event_t event, void *p_data)
1105 case BTA_AV_META_MSG_EVT:
1107 tBTA_AV *av = (tBTA_AV *)p_data;
1108 osi_free_and_reset((void **)&av->meta_msg.p_data);
1110 if (av->meta_msg.p_msg) {
1111 osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
1112 osi_free_and_reset((void **)&av->meta_msg.p_msg);
1122 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
1124 btif_transfer_context(btif_av_handle_event, event,
1125 (char*)p_data, sizeof(tBTA_AV), btif_av_event_deep_copy);
1128 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
1130 btif_sm_state_t state;
1132 tA2D_STATUS a2d_status;
1133 tA2D_SBC_CIE sbc_cie;
1134 btif_av_sink_config_req_t config_req;
1136 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
1138 state= btif_sm_get_state(btif_av_cb.sm_handle);
1139 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
1140 (state == BTIF_AV_STATE_OPENED) )
1142 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
1143 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
1149 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
1150 /* send a command to BT Media Task */
1151 btif_reset_decoder((UINT8*)(p_data->avk_config.codec_info));
1152 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)(p_data->avk_config.codec_info), FALSE);
1153 if (a2d_status == A2D_SUCCESS) {
1154 /* Switch to BTIF context */
1155 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
1156 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
1157 memcpy(&config_req.peer_bd,(UINT8*)(p_data->avk_config.bd_addr),
1158 sizeof(config_req.peer_bd));
1159 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
1160 (char*)&config_req, sizeof(config_req), NULL);
1162 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
1166 /*******************************************************************************
1168 ** Function btif_av_init
1170 ** Description Initializes btif AV if not already done
1172 ** Returns bt_status_t
1174 *******************************************************************************/
1176 bt_status_t btif_av_init(int service_id)
1178 if (btif_av_cb.sm_handle == NULL)
1180 alarm_free(av_open_on_rc_timer);
1181 av_open_on_rc_timer = alarm_new("btif_av.av_open_on_rc_timer");
1182 if (!btif_a2dp_start_media_task())
1183 return BT_STATUS_FAIL;
1185 btif_enable_service(service_id);
1187 /* Also initialize the AV state machine */
1188 btif_av_cb.sm_handle =
1189 btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
1191 btif_a2dp_on_init();
1194 return BT_STATUS_SUCCESS;
1197 /*******************************************************************************
1199 ** Function init_src
1201 ** Description Initializes the AV interface for source mode
1203 ** Returns bt_status_t
1205 *******************************************************************************/
1207 static bt_status_t init_src(btav_callbacks_t* callbacks)
1209 BTIF_TRACE_EVENT("%s()", __func__);
1211 bt_status_t status = btif_av_init(BTA_A2DP_SOURCE_SERVICE_ID);
1212 if (status == BT_STATUS_SUCCESS)
1213 bt_av_src_callbacks = callbacks;
1218 /*******************************************************************************
1220 ** Function init_sink
1222 ** Description Initializes the AV interface for sink mode
1224 ** Returns bt_status_t
1226 *******************************************************************************/
1228 static bt_status_t init_sink(btav_callbacks_t* callbacks)
1230 BTIF_TRACE_EVENT("%s()", __func__);
1232 bt_status_t status = btif_av_init(BTA_A2DP_SINK_SERVICE_ID);
1233 if (status == BT_STATUS_SUCCESS)
1234 bt_av_sink_callbacks = callbacks;
1239 #ifdef USE_AUDIO_TRACK
1240 /*******************************************************************************
1242 ** Function update_audio_focus_state
1244 ** Description Updates the final focus state reported by components calling
1249 *******************************************************************************/
1250 void update_audio_focus_state(int state)
1252 BTIF_TRACE_DEBUG("%s state %d ",__func__, state);
1253 btif_a2dp_set_audio_focus_state(state);
1256 /*******************************************************************************
1258 ** Function update_audio_track_gain
1260 ** Description Updates the track gain (used for ducking).
1264 *******************************************************************************/
1265 void update_audio_track_gain(float gain)
1267 BTIF_TRACE_DEBUG("%s gain %f ",__func__, gain);
1268 btif_a2dp_set_audio_track_gain(gain);
1272 /*******************************************************************************
1276 ** Description Establishes the AV signalling channel with the remote headset
1278 ** Returns bt_status_t
1280 *******************************************************************************/
1282 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
1284 btif_av_connect_req_t connect_req;
1285 connect_req.target_bda = bd_addr;
1286 connect_req.uuid = uuid;
1287 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1289 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
1291 return BT_STATUS_SUCCESS;
1294 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
1296 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1299 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
1302 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
1304 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1307 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
1310 /*******************************************************************************
1312 ** Function disconnect
1314 ** Description Tears down the AV signalling channel with the remote headset
1316 ** Returns bt_status_t
1318 *******************************************************************************/
1319 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
1321 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1325 /* Switch to BTIF context */
1326 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
1327 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
1330 /*******************************************************************************
1334 ** Description Shuts down the AV interface and does the cleanup
1338 *******************************************************************************/
1339 static void cleanup(int service_uuid)
1341 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1343 btif_transfer_context(btif_av_handle_event, BTIF_AV_CLEANUP_REQ_EVT, NULL, 0, NULL);
1345 btif_disable_service(service_uuid);
1347 /* Also shut down the AV state machine */
1348 btif_sm_shutdown(btif_av_cb.sm_handle);
1349 btif_av_cb.sm_handle = NULL;
1352 static void cleanup_src(void) {
1353 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1355 if (bt_av_src_callbacks)
1357 bt_av_src_callbacks = NULL;
1358 if (bt_av_sink_callbacks == NULL)
1359 cleanup(BTA_A2DP_SOURCE_SERVICE_ID);
1363 static void cleanup_sink(void) {
1364 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1366 if (bt_av_sink_callbacks)
1368 bt_av_sink_callbacks = NULL;
1369 if (bt_av_src_callbacks == NULL)
1370 cleanup(BTA_A2DP_SINK_SERVICE_ID);
1374 static const btav_interface_t bt_av_src_interface = {
1375 sizeof(btav_interface_t),
1384 static const btav_interface_t bt_av_sink_interface = {
1385 sizeof(btav_interface_t),
1390 #ifdef USE_AUDIO_TRACK
1391 update_audio_focus_state,
1392 update_audio_track_gain,
1399 /*******************************************************************************
1401 ** Function btif_av_get_sm_handle
1403 ** Description Fetches current av SM handle
1407 *******************************************************************************/
1409 btif_sm_handle_t btif_av_get_sm_handle(void)
1411 return btif_av_cb.sm_handle;
1414 /*******************************************************************************
1416 ** Function btif_av_get_addr
1418 ** Description Fetches current AV BD address
1420 ** Returns BD address
1422 *******************************************************************************/
1424 bt_bdaddr_t btif_av_get_addr(void)
1426 return btif_av_cb.peer_bda;
1429 /*******************************************************************************
1431 ** Function btif_av_stream_ready
1433 ** Description Checks whether AV is ready for starting a stream
1437 *******************************************************************************/
1439 BOOLEAN btif_av_stream_ready(void)
1441 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1443 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
1444 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1446 /* also make sure main adapter is enabled */
1447 if (btif_is_enabled() == 0)
1449 BTIF_TRACE_EVENT("main adapter not enabled");
1453 /* check if we are remotely suspended or stop is pending */
1454 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
1457 return (state == BTIF_AV_STATE_OPENED);
1460 /*******************************************************************************
1462 ** Function btif_av_stream_started_ready
1464 ** Description Checks whether AV ready for media start in streaming state
1468 *******************************************************************************/
1470 BOOLEAN btif_av_stream_started_ready(void)
1472 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1474 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
1475 btif_av_cb.sm_handle, state, btif_av_cb.flags);
1477 /* disallow media task to start if we have pending actions */
1478 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
1479 | BTIF_AV_FLAG_PENDING_STOP))
1482 return (state == BTIF_AV_STATE_STARTED);
1485 /*******************************************************************************
1487 ** Function btif_dispatch_sm_event
1489 ** Description Send event to AV statemachine
1493 *******************************************************************************/
1495 /* used to pass events to AV statemachine from other tasks */
1496 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
1498 /* Switch to BTIF context */
1499 btif_transfer_context(btif_av_handle_event, event,
1500 (char*)p_data, len, NULL);
1503 /*******************************************************************************
1505 ** Function btif_av_execute_service
1507 ** Description Initializes/Shuts down the service
1509 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1511 *******************************************************************************/
1512 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
1516 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1517 * handle this request in order to allow incoming connections to succeed.
1518 * We need to put this back once support for this is added */
1520 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1521 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1522 * be initiated by the app/audioflinger layers */
1523 /* Support for browsing for SDP record should work only if we enable BROWSE
1524 * while registering. */
1525 #if (AVRC_METADATA_INCLUDED == TRUE)
1526 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
1527 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
1528 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1530 |BTA_AV_FEAT_ADV_CTRL
1534 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
1537 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback,
1538 UUID_SERVCLASS_AUDIO_SOURCE);
1541 BTA_AvDeregister(btif_av_cb.bta_handle);
1544 return BT_STATUS_SUCCESS;
1547 /*******************************************************************************
1549 ** Function btif_av_sink_execute_service
1551 ** Description Initializes/Shuts down the service
1553 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1555 *******************************************************************************/
1556 bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
1560 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1561 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1562 * be initiated by the app/audioflinger layers */
1563 BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD|BTA_AV_FEAT_RCCT|
1564 BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|
1565 BTA_AV_FEAT_ADV_CTRL|BTA_AV_FEAT_RCTG,
1567 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AVK_SERVICE_NAME, 0, bte_av_media_callback,
1568 UUID_SERVCLASS_AUDIO_SINK);
1571 BTA_AvDeregister(btif_av_cb.bta_handle);
1574 return BT_STATUS_SUCCESS;
1577 /*******************************************************************************
1579 ** Function btif_av_get_src_interface
1581 ** Description Get the AV callback interface for A2DP source profile
1583 ** Returns btav_interface_t
1585 *******************************************************************************/
1586 const btav_interface_t *btif_av_get_src_interface(void)
1588 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1589 return &bt_av_src_interface;
1592 /*******************************************************************************
1594 ** Function btif_av_get_sink_interface
1596 ** Description Get the AV callback interface for A2DP sink profile
1598 ** Returns btav_interface_t
1600 *******************************************************************************/
1601 const btav_interface_t *btif_av_get_sink_interface(void)
1603 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1604 return &bt_av_sink_interface;
1607 /*******************************************************************************
1609 ** Function btif_av_is_connected
1611 ** Description Checks if av has a connected sink
1615 *******************************************************************************/
1616 BOOLEAN btif_av_is_connected(void)
1618 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
1619 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
1622 /*******************************************************************************
1624 ** Function btif_av_is_peer_edr
1626 ** Description Check if the connected a2dp device supports
1627 ** EDR or not. Only when connected this function
1628 ** will accurately provide a true capability of
1629 ** remote peer. If not connected it will always be false.
1631 ** Returns TRUE if remote device is capable of EDR
1633 *******************************************************************************/
1634 BOOLEAN btif_av_is_peer_edr(void)
1636 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
1644 /******************************************************************************
1646 ** Function btif_av_clear_remote_suspend_flag
1648 ** Description Clears btif_av_cd.flags if BTIF_AV_FLAG_REMOTE_SUSPEND is set
1651 ******************************************************************************/
1652 void btif_av_clear_remote_suspend_flag(void)
1654 BTIF_TRACE_DEBUG("%s: flag :%x",__func__, btif_av_cb.flags);
1655 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;