1 /******************************************************************************
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
5 * Copyright (C) 2009-2012 Broadcom Corporation
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at:
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************************/
21 #define LOG_TAG "btif_av"
28 #include <system/audio.h>
29 #include <hardware/bluetooth.h>
30 #include <hardware/bt_av.h>
34 #include "btif_media.h"
35 #include "btif_profile_queue.h"
36 #include "btif_util.h"
38 #include "bt_common.h"
39 #include "osi/include/allocator.h"
40 #include <cutils/properties.h>
42 /*****************************************************************************
44 ******************************************************************************/
45 #define BTIF_AV_SERVICE_NAME "Advanced Audio"
46 #define BTIF_AVK_SERVICE_NAME "Advanced Audio Sink"
48 #define BTIF_TIMEOUT_AV_OPEN_ON_RC_MS (2 * 1000)
50 /* Number of BTIF-AV control blocks */
51 /* Now supports Two AV connections. */
52 #define BTIF_AV_NUM_CB 2
53 #define HANDLE_TO_INDEX(x) ((x & BTA_AV_HNDL_MSK) - 1)
54 #define INVALID_INDEX -1
57 BTIF_AV_STATE_IDLE = 0x0,
58 BTIF_AV_STATE_OPENING,
60 BTIF_AV_STATE_STARTED,
64 /* Should not need dedicated suspend state as actual actions are no
65 different than open state. Suspend flags are needed however to prevent
66 media task from trying to restart stream during remote suspend or while
67 we are in the process of a local suspend */
69 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
70 #define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
71 #define BTIF_AV_FLAG_PENDING_START 0x4
72 #define BTIF_AV_FLAG_PENDING_STOP 0x8
73 /* Host role defenitions */
74 #define HOST_ROLE_MASTER 0x00
75 #define HOST_ROLE_SLAVE 0x01
76 #define HOST_ROLE_UNKNOWN 0xff
78 /*****************************************************************************
79 ** Local type definitions
80 ******************************************************************************/
84 tBTA_AV_HNDL bta_handle;
86 btif_sm_handle_t sm_handle;
89 UINT8 peer_sep; /* sep type of peer device */
92 BOOLEAN current_playing;
93 btif_sm_state_t state;
96 BOOLEAN is_device_playing;
97 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
104 bt_bdaddr_t *target_bda;
106 } btif_av_connect_req_t;
113 } btif_av_sink_config_req_t;
118 BOOLEAN aptx_offload;
120 BOOLEAN aptxhd_offload;
121 } btif_av_a2dp_offloaded_codec_cap_t;
130 /*****************************************************************************
132 ******************************************************************************/
133 static btav_callbacks_t *bt_av_src_callbacks = NULL;
134 static btav_callbacks_t *bt_av_sink_callbacks = NULL;
135 static alarm_t *av_open_on_rc_timer = NULL;
136 static btif_av_cb_t btif_av_cb[BTIF_AV_NUM_CB];
137 static btif_sm_event_t idle_rc_event;
138 static tBTA_AV idle_rc_data;
139 int btif_max_av_clients = 1;
140 static BOOLEAN enable_multicast = FALSE;
141 static BOOLEAN is_multicast_supported = FALSE;
142 static BOOLEAN multicast_disabled = FALSE;
143 BOOLEAN bt_split_a2dp_enabled = FALSE;
144 btif_av_a2dp_offloaded_codec_cap_t btif_av_codec_offload;
145 /* both interface and media task needs to be ready to alloc incoming request */
146 #define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
147 || (btif_av_cb[0].sm_handle == NULL))\
149 BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
150 return BT_STATUS_NOT_READY;\
154 BTIF_TRACE_EVENT("%s", __FUNCTION__);\
157 /* Helper macro to avoid code duplication in the state machine handlers */
158 #define CHECK_RC_EVENT(e, d) \
159 case BTA_AV_RC_CLOSE_EVT: \
160 case BTA_AV_REMOTE_CMD_EVT: \
161 case BTA_AV_VENDOR_CMD_EVT: \
162 case BTA_AV_META_MSG_EVT: \
163 case BTA_AV_BROWSE_MSG_EVT: \
164 case BTA_AV_RC_FEAT_EVT: \
165 case BTA_AV_REMOTE_RSP_EVT: \
167 btif_rc_handler(e, d);\
171 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data, int index);
172 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data, int index);
173 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data, int index);
174 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data,int index);
176 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data,int index);
178 static BOOLEAN btif_av_get_valid_idx(int idx);
179 static UINT8 btif_av_idx_by_bdaddr( BD_ADDR bd_addr);
180 int btif_get_latest_playing_device_idx();
181 static int btif_get_latest_device_idx_to_start();
182 static int btif_av_get_valid_idx_for_rc_events(BD_ADDR bd_addr, int rc_handle);
183 static int btif_get_conn_state_of_device(BD_ADDR address);
184 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid);
185 static void btif_av_update_current_playing_device(int index);
186 static void btif_av_check_rc_connection_priority(void *p_data);
188 void btif_av_request_audio_focus( BOOLEAN enable);
190 static const btif_sm_handler_t btif_av_state_handlers[] =
192 btif_av_state_idle_handler,
193 btif_av_state_opening_handler,
194 btif_av_state_opened_handler,
195 btif_av_state_started_handler,
196 btif_av_state_closing_handler
199 static void btif_av_event_free_data(btif_sm_event_t event, void *p_data);
201 /*************************************************************************
203 *************************************************************************/
204 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
205 extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
206 extern UINT8 btif_rc_get_connected_peer_handle(BD_ADDR peer_addr);
207 extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
208 extern void btif_rc_get_playing_device(BD_ADDR address);
209 extern void btif_rc_clear_playing_state(BOOLEAN play);
210 extern void btif_rc_clear_priority(BD_ADDR address);
211 extern void btif_rc_send_pause_command();
212 extern UINT16 btif_dm_get_br_edr_links();
213 extern UINT16 btif_dm_get_le_links();
214 extern UINT16 btif_hf_is_call_idle();
216 extern fixed_queue_t *btu_general_alarm_queue;
218 /*****************************************************************************
219 ** Local helper functions
220 ******************************************************************************/
221 void btif_av_trigger_dual_handoff(BOOLEAN handoff, BD_ADDR address);
222 BOOLEAN btif_av_is_device_connected(BD_ADDR address);
224 BOOLEAN btif_av_is_connected_on_other_idx(int current_index);
225 BOOLEAN btif_av_is_playing_on_other_idx(int current_index);
226 BOOLEAN btif_av_is_playing();
227 void btif_av_update_multicast_state(int index);
228 BOOLEAN btif_av_get_ongoing_multicast();
229 tBTA_AV_HNDL btif_av_get_playing_device_hdl();
230 tBTA_AV_HNDL btif_av_get_av_hdl_from_idx(UINT8 idx);
231 int btif_av_get_other_connected_idx(int current_index);
232 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
233 BOOLEAN btif_av_is_codec_offload_supported(int codec);
234 int btif_av_get_current_playing_dev_idx();
235 BOOLEAN btif_av_is_under_handoff();
237 #define btif_av_is_codec_offload_supported(codec) (0)
238 #define btif_av_get_current_playing_dev_idx() (0)
239 #define btif_av_is_under_handoff() (0)
242 const char *dump_av_sm_state_name(btif_av_state_t state)
246 CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
247 CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
248 CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
249 CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
250 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
251 default: return "UNKNOWN_STATE";
255 const char *dump_av_sm_event_name(btif_av_sm_event_t event)
259 CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
260 CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
261 CASE_RETURN_STR(BTA_AV_OPEN_EVT)
262 CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
263 CASE_RETURN_STR(BTA_AV_START_EVT)
264 CASE_RETURN_STR(BTA_AV_STOP_EVT)
265 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
266 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
267 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
268 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
269 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
270 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
271 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
272 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
273 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
274 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
275 CASE_RETURN_STR(BTA_AV_PENDING_EVT)
276 CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
277 CASE_RETURN_STR(BTA_AV_REJECT_EVT)
278 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
279 CASE_RETURN_STR(BTA_AV_OFFLOAD_START_RSP_EVT)
280 CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
281 CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
282 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
283 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
284 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
285 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
286 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
287 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
288 CASE_RETURN_STR(BTIF_AV_OFFLOAD_START_REQ_EVT)
289 #ifdef USE_AUDIO_TRACK
290 CASE_RETURN_STR(BTIF_AV_SINK_FOCUS_REQ_EVT)
292 CASE_RETURN_STR(BTIF_AV_UPDATE_ENCODER_REQ_EVT)
293 default: return "UNKNOWN_EVENT";
297 const char *dump_av_codec_name(btif_av_codec_list codec)
302 CASE_RETURN_STR(APTX)
304 CASE_RETURN_STR(APTXHD)
305 default: return "UNKNOWN_CODEC";
308 //TODO.. We will remove this data structure
309 static BD_ADDR bd_null= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
311 /****************************************************************************
312 ** Local helper functions
313 *****************************************************************************/
314 /*******************************************************************************
316 ** Function btif_initiate_av_open_timer_timeout
318 ** Description Timer to trigger AV open if the remote headset establishes
319 ** RC connection w/o AV connection. The timer is needed to IOP
320 ** with headsets that do establish AV after RC connection.
324 *******************************************************************************/
325 static void btif_initiate_av_open_timer_timeout(UNUSED_ATTR void *data)
329 /* is there at least one RC connection - There should be */
330 /*We have Two Connections.*/
331 if (btif_rc_get_connected_peer(peer_addr))
333 /*Check if this peer_addr is same as currently connected AV*/
334 if (btif_get_conn_state_of_device(peer_addr) == BTIF_AV_STATE_OPENED)
336 BTIF_TRACE_DEBUG("AV is already connected");
342 /* Multicast: Check if AV slot is available for connection
343 * If not available, AV got connected to different devices.
344 * Disconnect this RC connection without AV connection.
346 rc_handle = btif_rc_get_connected_peer_handle(peer_addr);
347 index = btif_av_get_valid_idx_for_rc_events(peer_addr, rc_handle);
348 if(index >= btif_max_av_clients)
350 BTIF_TRACE_ERROR("%s No slot free for AV connection, back off",
354 BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
355 if(bt_av_sink_callbacks != NULL)
356 btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, (bt_bdaddr_t*)&peer_addr,
358 if(bt_av_src_callbacks != NULL)
359 btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, (bt_bdaddr_t*)&peer_addr,
365 BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
371 /*****************************************************************************
373 ******************************************************************************/
375 /*******************************************************************************
377 ** Function btif_report_connection_state
379 ** Description Updates the components via the callbacks about the connection
380 ** state of a2dp connection.
384 *******************************************************************************/
385 static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
387 if (bt_av_sink_callbacks != NULL) {
388 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
389 } else if ( bt_av_src_callbacks != NULL) {
390 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
394 /*******************************************************************************
396 ** Function btif_report_audio_state
398 ** Description Updates the components via the callbacks about the audio
399 ** state of a2dp connection. The state is updated when either
400 ** the remote ends starts streaming (started state) or whenever
401 ** it transitions out of started state (to opened or streaming)
406 *******************************************************************************/
407 static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
409 if (bt_av_sink_callbacks != NULL) {
410 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
411 } else if (bt_av_src_callbacks != NULL) {
412 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
416 /*****************************************************************************
418 ** Function btif_av_state_idle_handler
420 ** Description State managing disconnected AV link
422 ** Returns TRUE if event was processed, FALSE otherwise
424 *******************************************************************************/
426 static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data, int index)
428 char a2dp_role[255] = "false";
430 BTIF_TRACE_IMP("%s event:%s flags %x on Index = %d", __FUNCTION__,
431 dump_av_sm_event_name(event), btif_av_cb[index].flags, index);
435 case BTIF_SM_ENTER_EVT:
436 /* clear the peer_bda */
437 BTIF_TRACE_EVENT("IDLE state for index: %d", index);
438 memset(&btif_av_cb[index].peer_bda, 0, sizeof(bt_bdaddr_t));
439 btif_av_cb[index].flags = 0;
440 btif_av_cb[index].edr_3mbps = 0;
441 btif_av_cb[index].edr = 0;
442 btif_av_cb[index].current_playing = FALSE;
443 btif_av_cb[index].is_slave = FALSE;
444 btif_av_cb[index].is_device_playing = FALSE;
445 for (int i = 0; i < btif_max_av_clients; i++)
447 btif_av_cb[i].dual_handoff = FALSE;
449 property_get("persist.service.bt.a2dp.sink", a2dp_role, "false");
450 if (!strncmp("false", a2dp_role, 5)) {
451 btif_av_cb[index].peer_sep = AVDT_TSEP_SNK;
452 btif_a2dp_set_peer_sep(AVDT_TSEP_SNK);
454 btif_av_cb[index].peer_sep = AVDT_TSEP_SRC;
455 btif_a2dp_set_peer_sep(AVDT_TSEP_SRC);
457 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
458 btif_av_cb[index].channel_id = 0;
460 /* This API will be called twice at initialization
461 ** Idle can be moved when device is disconnected too.
462 ** Take care of other connected device here.*/
463 if (!btif_av_is_connected())
465 BTIF_TRACE_EVENT("reset A2dp states in IDLE ");
470 //There is another AV connection, update current playin
471 BTIF_TRACE_EVENT("reset A2dp states in IDLE ");
472 //btif_media_send_reset_vendor_state();
473 btif_av_update_current_playing_device(index);
475 if (!btif_av_is_playing_on_other_idx(index) &&
476 bt_split_a2dp_enabled)
478 BTIF_TRACE_EVENT("reset Vendor flag A2DP state is IDLE");
479 btif_media_send_reset_vendor_state();
483 case BTIF_SM_EXIT_EVT:
486 case BTA_AV_ENABLE_EVT:
487 BTIF_TRACE_EVENT("AV is enabled now for index: %d", index);
490 case BTA_AV_REGISTER_EVT:
491 BTIF_TRACE_EVENT("The AV Handle:%d", ((tBTA_AV*)p_data)->registr.hndl);
492 btif_av_cb[index].bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
496 * In case Signalling channel is not down
497 * and remote started Streaming Procedure
498 * we have to handle config and open event in
499 * idle_state. We hit these scenarios while running
500 * PTS test case for AVRCP Controller
502 case BTIF_AV_SINK_CONFIG_REQ_EVT:
504 btif_av_sink_config_req_t req;
505 // copy to avoid alignment problems
506 memcpy(&req, p_data, sizeof(req));
508 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
510 if (bt_av_sink_callbacks != NULL) {
511 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(req.peer_bd),
512 req.sample_rate, req.channel_count);
516 case BTIF_AV_CONNECT_REQ_EVT:
517 /* For outgoing connect stack and app are in sync.
519 memcpy(&btif_av_cb[index].peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
520 sizeof(bt_bdaddr_t));
521 BTA_AvOpen(btif_av_cb[index].peer_bda.address, btif_av_cb[index].bta_handle,
522 TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid);
523 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_OPENING);
526 case BTA_AV_PENDING_EVT:
527 case BTA_AV_RC_OPEN_EVT:
528 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
529 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
530 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
531 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
532 * headsets, as some headsets initiate the AVRC connection first and then
533 * immediately initiate the AV connection
535 * TODO: We may need to do this only on an AVRCP Play. FixMe
537 /* Check if connection allowed with this device */
538 /* In Dual A2dp case, this event can come for both the headsets.
539 * Reject second connection request as we are already checking
540 * for device priority for first device and we cannot queue
541 * incoming connections requests.
544 if (idle_rc_event != 0)
546 BTIF_TRACE_DEBUG("Processing another RC Event ");
549 memcpy(&idle_rc_data, ((tBTA_AV*)p_data), sizeof(tBTA_AV));
550 if (event == BTA_AV_RC_OPEN_EVT)
552 if (((tBTA_AV*)p_data)->rc_open.status == BTA_AV_SUCCESS)
554 bdcpy(btif_av_cb[index].peer_bda.address,
555 ((tBTA_AV*)p_data)->rc_open.peer_addr);
565 bdcpy(btif_av_cb[index].peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
568 // Only for AVDTP connection request move to opening state
569 if (event == BTA_AV_PENDING_EVT)
570 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_OPENING);
572 if (bt_av_src_callbacks != NULL)
574 BTIF_TRACE_DEBUG("Calling connection priority callback ");
575 idle_rc_event = event;
576 HAL_CBACK(bt_av_src_callbacks, connection_priority_cb,
577 &(btif_av_cb[index].peer_bda));
579 if (bt_av_sink_callbacks != NULL)
581 if(event == BTA_AV_PENDING_EVT)
583 BTA_AvOpen(btif_av_cb[index].peer_bda.address, btif_av_cb[index].bta_handle,
584 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SINK);
586 else if(event == BTA_AV_RC_OPEN_EVT)
588 alarm_set_on_queue(av_open_on_rc_timer,
589 BTIF_TIMEOUT_AV_OPEN_ON_RC_MS,
590 btif_initiate_av_open_timer_timeout, NULL,
591 btu_general_alarm_queue);
592 btif_rc_handler(event, p_data);
597 case BTA_AV_OPEN_EVT:
599 /* We get this event in Idle State if Signaling
600 * channel is not closed, only Streaming channel was
601 * closed earlier, and now only stream setup process is
604 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
605 btav_connection_state_t state;
606 BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
607 p_bta_data->open.edr);
609 if (p_bta_data->open.status == BTA_AV_SUCCESS)
611 state = BTAV_CONNECTION_STATE_CONNECTED;
612 btif_av_cb[index].edr = p_bta_data->open.edr;
613 if (p_bta_data->open.role == HOST_ROLE_SLAVE)
615 btif_av_cb[index].is_slave = TRUE;
617 btif_av_cb[index].peer_sep = p_bta_data->open.sep;
618 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
620 if (p_bta_data->open.edr & BTA_AV_EDR_3MBPS)
622 BTIF_TRACE_DEBUG("remote supports 3 mbps");
623 btif_av_cb[index].edr_3mbps = TRUE;
626 bdcpy(btif_av_cb[index].peer_bda.address, ((tBTA_AV*)p_data)->open.bd_addr);
627 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
628 btif_av_cb[index].channel_id = p_bta_data->open.stream_chnl_id;
629 BTIF_TRACE_DEBUG("streaming channel id updated as : 0x%x",
630 btif_av_cb[index].channel_id);
635 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
636 p_bta_data->open.status );
637 state = BTAV_CONNECTION_STATE_DISCONNECTED;
640 /* change state to open based on the status */
641 if (p_bta_data->open.status == BTA_AV_SUCCESS)
643 /* inform the application of the event */
644 btif_report_connection_state(state, &(btif_av_cb[index].peer_bda));
645 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_OPENED);
646 /* BTIF AV State updated, now check
647 * and update multicast state
649 btif_av_update_multicast_state(index);
652 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
654 /* if queued PLAY command, send it now */
655 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
656 (p_bta_data->open.status == BTA_AV_SUCCESS));
658 else if ((btif_av_cb[index].peer_sep == AVDT_TSEP_SRC) &&
659 (p_bta_data->open.status == BTA_AV_SUCCESS))
661 /* if queued PLAY command, send it now */
662 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
663 /* Bring up AVRCP connection too */
664 BTA_AvOpenRc(btif_av_cb[index].bta_handle);
666 btif_queue_advance();
669 case BTA_AV_REMOTE_CMD_EVT:
670 case BTA_AV_VENDOR_CMD_EVT:
671 case BTA_AV_META_MSG_EVT:
672 case BTA_AV_RC_FEAT_EVT:
673 case BTA_AV_REMOTE_RSP_EVT:
674 case BTA_AV_BROWSE_MSG_EVT:
675 btif_rc_handler(event, (tBTA_AV*)p_data);
678 case BTA_AV_RC_CLOSE_EVT:
679 BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
680 alarm_cancel(av_open_on_rc_timer);
681 btif_rc_handler(event, p_data);
684 case BTIF_AV_OFFLOAD_START_REQ_EVT:
685 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE");
686 btif_a2dp_on_offload_started(BTA_AV_FAIL);
690 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
691 dump_av_sm_event_name(event));
698 /*****************************************************************************
700 ** Function btif_av_state_opening_handler
702 ** Description Intermediate state managing events during establishment
705 ** Returns TRUE if event was processed, FALSE otherwise
707 *******************************************************************************/
709 static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data, int index)
712 BTIF_TRACE_IMP("%s event:%s flags %x on index = %d", __FUNCTION__,
713 dump_av_sm_event_name(event), btif_av_cb[index].flags, index);
716 case BTIF_SM_ENTER_EVT:
717 /* inform the application that we are entering connecting state */
718 if (bt_av_sink_callbacks != NULL)
720 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb,
721 BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb[index].peer_bda));
723 else if (bt_av_src_callbacks != NULL)
725 HAL_CBACK(bt_av_src_callbacks, connection_state_cb,
726 BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb[index].peer_bda));
730 case BTIF_SM_EXIT_EVT:
733 case BTA_AV_REJECT_EVT:
734 BTIF_TRACE_DEBUG(" Received BTA_AV_REJECT_EVT ");
735 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
736 &(btif_av_cb[index].peer_bda));
737 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
740 case BTA_AV_OPEN_EVT:
742 tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
743 btav_connection_state_t state;
744 btif_sm_state_t av_state;
745 BTIF_TRACE_DEBUG("status:%d, edr 0x%x, role: 0x%x",p_bta_data->open.status,
746 p_bta_data->open.edr, p_bta_data->open.role);
748 if (p_bta_data->open.status == BTA_AV_SUCCESS)
750 state = BTAV_CONNECTION_STATE_CONNECTED;
751 av_state = BTIF_AV_STATE_OPENED;
752 btif_av_cb[index].edr = p_bta_data->open.edr;
753 if (p_bta_data->open.role == HOST_ROLE_SLAVE)
755 btif_av_cb[index].is_slave = TRUE;
757 btif_av_cb[index].peer_sep = p_bta_data->open.sep;
758 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
759 if (p_bta_data->open.edr & BTA_AV_EDR_3MBPS)
761 BTIF_TRACE_DEBUG("remote supports 3 mbps");
762 btif_av_cb[index].edr_3mbps = TRUE;
764 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
765 btif_av_cb[index].channel_id = p_bta_data->open.stream_chnl_id;
766 BTIF_TRACE_DEBUG("streaming channel id updated as : 0x%x",
767 btif_av_cb[index].channel_id);
772 BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
773 p_bta_data->open.status );
774 /* Multicast: Check if connected to AVRC only device
775 * disconnect when Dual A2DP/Multicast is supported.
778 if ((btif_rc_get_connected_peer(peer_addr))
779 &&(!bdcmp(btif_av_cb[index].peer_bda.address, peer_addr)))
781 /* Do not disconnect AVRCP connection if A2DP
782 * connection failed due to SDP failure since remote
783 * may not support A2DP. In such case we will keep
784 * AVRCP only connection.
786 if (p_bta_data->open.status != BTA_AV_FAIL_SDP)
788 BTIF_TRACE_WARNING("Disconnecting AVRCP ");
789 BTA_AvCloseRc(btif_rc_get_connected_peer_handle(peer_addr));
793 BTIF_TRACE_WARNING("Keep AVRCP only connection");
796 state = BTAV_CONNECTION_STATE_DISCONNECTED;
797 av_state = BTIF_AV_STATE_IDLE;
800 /* inform the application of the event */
801 btif_report_connection_state(state, &(btif_av_cb[index].peer_bda));
802 /* change state to open/idle based on the status */
803 btif_sm_change_state(btif_av_cb[index].sm_handle, av_state);
804 /* Check if the other connected AV is playing,
805 * If YES, trigger DUAL Handoff. */
806 if (p_bta_data->open.status == BTA_AV_SUCCESS)
808 /* BTIF AV State updated, now check
809 * and update multicast state
811 btif_av_update_multicast_state(index);
813 /*This device should be now ready for all next playbacks*/
814 btif_av_cb[index].current_playing = TRUE;
815 if (enable_multicast == FALSE)
817 for (i = 0; i < btif_max_av_clients; i++)
819 //Other device is not current playing
821 btif_av_cb[i].current_playing = FALSE;
823 /* In A2dp Multicast, stack will take care of starting
824 * the stream on newly connected A2dp device. If Handoff
825 * is supported, trigger Handoff here. */
826 if (btif_av_is_playing())
828 BTIF_TRACE_DEBUG("Trigger Dual A2dp Handoff on %d", index);
829 btif_av_trigger_dual_handoff(TRUE, btif_av_cb[index].peer_bda.address);
832 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
834 /* if queued PLAY command, send it now */
835 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
836 (p_bta_data->open.status == BTA_AV_SUCCESS));
838 else if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC)
840 /* if queued PLAY command, send it now */
841 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
842 /* Bring up AVRCP connection too */
843 BTA_AvOpenRc(btif_av_cb[index].bta_handle);
846 btif_queue_advance();
849 case BTIF_AV_SINK_CONFIG_REQ_EVT:
851 btif_av_sink_config_req_t req;
852 // copy to avoid alignment problems
853 memcpy(&req, p_data, sizeof(req));
855 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
857 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
858 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb[index].peer_bda),
859 req.sample_rate, req.channel_count);
863 case BTIF_AV_CONNECT_REQ_EVT:
864 // Check for device, if same device which moved to opening then ignore callback
865 if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb[index].peer_bda),
866 sizeof(btif_av_cb[index].peer_bda)) == 0)
868 BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req", __func__);
869 btif_queue_advance();
874 BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request", __func__);
875 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t*)p_data);
876 btif_queue_advance();
880 case BTA_AV_PENDING_EVT:
881 // Check for device, if same device which moved to opening then ignore callback
882 if (memcmp (((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb[index].peer_bda),
883 sizeof(btif_av_cb[index].peer_bda)) == 0)
885 BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req", __func__);
890 BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request", __func__);
891 BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
895 case BTIF_AV_OFFLOAD_START_REQ_EVT:
896 btif_a2dp_on_offload_started(BTA_AV_FAIL);
897 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING");
900 case BTA_AV_CLOSE_EVT:
901 /* avdtp link is closed */
902 /* Check if any other device is playing
903 * and this is not the one.*/
904 if (!btif_av_is_playing())
906 btif_a2dp_on_stopped(NULL);
908 /* inform the application that we are disconnected */
909 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
910 &(btif_av_cb[index].peer_bda));
911 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
914 case BTIF_AV_DISCONNECT_REQ_EVT:
915 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
916 &(btif_av_cb[index].peer_bda));
917 BTA_AvClose(btif_av_cb[index].bta_handle);
918 btif_queue_advance();
919 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
922 case BTA_AV_RC_OPEN_EVT:
923 btif_rc_handler(event, p_data);;
926 CHECK_RC_EVENT(event, p_data);
929 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
930 dump_av_sm_event_name(event));
937 /*****************************************************************************
939 ** Function btif_av_state_closing_handler
941 ** Description Intermediate state managing events during closing
944 ** Returns TRUE if event was processed, FALSE otherwise
946 *******************************************************************************/
948 static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data, int index)
950 BTIF_TRACE_IMP("%s event:%s flags %x and index = %d", __FUNCTION__,
951 dump_av_sm_event_name(event), btif_av_cb[index].flags, index);
955 case BTIF_SM_ENTER_EVT:
956 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
958 /* Multicast/Soft Hand-off:
959 * If MC/SHO is enabled we need to keep/start playing on
962 if (btif_av_is_connected_on_other_idx(index))
964 if (btif_av_is_playing())
966 APPL_TRACE_DEBUG("Keep playing on other device");
970 APPL_TRACE_DEBUG("Not playing on other devie: Set Flush");
971 btif_a2dp_set_tx_flush(TRUE);
976 /* Single connections scenario:
977 * Immediately stop transmission of frames
978 * wait for audioflinger to stop a2dp
980 btif_a2dp_set_tx_flush(TRUE);
983 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC)
985 btif_a2dp_set_rx_flush(TRUE);
989 case BTA_AV_STOP_EVT:
990 case BTIF_AV_STOP_STREAM_REQ_EVT:
991 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
993 /* Dont stop in DUAL A2dp connections, as
994 * UIPC will keep waiting for Audio CTRL channel
995 * to get closed which is not required in Dual A2dp.
996 * We will stop only when only single A2dp conn is present.*/
997 if (btif_av_is_connected_on_other_idx(index))
999 if (!btif_av_is_playing())
1001 APPL_TRACE_WARNING("Suspend the AV Data channel");
1002 //Flush and close media channel
1003 btif_a2dp_set_tx_flush(TRUE);
1004 btif_media_task_stop_aa_req();
1009 /* immediately flush any pending tx frames while suspend is pending */
1010 APPL_TRACE_WARNING("Stop the AV Data channel");
1011 btif_a2dp_set_tx_flush(TRUE);
1012 btif_a2dp_on_stopped(NULL);
1015 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC)
1017 btif_a2dp_set_rx_flush(TRUE);
1018 btif_a2dp_on_stopped(NULL);
1022 case BTIF_SM_EXIT_EVT:
1025 case BTA_AV_CLOSE_EVT:
1027 /* inform the application that we are disconnecting */
1028 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb[index].peer_bda));
1030 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
1033 /* Handle the RC_CLOSE event for the cleanup */
1034 case BTA_AV_RC_CLOSE_EVT:
1035 btif_rc_handler(event, (tBTA_AV*)p_data);
1038 case BTIF_AV_OFFLOAD_START_REQ_EVT:
1039 btif_a2dp_on_offload_started(BTA_AV_FAIL);
1040 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing");
1044 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
1045 dump_av_sm_event_name(event));
1051 /*****************************************************************************
1053 ** Function btif_av_state_opened_handler
1055 ** Description Handles AV events while AVDTP is in OPEN state
1057 ** Returns TRUE if event was processed, FALSE otherwise
1059 *******************************************************************************/
1061 static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data, int index)
1063 tBTA_AV *p_av = (tBTA_AV*)p_data;
1065 BTIF_TRACE_IMP("%s event:%s flags %x and index = %d", __FUNCTION__,
1066 dump_av_sm_event_name(event), btif_av_cb[index].flags, index);
1068 if ((event == BTA_AV_REMOTE_CMD_EVT) &&
1069 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
1071 for (int i = 0; i < btif_max_av_clients; i++)
1073 if (btif_av_cb[i].flags & BTIF_AV_FLAG_REMOTE_SUSPEND)
1075 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY",
1077 btif_av_cb[i].flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
1084 case BTIF_SM_ENTER_EVT:
1085 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_STOP;
1086 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_START;
1089 case BTIF_SM_EXIT_EVT:
1092 case BTIF_AV_START_STREAM_REQ_EVT:
1093 /* update multicast state here if new device is connected
1094 * after A2dp connection. New A2dp device is connected
1096 btif_av_update_multicast_state(index);
1097 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC)
1099 BTA_AvStart(btif_av_cb[index].bta_handle);
1100 btif_av_cb[index].flags |= BTIF_AV_FLAG_PENDING_START;
1103 tBTIF_STATUS status = btif_a2dp_setup_codec(btif_av_cb[index].bta_handle);
1104 if (status == BTIF_SUCCESS)
1107 BTA_AvStart(btif_av_cb[index].bta_handle);
1108 if (enable_multicast == TRUE)
1110 /* In A2dp Multicast, DUT initiated stream request
1111 * should be true for all connected A2dp devices. */
1112 for (; idx < btif_max_av_clients; idx++)
1114 btif_av_cb[idx].flags |= BTIF_AV_FLAG_PENDING_START;
1119 btif_av_cb[index].flags |= BTIF_AV_FLAG_PENDING_START;
1122 else if (status == BTIF_ERROR_SRV_AV_CP_NOT_SUPPORTED)
1124 #if defined(BTA_AV_DISCONNECT_IF_NO_SCMS_T) && (BTA_AV_DISCONNECT_IF_NO_SCMS_T == TRUE)
1125 BTIF_TRACE_ERROR0("SCMST enabled, disconnect as remote does not support SCMST");
1126 BTA_AvDisconnect(btif_av_cb[index].peer_bda.address);
1128 BTIF_TRACE_WARNING("SCMST enabled, connecting to non SCMST SEP");
1129 BTA_AvStart(btif_av_cb[index].bta_handle);
1130 btif_av_cb[index].flags |= BTIF_AV_FLAG_PENDING_START;
1135 BTIF_TRACE_ERROR("## AV Disconnect## status : %x",status);
1136 BTA_AvDisconnect(btif_av_cb[index].peer_bda.address);
1140 case BTIF_AV_UPDATE_ENCODER_REQ_EVT:
1141 btif_a2dp_update_codec();
1144 case BTA_AV_START_EVT:
1146 BTIF_TRACE_DEBUG("BTA_AV_START_EVT status %d, suspending %d, init %d",
1147 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
1148 BTIF_TRACE_DEBUG("BTA_AV_START_EVT role: %d", p_av->start.role);
1149 if (p_av->start.role == HOST_ROLE_SLAVE)
1151 btif_av_cb[index].is_slave = TRUE;
1155 // update if we are master after role switch before start
1156 btif_av_cb[index].is_slave = FALSE;
1158 /* There can be role switch after device is connected,
1159 * hence check for role before starting multicast, and
1160 * disable if we are in slave role for any connection
1162 btif_av_update_multicast_state(index);
1164 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
1167 /* if remote tries to start a2dp when call is in progress, suspend it right away */
1168 if ((!(btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START)) && (!btif_hf_is_call_idle())) {
1169 BTIF_TRACE_EVENT("%s: trigger suspend as call is in progress!!", __FUNCTION__);
1170 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
1173 /* if remote tries to start a2dp when DUT is a2dp source
1174 * then suspend. In case a2dp is sink and call is active
1175 * then disconnect the AVDTP channel
1177 if (!(btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START))
1179 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1181 if (enable_multicast)
1183 /* Stack will start the playback on newly connected
1184 * A2dp device, if the playback is already happening on
1185 * other connected device.*/
1186 if (btif_av_is_playing())
1188 /* when HS2 is connected during HS1 playing, stack directly
1189 * sends start event hence update encoder so that least L2CAP
1190 * MTU is selected.*/
1191 //btif_a2dp_update_codec();
1192 BTIF_TRACE_DEBUG("%s: A2dp Multicast playback",
1195 /* initiate suspend if start is initiate by remote and multicast
1197 * Avoid suspend if stream is started as quick suspend-start
1198 * creates IOT issue, seen with SBH50.
1201 if (!p_av->start.initiator && !btif_av_is_playing())
1203 BTIF_TRACE_DEBUG("initiate suspend for remote start");
1204 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
1209 if ((btif_av_cb[index].flags & BTIF_AV_FLAG_REMOTE_SUSPEND))
1211 BTIF_TRACE_DEBUG("%s: clear remote suspend flag on remote start",
1213 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
1217 BTIF_TRACE_DEBUG("%s: trigger suspend as remote initiated!!",
1219 btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
1225 /* remain in open state if status failed */
1226 /* Multicast-soft Handoff:
1227 * START failed, cleanup Handoff flag.
1229 if (p_av->start.status != BTA_AV_SUCCESS)
1233 /* In case peer is A2DP SRC we do not want to ack commands on UIPC */
1234 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1236 if (btif_a2dp_on_started(&p_av->start,
1237 ((btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START) != 0),
1238 btif_av_cb[index].bta_handle))
1240 /* only clear pending flag after acknowledgement */
1241 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_START;
1244 /* Clear dual handoff flag */
1245 for (i = 0; i < btif_max_av_clients; i++)
1247 btif_av_cb[i].dual_handoff = FALSE;
1252 #ifndef AVK_BACKPORT
1253 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC)
1255 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
1259 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_STARTED);
1263 case BTIF_AV_DISCONNECT_REQ_EVT:
1264 BTA_AvClose(btif_av_cb[index].bta_handle);
1265 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC) {
1266 BTA_AvCloseRc(btif_av_cb[index].bta_handle);
1269 /* inform the application that we are disconnecting */
1270 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb[index].peer_bda));
1273 case BTA_AV_CLOSE_EVT:
1274 /* avdtp link is closed */
1275 /*Dont close the A2dp when Dual playback is happening*/
1276 if (btif_av_is_connected_on_other_idx(index))
1278 APPL_TRACE_WARNING("Conn is closing,close AV data channel");
1279 if (!btif_av_is_playing())
1281 APPL_TRACE_WARNING("Suspend the AV Data channel");
1282 /* ensure tx frames are immediately suspended */
1283 btif_a2dp_set_tx_flush(TRUE);
1284 btif_media_task_stop_aa_req();
1289 APPL_TRACE_WARNING("Stop the AV Data channel");
1290 btif_a2dp_on_stopped(NULL);
1293 /* inform the application that we are disconnected */
1294 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
1295 &(btif_av_cb[index].peer_bda));
1297 /* change state to idle, send acknowledgement if start is pending */
1298 if (btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START) {
1299 btif_a2dp_ack_fail();
1300 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_START;
1303 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
1306 case BTA_AV_RECONFIG_EVT:
1307 if((btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START) &&
1308 (p_av->reconfig.status == BTA_AV_SUCCESS))
1310 APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
1311 BTA_AvStart(btif_av_cb[index].bta_handle);
1313 else if(btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START)
1315 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_START;
1316 btif_a2dp_ack_fail();
1320 case BTIF_AV_CONNECT_REQ_EVT:
1321 if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb[index].peer_bda),
1322 sizeof(btif_av_cb[index].peer_bda)) == 0)
1324 BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device", __func__);
1328 BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req", __func__);
1329 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
1330 (bt_bdaddr_t*)p_data);
1332 btif_queue_advance();
1335 case BTIF_AV_OFFLOAD_START_REQ_EVT:
1336 btif_a2dp_on_offload_started(BTA_AV_FAIL);
1337 BTIF_TRACE_ERROR("BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened");
1340 case BTA_AV_RC_OPEN_EVT:
1341 btif_av_check_rc_connection_priority(p_data);
1343 CHECK_RC_EVENT(event, p_data);
1346 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
1347 dump_av_sm_event_name(event));
1354 /*****************************************************************************
1356 ** Function btif_av_state_started_handler
1358 ** Description Handles AV events while A2DP stream is started
1360 ** Returns TRUE if event was processed, FALSE otherwise
1362 *******************************************************************************/
1364 static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data, int index)
1366 tBTA_AV *p_av = (tBTA_AV*)p_data;
1367 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
1370 BTIF_TRACE_IMP("%s event:%s flags %x index =%d", __FUNCTION__,
1371 dump_av_sm_event_name(event), btif_av_cb[index].flags, index);
1375 case BTIF_SM_ENTER_EVT:
1376 /*Ack from entry point of started handler instead of open state to avoid race condition*/
1377 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1379 if (btif_a2dp_on_started(&p_av->start,
1380 ((btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START) != 0),
1381 btif_av_cb[index].bta_handle))
1383 /* only clear pending flag after acknowledgement */
1384 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_START;
1388 /* Already changed state to started, send acknowledgement if start is pending */
1389 if (btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START) {
1390 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1391 btif_a2dp_on_started(NULL, TRUE, btif_av_cb[index].bta_handle);
1392 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_PENDING_START;
1395 /* we are again in started state, clear any remote suspend flags */
1396 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
1398 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb[index].peer_bda));
1399 btif_av_cb[index].is_device_playing = TRUE;
1401 /* increase the a2dp consumer task priority temporarily when start
1402 ** audio playing, to avoid overflow the audio packet queue. */
1403 adjust_priority_a2dp(TRUE);
1405 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC)
1407 btif_av_request_audio_focus(TRUE);
1410 //Clear Dual Handoff for all SCBs
1411 for (i = 0; i < btif_max_av_clients; i++)
1413 btif_av_cb[i].dual_handoff = FALSE;
1414 //Other device is not current playing
1416 btif_av_cb[i].current_playing = FALSE;
1418 //This is latest device to play now
1419 btif_av_cb[index].current_playing = TRUE;
1422 case BTIF_SM_EXIT_EVT:
1423 /* restore the a2dp consumer task priority when stop audio playing. */
1424 adjust_priority_a2dp(FALSE);
1428 case BTIF_AV_START_STREAM_REQ_EVT:
1429 /* we were remotely started, just ack back the local request */
1430 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1431 btif_a2dp_on_started(NULL, TRUE, btif_av_cb[index].bta_handle);
1434 case BTIF_AV_UPDATE_ENCODER_REQ_EVT:
1435 btif_a2dp_update_codec();
1438 /* fixme -- use suspend = true always to work around issue with BTA AV */
1439 case BTIF_AV_STOP_STREAM_REQ_EVT:
1440 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
1442 /* set pending flag to ensure btif task is not trying to restart
1443 * stream while suspend is in progress.
1444 * Multicast: If streaming is happening on both devices, we need
1445 * to update flag for both connections as SUSPEND request will
1446 * be sent to only one stream as internally BTA takes care of
1447 * suspending both streams.
1449 for(i = 0; i < btif_max_av_clients; i++)
1451 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
1452 if (state == BTIF_AV_STATE_STARTED)
1454 btif_av_cb[i].flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
1458 /* if we were remotely suspended but suspend locally, local suspend
1460 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
1462 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1464 /* immediately stop transmission of frames while suspend is pending */
1465 btif_a2dp_set_tx_flush(TRUE);
1468 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC) {
1469 btif_a2dp_set_rx_flush(TRUE);
1470 btif_a2dp_on_stopped(NULL);
1473 BTA_AvStop(TRUE, btif_av_cb[index].bta_handle);
1476 case BTIF_AV_DISCONNECT_REQ_EVT:
1478 //Now it is not the current playing
1479 btif_av_cb[index].current_playing = FALSE;
1480 btif_av_update_current_playing_device(index);
1481 btif_rc_clear_priority(btif_av_cb[index].peer_bda.address);
1482 if (bt_split_a2dp_enabled && btif_av_is_connected_on_other_idx(index))
1484 /*Fake handoff state to switch streaming to other coddeced
1486 btif_av_cb[index].dual_handoff = TRUE;
1488 /* request avdtp to close */
1489 BTA_AvClose(btif_av_cb[index].bta_handle);
1490 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SRC) {
1491 BTA_AvCloseRc(btif_av_cb[index].bta_handle);
1494 /* inform the application that we are disconnecting */
1495 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb[index].peer_bda));
1497 /* wait in closing state until fully closed */
1498 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_CLOSING);
1499 if (bt_split_a2dp_enabled &&
1500 btif_av_is_connected_on_other_idx(index))
1502 BTIF_TRACE_DEBUG("%s: Notify framework to reconfig",__func__);
1503 int idx = btif_av_get_other_connected_idx(index);
1504 /* Fix for below Klockwork Issue
1505 * Array 'btif_av_cb' of size 2 may use index value(s) -1 */
1506 if (idx != INVALID_INDEX)
1508 HAL_CBACK(bt_av_src_callbacks, reconfig_a2dp_trigger_cb, 1,
1509 &(btif_av_cb[idx].peer_bda));
1514 case BTA_AV_SUSPEND_EVT:
1516 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
1517 p_av->suspend.status, p_av->suspend.initiator);
1518 //Check if this suspend is due to DUAL_Handoff
1519 if ((btif_av_cb[index].dual_handoff) &&
1520 (p_av->suspend.status == BTA_AV_SUCCESS))
1522 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT: Dual handoff");
1523 btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0);
1525 if (p_av->suspend.initiator != TRUE)
1527 /* remote suspend, notify HAL and await audioflinger to
1528 * suspend/stop stream
1529 * set remote suspend flag to block media task from restarting
1530 * stream only if we did not already initiate a local suspend
1531 * set remote suspend flag before suspending stream as in race conditions
1532 * when stream is suspended, but flag is things ge tossed up
1534 BTIF_TRACE_EVENT("Clear before suspending");
1535 if ((btif_av_cb[index].flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
1536 btif_av_cb[index].flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
1537 for (int i = 0; i < btif_max_av_clients; i++)
1539 if ((i != index) && btif_av_get_ongoing_multicast())
1541 multicast_disabled = TRUE;
1542 btif_av_update_multicast_state(index);
1543 BTIF_TRACE_EVENT("Initiate suspend for other HS also");
1544 btif_sm_dispatch(btif_av_cb[i].sm_handle,
1545 BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL);
1550 /* a2dp suspended, stop media task until resumed */
1551 /* Multicast: If streaming on other device, don't call onsuspended
1552 * as it unblocks the audio process and audio process may send
1553 * subsequent commands and create problem during the time where we
1554 * still did not receive response for SUSPEND sent to other device.
1555 * Keep the suspend failure handling untouched and handle
1556 * only success case to check and avoid calling onsuspended.
1558 if ((p_av->suspend.status != BTA_AV_SUCCESS) ||
1559 !btif_av_is_playing_on_other_idx(index))
1561 btif_a2dp_on_suspended(&p_av->suspend);
1563 else if(btif_av_is_playing_on_other_idx(index))
1565 BTIF_TRACE_DEBUG("Other device not suspended, don't ack the suspend");
1568 /* if not successful, remain in current state */
1569 if (p_av->suspend.status != BTA_AV_SUCCESS)
1571 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
1573 if (btif_av_cb[index].peer_sep == AVDT_TSEP_SNK)
1575 /* suspend failed, reset back tx flush state */
1576 btif_a2dp_set_tx_flush(FALSE);
1581 if (p_av->suspend.initiator != TRUE)
1583 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb[index].peer_bda));
1587 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb[index].peer_bda));
1589 btif_av_cb[index].is_device_playing = FALSE;
1590 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_OPENED);
1592 /* suspend completed and state changed, clear pending status */
1593 btif_av_cb[index].flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
1596 case BTA_AV_STOP_EVT:
1598 btif_av_cb[index].flags |= BTIF_AV_FLAG_PENDING_STOP;
1599 btif_av_cb[index].current_playing = FALSE;
1600 if (btif_av_is_connected_on_other_idx(index))
1602 if (enable_multicast == FALSE)
1604 APPL_TRACE_WARNING("other Idx is connected, move to SUSPENDED");
1605 if (!bt_split_a2dp_enabled) {
1606 btif_rc_send_pause_command();
1608 btif_a2dp_on_stopped(&p_av->suspend);
1613 APPL_TRACE_WARNING("Stop the AV Data channel as no connection is present");
1614 btif_a2dp_on_stopped(&p_av->suspend);
1616 btif_av_cb[index].is_device_playing = FALSE;
1619 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb[index].peer_bda));
1620 /* if stop was successful, change state to open */
1621 if (p_av->suspend.status == BTA_AV_SUCCESS)
1622 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_OPENED);
1624 if (bt_split_a2dp_enabled &&
1625 btif_av_is_connected_on_other_idx(index))
1627 /*Fake handoff state to switch streaming to other coddeced
1629 btif_av_cb[index].dual_handoff = TRUE;
1630 BTIF_TRACE_DEBUG("%s: Notify framework to reconfig",__func__);
1631 int idx = btif_av_get_other_connected_idx(index);
1632 /* Fix for below Klockwork Issue
1633 * Array 'btif_av_cb' of size 2 may use index value(s) -1 */
1634 if (idx != INVALID_INDEX)
1636 HAL_CBACK(bt_av_src_callbacks, reconfig_a2dp_trigger_cb, 1,
1637 &(btif_av_cb[idx].peer_bda));
1643 case BTA_AV_CLOSE_EVT:
1645 btif_av_cb[index].flags |= BTIF_AV_FLAG_PENDING_STOP;
1647 /* avdtp link is closed */
1648 APPL_TRACE_WARNING("Stop the AV Data channel");
1649 btif_a2dp_on_stopped(NULL);
1651 /* inform the application that we are disconnected */
1652 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
1653 &(btif_av_cb[index].peer_bda));
1655 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
1658 case BTA_AV_RC_OPEN_EVT:
1659 btif_av_check_rc_connection_priority(p_data);
1662 case BTIF_AV_OFFLOAD_START_REQ_EVT:
1663 BTA_AvOffloadStart(btif_av_cb[index].bta_handle);
1666 case BTA_AV_OFFLOAD_START_RSP_EVT:
1667 btif_a2dp_on_offload_started(p_av->status);
1670 CHECK_RC_EVENT(event, p_data);
1673 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
1674 dump_av_sm_event_name(event));
1682 void btif_av_event_deep_copy(UINT16 event, char *p_dest, char *p_src)
1684 tBTA_AV *av_src = (tBTA_AV *)p_src;
1685 tBTA_AV *av_dest = (tBTA_AV *)p_dest;
1687 // First copy the structure
1688 maybe_non_aligned_memcpy(av_dest, av_src, sizeof(*av_src));
1692 case BTA_AV_META_MSG_EVT:
1693 if (av_src->meta_msg.p_data && av_src->meta_msg.len)
1695 av_dest->meta_msg.p_data = osi_calloc(av_src->meta_msg.len);
1696 memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data,
1697 av_src->meta_msg.len);
1700 if (av_src->meta_msg.p_msg)
1702 av_dest->meta_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
1703 memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg,
1706 if (av_src->meta_msg.p_msg->vendor.p_vendor_data &&
1707 av_src->meta_msg.p_msg->vendor.vendor_len)
1709 av_dest->meta_msg.p_msg->vendor.p_vendor_data = osi_calloc(
1710 av_src->meta_msg.p_msg->vendor.vendor_len);
1711 memcpy(av_dest->meta_msg.p_msg->vendor.p_vendor_data,
1712 av_src->meta_msg.p_msg->vendor.p_vendor_data,
1713 av_src->meta_msg.p_msg->vendor.vendor_len);
1717 case BTA_AV_BROWSE_MSG_EVT:
1718 if (av_src->browse_msg.p_msg)
1720 av_dest->browse_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
1721 assert(av_dest->browse_msg.p_msg);
1722 memcpy(av_dest->browse_msg.p_msg, av_src->browse_msg.p_msg, sizeof(tAVRC_MSG));
1724 if (av_src->browse_msg.p_msg->browse.p_browse_data &&
1725 av_src->browse_msg.p_msg->browse.browse_len)
1727 av_dest->browse_msg.p_msg->browse.p_browse_data = osi_calloc(
1728 av_src->browse_msg.p_msg->browse.browse_len);
1729 assert(av_dest->browse_msg.p_msg->browse.p_browse_data);
1730 memcpy(av_dest->browse_msg.p_msg->browse.p_browse_data,
1731 av_src->browse_msg.p_msg->browse.p_browse_data,
1732 av_src->browse_msg.p_msg->browse.browse_len);
1742 static void btif_av_event_free_data(btif_sm_event_t event, void *p_data)
1746 case BTA_AV_META_MSG_EVT:
1748 tBTA_AV *av = (tBTA_AV *)p_data;
1749 osi_free_and_reset((void **)&av->meta_msg.p_data);
1751 if (av->meta_msg.p_msg) {
1752 osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
1753 osi_free_and_reset((void **)&av->meta_msg.p_msg);
1757 case BTA_AV_BROWSE_MSG_EVT:
1759 tBTA_AV *av = (tBTA_AV*)p_data;
1761 if (av->browse_msg.p_msg)
1763 if (av->browse_msg.p_msg->browse.p_browse_data)
1764 osi_free(av->browse_msg.p_msg->browse.p_browse_data);
1765 osi_free(av->browse_msg.p_msg);
1775 /*****************************************************************************
1776 ** Local event handlers
1777 ******************************************************************************/
1779 static void btif_av_handle_event(UINT16 event, char* p_param)
1782 tBTA_AV *p_bta_data = (tBTA_AV*)p_param;
1783 bt_bdaddr_t * bt_addr;
1789 case BTIF_AV_INIT_REQ_EVT:
1790 BTIF_TRACE_IMP("%s: BTIF_AV_INIT_REQ_EVT", __FUNCTION__);
1791 if(btif_a2dp_start_media_task())
1792 btif_a2dp_on_init();
1794 /*events from Upper layer and Media Task*/
1795 case BTIF_AV_CLEANUP_REQ_EVT: /*Clean up to be called on default index*/
1796 BTIF_TRACE_IMP("%s: BTIF_AV_CLEANUP_REQ_EVT", __FUNCTION__);
1797 uuid = (int)*p_param;
1798 if (uuid == BTA_A2DP_SOURCE_SERVICE_ID)
1800 if (bt_av_src_callbacks)
1802 bt_av_src_callbacks = NULL;
1803 if (bt_av_sink_callbacks != NULL)
1809 if (bt_av_sink_callbacks)
1811 bt_av_sink_callbacks = NULL;
1812 if (bt_av_src_callbacks != NULL)
1817 btif_a2dp_stop_media_task();
1819 case BTIF_AV_CONNECT_REQ_EVT:
1821 case BTIF_AV_DISCONNECT_REQ_EVT:
1822 /*Bd address passed should help us in getting the handle*/
1823 bt_addr = (bt_bdaddr_t *)p_param;
1824 index = btif_av_idx_by_bdaddr(bt_addr->address);
1825 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
1826 if (bt_split_a2dp_enabled && (btif_av_get_current_playing_dev_idx() == index))
1828 BTIF_TRACE_DEBUG("%s:Disconnecting playing device,send VS STOP",__func__);
1829 btif_media_on_stop_vendor_command();
1833 case BTIF_AV_UPDATE_ENCODER_REQ_EVT:
1834 case BTIF_AV_START_STREAM_REQ_EVT:
1835 /* Get the last connected device on which START can be issued
1836 * Get the Dual A2dp Handoff Device first, if none is present,
1837 * go for lastest connected.
1838 * In A2dp Multicast, the index selected can be any of the
1839 * connected device. Stack will ensure to START the steaming
1840 * on both the devices. */
1841 index = btif_get_latest_device_idx_to_start();
1843 case BTIF_AV_STOP_STREAM_REQ_EVT:
1844 case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
1845 /*Should be handled by current STARTED*/
1846 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
1847 if (bt_split_a2dp_enabled)
1848 btif_media_on_stop_vendor_command();
1850 index = btif_get_latest_playing_device_idx();
1852 /*Events from the stack, BTA*/
1853 case BTA_AV_ENABLE_EVT:
1856 case BTA_AV_REGISTER_EVT:
1857 index = HANDLE_TO_INDEX(p_bta_data->registr.hndl);
1859 case BTA_AV_OPEN_EVT:
1860 index = HANDLE_TO_INDEX(p_bta_data->open.hndl);
1862 case BTA_AV_ROLE_CHANGED_EVT:
1863 index = HANDLE_TO_INDEX(p_bta_data->role_changed.hndl);
1864 role = p_bta_data->role_changed.new_role;
1865 BTIF_TRACE_EVENT("Role change: 0x%x: new role: %s",
1866 p_bta_data->role_changed.hndl, (role == HOST_ROLE_SLAVE) ? "Slave" : "Master");
1867 if (index >= 0 && index < btif_max_av_clients)
1869 btif_av_cb[index].is_slave = (role == HOST_ROLE_SLAVE) ? TRUE : FALSE;
1870 btif_av_update_multicast_state(index);
1874 BTIF_TRACE_ERROR("%s: Invalid index for connection", __FUNCTION__);
1877 case BTA_AV_PENDING_EVT:
1878 index = HANDLE_TO_INDEX(p_bta_data->pend.hndl);
1880 case BTA_AV_REJECT_EVT:
1881 index = HANDLE_TO_INDEX(p_bta_data->reject.hndl);
1883 case BTA_AV_STOP_EVT:
1884 index = HANDLE_TO_INDEX(p_bta_data->suspend.hndl);
1886 case BTA_AV_CLOSE_EVT:
1887 index = HANDLE_TO_INDEX(p_bta_data->close.hndl);
1889 case BTA_AV_START_EVT:
1890 index = HANDLE_TO_INDEX(p_bta_data->start.hndl);
1892 case BTA_AV_RECONFIG_EVT:
1893 index = HANDLE_TO_INDEX(p_bta_data->reconfig.hndl);
1895 case BTA_AV_SUSPEND_EVT:
1896 index = HANDLE_TO_INDEX(p_bta_data->suspend.hndl);
1899 /* Handle all RC events on default index. RC handling should take
1900 * care of the events. All events come with BD Address
1901 * Handled well in AV Opening, opened and started state
1902 * AV Idle handler needs to take care of this event properly.
1904 case BTA_AV_RC_OPEN_EVT:
1905 index = btif_av_get_valid_idx_for_rc_events(p_bta_data->rc_open.peer_addr,
1906 p_bta_data->rc_open.rc_handle);
1908 case BTA_AV_RC_CLOSE_EVT:
1909 /* If there is no entry in the connection table
1910 * RC handler has to be called for cleanup.
1911 * Directly call the RC handler as we cannot
1912 * associate any AV handle to it.
1914 index = btif_av_idx_by_bdaddr(p_bta_data->rc_open.peer_addr);
1915 if (index == btif_max_av_clients)
1917 btif_rc_handler(event, p_bta_data);
1920 /* Let the RC handler decide on these passthrough cmds
1921 * Use rc_handle to get the active AV device and use that mapping.
1923 case BTA_AV_REMOTE_CMD_EVT:
1924 case BTA_AV_VENDOR_CMD_EVT:
1925 case BTA_AV_META_MSG_EVT:
1926 case BTA_AV_RC_FEAT_EVT:
1927 case BTA_AV_BROWSE_MSG_EVT:
1929 BTIF_TRACE_EVENT("RC events: on index = %d", index);
1932 BTIF_TRACE_ERROR("Unhandled event = %d", event);
1935 BTIF_TRACE_DEBUG("Handle the AV event = %x on index = %d", event, index);
1936 if (index >= 0 && index < btif_max_av_clients)
1937 btif_sm_dispatch(btif_av_cb[index].sm_handle, event, (void*)p_param);
1939 BTIF_TRACE_ERROR("Unhandled Index = %d", index);
1940 btif_av_event_free_data(event, p_param);
1944 /*******************************************************************************
1946 ** Function btif_av_get_valid_idx
1948 ** Description Check the validity of the current index for the connection
1952 *******************************************************************************/
1954 static BOOLEAN btif_av_get_valid_idx(int idx)
1956 btif_sm_state_t state = btif_sm_get_state(btif_av_cb[idx].sm_handle);
1957 return ((state == BTIF_AV_STATE_OPENED) ||
1958 (state == BTIF_AV_STATE_STARTED) ||
1959 (state == BTIF_AV_STATE_OPENING));
1962 /*******************************************************************************
1964 ** Function btif_av_idx_by_bdaddr
1966 ** Description Get the index corresponding to BD addr
1970 *******************************************************************************/
1972 static UINT8 btif_av_idx_by_bdaddr(BD_ADDR bd_addr)
1975 for (i = 0; i < btif_max_av_clients; i++)
1978 btif_av_cb[i].peer_bda.address) == 0))
1984 BOOLEAN btif_av_is_current_device(BD_ADDR address)
1988 index = btif_av_idx_by_bdaddr(address);
1989 if((index < btif_max_av_clients) && btif_av_cb[index].current_playing)
1996 /*******************************************************************************
1998 ** Function btif_get_latest_device_idx_to_start
2000 ** Description Get the index of the AV where streaming is to be started
2004 *******************************************************************************/
2006 static int btif_get_latest_device_idx_to_start()
2009 BD_ADDR playing_address;
2011 /* Get the device which sent PLAY command
2012 * If found, START on that index.
2014 memset(playing_address, 0, sizeof(BD_ADDR));
2015 btif_rc_get_playing_device(playing_address);
2016 if (bdcmp(playing_address, bd_addr_null) != 0)
2018 /* Got some valid Playing device.
2019 * Get the AV index for this device.
2021 i = btif_av_idx_by_bdaddr(playing_address);
2022 if (i == btif_max_av_clients)
2023 return btif_max_av_clients;
2024 BTIF_TRACE_EVENT("Got some valid Playing device; %d", i);
2025 /*Clear the Current playing device*/
2026 for (j = 0; j < btif_max_av_clients; j++)
2029 btif_av_cb[j].current_playing = FALSE;
2031 /*Clear the Play command in RC*/
2032 btif_rc_clear_playing_state(FALSE);
2036 /*No playing device, get the latest*/
2037 for (i = 0; i < btif_max_av_clients; i++)
2039 if (btif_av_cb[i].current_playing)
2042 if (i == btif_max_av_clients)
2044 BTIF_TRACE_ERROR("Play on default");
2045 i = 0; /*play on default*/
2050 /*******************************************************************************
2052 ** Function btif_get_latest_playing_device_idx
2054 ** Description Get the index of AV where streaming is happening
2058 *******************************************************************************/
2060 int btif_get_latest_playing_device_idx()
2063 btif_sm_state_t state;
2064 for (i = 0; i < btif_max_av_clients; i++)
2066 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
2067 if (state == BTIF_AV_STATE_STARTED)
2075 /*******************************************************************************
2077 ** Function btif_av_is_playing
2079 ** Description Is AV in streaming state
2083 *******************************************************************************/
2085 BOOLEAN btif_av_is_playing()
2088 for (i = 0; i < btif_max_av_clients; i++)
2090 btif_av_cb[i].state = btif_sm_get_state(btif_av_cb[i].sm_handle);
2091 if (btif_av_cb[i].state == BTIF_AV_STATE_STARTED)
2093 BTIF_TRACE_EVENT("btif_av_is_playing on index= %d", i);
2100 /*******************************************************************************
2102 ** Function btif_get_conn_state_of_device
2104 ** Description Returns the state of AV scb
2108 *******************************************************************************/
2110 static int btif_get_conn_state_of_device(BD_ADDR address)
2112 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
2114 for (i = 0; i < btif_max_av_clients; i++)
2117 btif_av_cb[i].peer_bda.address) == 0))
2119 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
2120 BTIF_TRACE_EVENT("BD Found: %02X %02X %02X %02X %02X %02X :state: %s",
2121 address[5], address[4], address[3],
2122 address[2], address[1], address[0],
2123 dump_av_sm_state_name(state));
2129 /*******************************************************************************
2131 ** Function btif_av_get_valid_idx_for_rc_events
2133 ** Description gets th valid index for the RC event address
2137 *******************************************************************************/
2139 static int btif_av_get_valid_idx_for_rc_events(BD_ADDR bd_addr, int rc_handle)
2142 /* First try to find if it is first event in AV IF
2143 * both the handles would be in IDLE state, pick the first
2144 * If we get second RC event while processing the priority
2145 * for the first, reject the second connection. */
2147 /*Get the index from connected SCBs*/
2148 index = btif_av_idx_by_bdaddr(bd_addr);
2149 if (index == btif_max_av_clients)
2151 /* None of the SCBS matched
2152 * Allocate free SCB, null address SCB*/
2153 index = btif_av_idx_by_bdaddr(bd_null);
2154 BTIF_TRACE_EVENT("btif_av_get_valid_idx_for_rc_events is %d", index);
2155 if (index >= btif_max_av_clients)
2157 BTIF_TRACE_EVENT("disconnect only AVRCP device rc_handle %d", rc_handle);
2158 BTA_AvCloseRc(rc_handle);
2164 /*******************************************************************************
2166 ** Function btif_av_check_rc_connection_priority
2168 ** Description Handles Priority callback for RC connections
2172 *******************************************************************************/
2174 static void btif_av_check_rc_connection_priority(void *p_data)
2176 bt_bdaddr_t peer_bda;
2178 /*Check if it is for same AV device*/
2179 if (btif_av_is_device_connected(((tBTA_AV*)p_data)->rc_open.peer_addr))
2181 /*AV is connected */
2182 BTIF_TRACE_DEBUG("AV is connected, process RC connect event");
2183 btif_rc_handler(BTA_AV_RC_OPEN_EVT, (tBTA_AV*)p_data);
2186 BTIF_TRACE_DEBUG("btif_av_check_rc_connection_priority");
2187 bdcpy(peer_bda.address, ((tBTA_AV*)p_data)->rc_open.peer_addr);
2189 if (idle_rc_event != 0)
2191 BTIF_TRACE_DEBUG("Processing another RC Event ");
2194 idle_rc_event = BTA_AV_RC_OPEN_EVT;
2195 memcpy(&idle_rc_data, ((tBTA_AV*)p_data), sizeof(tBTA_AV));
2196 if (((tBTA_AV*)p_data)->rc_open.status == BTA_AV_SUCCESS)
2198 BTIF_TRACE_DEBUG("RC conn is success ");
2199 if (bt_av_src_callbacks != NULL)
2201 BTIF_TRACE_DEBUG(" Check Device priority");
2202 HAL_CBACK(bt_av_src_callbacks, connection_priority_cb,
2209 memset(&idle_rc_data, 0, sizeof(tBTA_AV));
2215 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
2217 btif_transfer_context(btif_av_handle_event, event,
2218 (char*)p_data, sizeof(tBTA_AV), btif_av_event_deep_copy);
2221 /*Called only in case of A2dp SInk, which runs on index 0*/
2222 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
2224 btif_sm_state_t state;
2226 tA2D_STATUS a2d_status;
2227 tA2D_SBC_CIE sbc_cie;
2228 btif_av_sink_config_req_t config_req;
2231 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
2233 state= btif_sm_get_state(btif_av_cb[index].sm_handle);
2234 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
2235 (state == BTIF_AV_STATE_OPENED) )
2237 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
2238 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
2244 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
2245 /* send a command to BT Media Task */
2246 btif_reset_decoder((UINT8*)(p_data->avk_config.codec_info));
2247 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)(p_data->avk_config.codec_info), FALSE);
2248 if (a2d_status == A2D_SUCCESS) {
2249 /* Switch to BTIF context */
2250 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
2251 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
2252 memcpy(&config_req.peer_bd,(UINT8*)(p_data->avk_config.bd_addr),
2253 sizeof(config_req.peer_bd));
2254 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
2255 (char*)&config_req, sizeof(config_req), NULL);
2257 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
2262 /******************************************************************************
2263 ** Function a2dp_offload_codec_cap_parser
2265 ** Description Parse the offload supported codec capability during init
2268 *****************************************************************************/
2269 static void a2dp_offload_codec_cap_parser(const char *value)
2272 char *tmp_token = NULL;
2273 /* Fix for below Klockwork Issue
2274 * 'strtok' has been deprecated; replace it with a safe function. */
2275 tok = strtok_r((char*)value, "-", &tmp_token);
2278 if (strcmp(tok,"sbc") == 0)
2280 BTIF_TRACE_ERROR("%s: SBC offload supported",__func__);
2281 btif_av_codec_offload.sbc_offload = TRUE;
2283 else if (strcmp(tok,"aptx") == 0)
2285 BTIF_TRACE_ERROR("%s: aptX offload supported",__func__);
2286 btif_av_codec_offload.aptx_offload = TRUE;
2288 else if (strcmp(tok,"aac") == 0)
2290 BTIF_TRACE_ERROR("%s: AAC offload supported",__func__);
2291 btif_av_codec_offload.aac_offload = TRUE;
2293 else if (strcmp(tok,"aptxhd") == 0)
2295 BTIF_TRACE_ERROR("%s: APTXHD offload supported",__func__);
2296 btif_av_codec_offload.aptxhd_offload = TRUE;
2298 tok = strtok_r(NULL, "-", &tmp_token);
2302 /******************************************************************************
2303 ** Function get_offload_codec_capabilities
2305 ** Description Read offload supported codecs
2306 ** To set offload capabilities:
2307 ** adb shell setprop persist.bt.a2dp_offload_cap "sbc-aptx"
2310 *****************************************************************************/
2311 static void get_offload_codec_capabilities(const char* codec_cap)
2313 BTIF_TRACE_DEBUG("%s",__func__);
2314 a2dp_offload_codec_cap_parser(codec_cap);
2317 /*******************************************************************************
2319 ** Function btif_av_init
2321 ** Description Initializes btif AV if not already done
2323 ** Returns bt_status_t
2325 *******************************************************************************/
2327 bt_status_t btif_av_init(int service_id)
2330 if (btif_av_cb[0].sm_handle == NULL)
2332 alarm_free(av_open_on_rc_timer);
2333 av_open_on_rc_timer = alarm_new("btif_av.av_open_on_rc_timer");
2334 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
2335 if(!btif_a2dp_is_media_task_stopped())
2336 return BT_STATUS_FAIL;
2337 btif_av_cb[0].service = service_id;
2339 /* Also initialize the AV state machine */
2340 for (i = 0; i < btif_max_av_clients; i++)
2342 btif_av_cb[i].sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers,
2343 BTIF_AV_STATE_IDLE, i);
2346 btif_transfer_context(btif_av_handle_event, BTIF_AV_INIT_REQ_EVT,
2347 (char*)&service_id, sizeof(int), NULL);
2349 btif_enable_service(service_id);
2352 return BT_STATUS_SUCCESS;
2355 /*******************************************************************************
2357 ** Function init_src
2359 ** Description Initializes the AV interface for source mode
2361 ** Returns bt_status_t
2363 *******************************************************************************/
2365 static bt_status_t init_src(btav_callbacks_t* callbacks, int max_a2dp_connections,
2366 int a2dp_multicast_state, const char* offload_cap)
2370 BTIF_TRACE_EVENT("%s with max conn = %d", __FUNCTION__, max_a2dp_connections);
2372 if (bt_av_sink_callbacks != NULL) {
2373 // already did btif_av_init()
2374 status = BT_STATUS_SUCCESS;
2378 if (a2dp_multicast_state)
2380 is_multicast_supported = TRUE;
2384 bt_split_a2dp_enabled = TRUE;
2385 get_offload_codec_capabilities(offload_cap);
2386 is_multicast_supported = FALSE; //Disable multicast in Split A2dp mode
2388 btif_max_av_clients = max_a2dp_connections;
2389 status = btif_av_init(BTA_A2DP_SOURCE_SERVICE_ID);
2392 if (status == BT_STATUS_SUCCESS) {
2393 bt_av_src_callbacks = callbacks;
2399 /*******************************************************************************
2401 ** Function init_sink
2403 ** Description Initializes the AV interface for sink mode
2405 ** Returns bt_status_t
2407 *******************************************************************************/
2409 static bt_status_t init_sink(btav_callbacks_t* callbacks, int max,
2410 int a2dp_multicast_state, const char *offload_cap)
2414 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2416 if (bt_av_src_callbacks != NULL) {
2417 // already did btif_av_init()
2418 status = BT_STATUS_SUCCESS;
2422 enable_multicast = FALSE; // Clear multicast flag for sink
2423 bt_split_a2dp_enabled = FALSE; //Clear split a2dp for sink
2426 BTIF_TRACE_ERROR("Only one Sink can be initialized");
2429 btif_max_av_clients = max; //Should be 1
2430 status = btif_av_init(BTA_A2DP_SINK_SERVICE_ID);
2433 if (status == BT_STATUS_SUCCESS) {
2434 bt_av_sink_callbacks = callbacks;
2435 //BTA_AvEnable_Sink(TRUE);
2441 #ifdef USE_AUDIO_TRACK
2442 /*******************************************************************************
2444 ** Function update_audio_focus_state
2446 ** Description Updates the final focus state reported by components calling
2451 *******************************************************************************/
2452 void update_audio_focus_state(int state)
2454 BTIF_TRACE_DEBUG("%s state %d ",__func__, state);
2455 btif_a2dp_set_audio_focus_state(state);
2458 /*******************************************************************************
2460 ** Function update_audio_track_gain
2462 ** Description Updates the track gain (used for ducking).
2466 *******************************************************************************/
2467 void update_audio_track_gain(float gain)
2469 BTIF_TRACE_DEBUG("%s gain %f ",__func__, gain);
2470 btif_a2dp_set_audio_track_gain(gain);
2475 void btif_get_latest_playing_device(BD_ADDR address)
2478 index = btif_get_latest_playing_device_idx();
2479 if (index < btif_max_av_clients)
2482 bdcpy(address, btif_av_cb[index].peer_bda.address);
2486 bdcpy(address, bd_null);
2490 BOOLEAN btif_av_is_device_connected(BD_ADDR address)
2492 btif_sm_state_t state = btif_get_conn_state_of_device(address);
2494 if ((state == BTIF_AV_STATE_OPENED) ||
2495 (state == BTIF_AV_STATE_STARTED))
2501 /*This function will trigger remote suspend for currently
2502 * playing device and then initiate START on Handoff device
2503 * whose address is passed as an argument. */
2504 /*******************************************************************************
2506 ** Function btif_av_trigger_dual_handoff
2508 ** Description Trigger the DUAL HANDOFF
2512 *******************************************************************************/
2514 void btif_av_trigger_dual_handoff(BOOLEAN handoff, BD_ADDR address)
2517 /*Get the current playing device*/
2518 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
2519 index = btif_get_latest_playing_device_idx();
2520 if (index != btif_max_av_clients)
2522 btif_av_cb[index].dual_handoff = handoff; /*Initiate Handoff*/
2523 if (bt_split_a2dp_enabled)
2524 btif_media_on_stop_vendor_command();
2525 /*Initiate SUSPEND for this device*/
2526 BTIF_TRACE_DEBUG("Initiate SUSPEND for this device on index = %d", index);
2527 btif_sm_dispatch(btif_av_cb[index].sm_handle, BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL);
2531 BTIF_TRACE_ERROR("Handoff on invalid index");
2533 if (bt_split_a2dp_enabled)
2535 btif_media_send_reset_vendor_state();
2536 next_idx = btif_av_get_other_connected_idx(index);
2537 /* Fix for below Klockwork Issue
2538 Array 'btif_av_cb' of size 2 may use index value(s) -1 */
2539 if (next_idx != INVALID_INDEX && next_idx != btif_max_av_clients)
2541 HAL_CBACK(bt_av_src_callbacks, reconfig_a2dp_trigger_cb, 1,
2542 &(btif_av_cb[next_idx].peer_bda));
2547 /*******************************************************************************
2549 ** Function btif_av_trigger_suspend
2551 ** Description Trigger suspend when multicast is ongoing for tuch tones
2552 ** and new ACL is created.
2556 *******************************************************************************/
2558 void btif_av_trigger_suspend()
2561 /*Get the current playing device*/
2562 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
2563 index = btif_get_latest_playing_device_idx();
2564 if (index <= btif_max_av_clients)
2566 /*Initiate SUSPEND for this device*/
2567 BTIF_TRACE_DEBUG("Initiate SUSPEND for this device on index = %d", index);
2568 btif_sm_dispatch(btif_av_cb[index].sm_handle, BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL);
2572 BTIF_TRACE_ERROR("suspend on invalid index");
2576 /*******************************************************************************
2580 ** Description Establishes the AV signalling channel with the remote headset
2582 ** Returns bt_status_t
2584 *******************************************************************************/
2586 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
2588 btif_av_connect_req_t connect_req;
2590 connect_req.target_bda = bd_addr;
2591 connect_req.uuid = uuid;
2592 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2594 for (i = 0; i < btif_max_av_clients;)
2596 if(btif_av_get_valid_idx(i))
2598 if (bdcmp(bd_addr->address, btif_av_cb[i].peer_bda.address) == 0)
2600 BTIF_TRACE_ERROR("Attempting connection for non idle device.. back off ");
2601 btif_queue_advance();
2602 return BT_STATUS_SUCCESS;
2609 if (i == btif_max_av_clients)
2613 BTIF_TRACE_ERROR("%s: All indexes are full", __FUNCTION__);
2615 /* Multicast: Check if AV slot is available for connection
2616 * If not available, AV got connected to different devices.
2617 * Disconnect this RC connection without AV connection.
2619 rc_handle = btif_rc_get_connected_peer_handle(bd_addr->address);
2620 if (rc_handle != BTIF_RC_HANDLE_NONE)
2622 BTA_AvCloseRc(rc_handle);
2624 btif_queue_advance();
2625 return BT_STATUS_FAIL;
2628 btif_sm_dispatch(btif_av_cb[i].sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
2631 return BT_STATUS_SUCCESS;
2634 static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
2636 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2639 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
2642 static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
2644 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2647 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
2650 /*******************************************************************************
2652 ** Function disconnect
2654 ** Description Tears down the AV signalling channel with the remote headset
2656 ** Returns bt_status_t
2658 *******************************************************************************/
2659 static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
2661 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2665 /* Switch to BTIF context */
2666 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
2667 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
2670 /*******************************************************************************
2674 ** Description Shuts down the AV interface and does the cleanup
2678 *******************************************************************************/
2679 static void cleanup(int service_uuid)
2681 BTIF_TRACE_IMP("AV %s", __FUNCTION__);
2683 btif_transfer_context(btif_av_handle_event, BTIF_AV_CLEANUP_REQ_EVT,
2684 (char*)&service_uuid, sizeof(int), NULL);
2686 btif_disable_service(service_uuid);
2689 static void cleanup_src(void) {
2690 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2691 cleanup(BTA_A2DP_SOURCE_SERVICE_ID);
2692 BTIF_TRACE_EVENT("%s completed", __FUNCTION__);
2695 static void cleanup_sink(void) {
2696 BTIF_TRACE_EVENT("%s", __FUNCTION__);
2697 cleanup(BTA_A2DP_SINK_SERVICE_ID);
2700 static void allow_connection(int is_valid, bt_bdaddr_t *bd_addr)
2703 BTIF_TRACE_DEBUG(" %s isValid is %d event %d", __FUNCTION__,is_valid,idle_rc_event);
2704 switch (idle_rc_event)
2706 case BTA_AV_RC_OPEN_EVT:
2709 BTIF_TRACE_DEBUG("allowconn for RC connection");
2710 alarm_set_on_queue(av_open_on_rc_timer,
2711 BTIF_TIMEOUT_AV_OPEN_ON_RC_MS,
2712 btif_initiate_av_open_timer_timeout, NULL,
2713 btu_general_alarm_queue);
2714 btif_rc_handler(idle_rc_event, &idle_rc_data);
2718 UINT8 rc_handle = idle_rc_data.rc_open.rc_handle;
2719 BTA_AvCloseRc(rc_handle);
2723 case BTA_AV_PENDING_EVT:
2726 index = btif_av_idx_by_bdaddr(bd_addr->address);
2727 if (index >= btif_max_av_clients)
2729 BTIF_TRACE_DEBUG("Invalid index for device");
2732 BTIF_TRACE_DEBUG("The connection is allowed for the device at index = %d", index);
2733 BTA_AvOpen(btif_av_cb[index].peer_bda.address, btif_av_cb[index].bta_handle,
2734 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE);
2738 BTA_AvDisconnect(idle_rc_data.pend.bd_addr);
2743 BTIF_TRACE_DEBUG("%s : unhandled event:%s", __FUNCTION__,
2744 dump_av_sm_event_name(idle_rc_event));
2747 memset(&idle_rc_data, 0, sizeof(tBTA_AV));
2750 static const btav_interface_t bt_av_src_interface = {
2751 sizeof(btav_interface_t),
2761 static const btav_interface_t bt_av_sink_interface = {
2762 sizeof(btav_interface_t),
2767 #ifdef USE_AUDIO_TRACK
2768 update_audio_focus_state,
2769 update_audio_track_gain,
2777 /*******************************************************************************
2779 ** Function btif_av_get_sm_handle
2781 ** Description Fetches current av SM handle
2785 *******************************************************************************/
2786 /* Media task uses this info
2787 * But dont use it. */
2788 btif_sm_handle_t btif_av_get_sm_handle(void)
2790 return btif_av_cb[0].sm_handle;
2793 /*******************************************************************************
2795 ** Function btif_av_get_addr
2797 ** Description Fetches current AV BD address
2799 ** Returns BD address
2801 *******************************************************************************/
2803 bt_bdaddr_t btif_av_get_addr(BD_ADDR address)
2806 bt_bdaddr_t not_found ;
2807 memset (¬_found, 0, sizeof(bt_bdaddr_t));
2808 for (i = 0; i < btif_max_av_clients; i++)
2810 if (bdcmp(btif_av_cb[i].peer_bda.address, address) == 0)
2811 return btif_av_cb[i].peer_bda;
2816 /*******************************************************************************
2817 ** Function btif_av_is_sink_enabled
2819 ** Description Checks if A2DP Sink is enabled or not
2821 ** Returns TRUE if A2DP Sink is enabled, false otherwise
2823 *******************************************************************************/
2825 BOOLEAN btif_av_is_sink_enabled(void)
2827 return (bt_av_sink_callbacks != NULL) ? TRUE : FALSE;
2830 /*******************************************************************************
2832 ** Function btif_av_stream_ready
2834 ** Description Checks whether AV is ready for starting a stream
2838 *******************************************************************************/
2840 BOOLEAN btif_av_stream_ready(void)
2843 BOOLEAN status = FALSE;
2844 /* also make sure main adapter is enabled */
2845 if (btif_is_enabled() == 0)
2847 BTIF_TRACE_EVENT("main adapter not enabled");
2851 for (i = 0; i < btif_max_av_clients; i++)
2853 btif_av_cb[i].state = btif_sm_get_state(btif_av_cb[i].sm_handle);
2855 * If any of the stream is in pending suspend state when
2856 * we initiate start, it will result in inconsistent behavior
2857 * Check the pending SUSPEND flag and return failure
2858 * if suspend is in progress.
2860 if (btif_av_cb[i].dual_handoff ||
2861 (btif_av_cb[i].flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING))
2866 else if (btif_av_cb[i].flags &
2867 (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
2872 else if (btif_av_cb[i].state == BTIF_AV_STATE_OPENED)
2877 BTIF_TRACE_DEBUG("btif_av_stream_ready: %d", status);
2881 /*******************************************************************************
2883 ** Function btif_av_stream_started_ready
2885 ** Description Checks whether AV ready for media start in streaming state
2889 *******************************************************************************/
2891 BOOLEAN btif_av_stream_started_ready(void)
2894 BOOLEAN status = FALSE;
2896 for (i = 0; i < btif_max_av_clients; i++)
2898 btif_av_cb[i].state = btif_sm_get_state(btif_av_cb[i].sm_handle);
2899 if (btif_av_cb[i].dual_handoff)
2901 BTIF_TRACE_ERROR("%s: Under Dual handoff ",__FUNCTION__ );
2904 } else if (btif_av_cb[i].flags &
2905 (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING |
2906 BTIF_AV_FLAG_REMOTE_SUSPEND |
2907 BTIF_AV_FLAG_PENDING_STOP))
2911 } else if (btif_av_cb[i].state == BTIF_AV_STATE_STARTED)
2916 BTIF_TRACE_DEBUG("btif_av_stream_started_ready: %d", status);
2920 /*******************************************************************************
2922 ** Function btif_dispatch_sm_event
2924 ** Description Send event to AV statemachine
2928 *******************************************************************************/
2930 /* used to pass events to AV statemachine from other tasks */
2931 void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
2933 /* Switch to BTIF context */
2934 BTIF_TRACE_IMP("%s: event: %d, len: %d", __FUNCTION__, event, len);
2935 btif_transfer_context(btif_av_handle_event, event,
2936 (char*)p_data, len, NULL);
2937 BTIF_TRACE_IMP("%s: event %d sent", __FUNCTION__, event);
2940 /*******************************************************************************
2942 ** Function btif_av_execute_service
2944 ** Description Initializes/Shuts down the service
2946 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
2948 *******************************************************************************/
2949 bt_status_t btif_av_execute_service(BOOLEAN b_enable)
2952 btif_sm_state_t state;
2953 BTIF_TRACE_IMP("%s: enable: %d", __FUNCTION__, b_enable);
2956 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
2957 * handle this request in order to allow incoming connections to succeed.
2958 * We need to put this back once support for this is added */
2960 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
2961 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
2962 * be initiated by the app/audioflinger layers */
2963 #if (AVRC_METADATA_INCLUDED == TRUE)
2964 BTA_AvEnable(BTA_SEC_AUTHENTICATE,
2965 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
2966 |BTA_AV_FEAT_ACP_START
2967 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
2969 |BTA_AV_FEAT_ADV_CTRL
2974 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD
2975 |BTA_AV_FEAT_ACP_START), bte_av_callback);
2977 for (i = 0; i < btif_max_av_clients; i++)
2979 BTIF_TRACE_DEBUG("%s: BTA_AvRegister : %d", __FUNCTION__, i);
2980 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback,
2981 UUID_SERVCLASS_AUDIO_SOURCE);
2983 BTA_AvUpdateMaxAVClient(btif_max_av_clients);
2987 /* Also shut down the AV state machine */
2988 for (i = 0; i < btif_max_av_clients; i++ )
2990 if (btif_av_cb[i].sm_handle != NULL)
2992 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
2993 if(state==BTIF_AV_STATE_OPENING)
2995 BTIF_TRACE_DEBUG("Moving State from Opening to Idle due to BT ShutDown");
2996 btif_sm_change_state(btif_av_cb[i].sm_handle, BTIF_AV_STATE_IDLE);
2997 btif_queue_advance();
2999 btif_sm_shutdown(btif_av_cb[i].sm_handle);
3000 btif_av_cb[i].sm_handle = NULL;
3003 for (i = 0; i < btif_max_av_clients; i++)
3005 BTA_AvDeregister(btif_av_cb[i].bta_handle);
3009 BTIF_TRACE_IMP("%s: enable: %d completed", __FUNCTION__, b_enable);
3010 return BT_STATUS_SUCCESS;
3013 /*******************************************************************************
3015 ** Function btif_av_sink_execute_service
3017 ** Description Initializes/Shuts down the service
3019 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
3021 *******************************************************************************/
3022 bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
3025 BTIF_TRACE_IMP("%s: enable: %d", __FUNCTION__, b_enable);
3029 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
3030 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
3031 * be initiated by the app/audioflinger layers */
3032 BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD|BTA_AV_FEAT_RCCT|
3033 BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|
3034 BTA_AV_FEAT_ADV_CTRL|BTA_AV_FEAT_RCTG,
3036 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AVK_SERVICE_NAME, 0, bte_av_media_callback,
3037 UUID_SERVCLASS_AUDIO_SINK);
3040 /* Also shut down the AV state machine */
3041 for (i = 0; i < btif_max_av_clients; i++ )
3043 if (btif_av_cb[i].sm_handle != NULL)
3045 BTIF_TRACE_IMP("%s: shutting down AV SM", __FUNCTION__);
3046 btif_sm_shutdown(btif_av_cb[i].sm_handle);
3047 btif_av_cb[i].sm_handle = NULL;
3050 BTA_AvDeregister(btif_av_cb[0].bta_handle);
3053 BTIF_TRACE_IMP("%s: enable: %d completed", __FUNCTION__, b_enable);
3054 return BT_STATUS_SUCCESS;
3057 /*******************************************************************************
3059 ** Function btif_av_get_src_interface
3061 ** Description Get the AV callback interface for A2DP source profile
3063 ** Returns btav_interface_t
3065 *******************************************************************************/
3066 const btav_interface_t *btif_av_get_src_interface(void)
3068 BTIF_TRACE_EVENT("%s", __FUNCTION__);
3069 return &bt_av_src_interface;
3072 /*******************************************************************************
3074 ** Function btif_av_get_sink_interface
3076 ** Description Get the AV callback interface for A2DP sink profile
3078 ** Returns btav_interface_t
3080 *******************************************************************************/
3081 const btav_interface_t *btif_av_get_sink_interface(void)
3083 BTIF_TRACE_EVENT("%s", __FUNCTION__);
3084 return &bt_av_sink_interface;
3087 /*******************************************************************************
3089 ** Function btif_av_is_connected
3091 ** Description Checks if av has a connected sink
3095 *******************************************************************************/
3096 BOOLEAN btif_av_is_connected(void)
3099 BOOLEAN status = FALSE;
3100 for (i = 0; i < btif_max_av_clients; i++)
3102 btif_av_cb[i].state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3103 if ((btif_av_cb[i].state == BTIF_AV_STATE_OPENED) ||
3104 (btif_av_cb[i].state == BTIF_AV_STATE_STARTED))
3110 /*******************************************************************************
3112 ** Function btif_av_is_connected_on_other_idx
3114 ** Description Checks if any other AV SCB is connected
3118 *******************************************************************************/
3120 BOOLEAN btif_av_is_connected_on_other_idx(int current_index)
3122 //return true if other IDx is connected
3123 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
3125 for (i = 0; i < btif_max_av_clients; i++)
3127 if (i != current_index)
3129 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3130 if ((state == BTIF_AV_STATE_OPENED) ||
3131 (state == BTIF_AV_STATE_STARTED))
3138 /*******************************************************************************
3140 ** Function btif_av_get_other_connected_idx
3142 ** Description Checks if any AV SCB is connected other than the current
3147 *******************************************************************************/
3148 int btif_av_get_other_connected_idx(int current_index)
3150 //return true if other IDx is connected
3151 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
3153 for (i = 0; i < btif_max_av_clients; i++)
3155 if (i != current_index)
3157 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3158 if ((state == BTIF_AV_STATE_OPENED) ||
3159 (state == BTIF_AV_STATE_STARTED))
3163 return INVALID_INDEX;
3166 /*******************************************************************************
3168 ** Function btif_av_is_playing_on_other_idx
3170 ** Description Checks if any other AV SCB is connected
3174 *******************************************************************************/
3176 BOOLEAN btif_av_is_playing_on_other_idx(int current_index)
3178 //return true if other IDx is playing
3179 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
3181 for (i = 0; i < btif_max_av_clients; i++)
3183 if (i != current_index)
3185 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3186 if (state == BTIF_AV_STATE_STARTED)
3193 /*******************************************************************************
3195 ** Function btif_av_update_current_playing_device
3197 ** Description Update the next connected device as playing
3201 *******************************************************************************/
3203 static void btif_av_update_current_playing_device(int index)
3206 for (i = 0; i < btif_max_av_clients; i++)
3209 btif_av_cb[i].current_playing = TRUE;
3213 /*******************************************************************************
3215 ** Function btif_av_is_peer_edr
3217 ** Description Check if the connected a2dp device supports
3218 ** EDR or not. Only when connected this function
3219 ** will accurately provide a true capability of
3220 ** remote peer. If not connected it will always be false.
3222 ** Returns TRUE if remote device is capable of EDR
3224 *******************************************************************************/
3225 BOOLEAN btif_av_is_peer_edr(void)
3227 btif_sm_state_t state;
3228 BOOLEAN peer_edr = FALSE;
3230 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
3232 /* If any of the remote in streaming state is BR
3233 * return FALSE to ensure proper configuration
3234 * is used. Ideally, since multicast is not supported
3235 * if any of the connected device is BR device,
3236 * we should not see both devices in START state.
3238 for (int index = 0; index < btif_max_av_clients; index ++)
3240 state = btif_sm_get_state(btif_av_cb[index].sm_handle);
3241 if ((btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START)
3242 || (state == BTIF_AV_STATE_STARTED))
3244 if (btif_av_cb[index].edr)
3257 /*******************************************************************************
3259 ** Function btif_av_any_br_peer
3261 ** Description Check if the any of connected devices is BR device.
3263 ** Returns TRUE if connected to any BR device, FALSE otherwise.
3265 *******************************************************************************/
3266 BOOLEAN btif_av_any_br_peer(void)
3268 btif_sm_state_t state;
3269 for (int index = 0; index < btif_max_av_clients; index ++)
3271 state = btif_sm_get_state(btif_av_cb[index].sm_handle);
3272 if (state >= BTIF_AV_STATE_OPENED)
3274 if (!btif_av_cb[index].edr)
3276 BTIF_TRACE_WARNING("%s : Connected to BR device :", __FUNCTION__);
3284 /*******************************************************************************
3286 ** Function btif_av_peer_supports_3mbps
3288 ** Description check if the connected a2dp device supports
3289 ** 3mbps edr. Only when connected this function
3290 ** will accurately provide a true capability of
3291 ** remote peer. If not connected it will always be false.
3293 ** Returns TRUE if remote device is EDR and supports 3mbps
3295 *******************************************************************************/
3296 BOOLEAN btif_av_peer_supports_3mbps(void)
3298 btif_sm_state_t state;
3299 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
3301 for (int index = 0; index < btif_max_av_clients; index ++)
3303 state = btif_sm_get_state(btif_av_cb[index].sm_handle);
3304 if ((btif_av_cb[index].flags & BTIF_AV_FLAG_PENDING_START)
3305 || (state == BTIF_AV_STATE_STARTED))
3307 if(btif_av_cb[index].edr_3mbps)
3314 /******************************************************************************
3316 ** Function btif_av_clear_remote_suspend_flag
3318 ** Description Clears btif_av_cd.flags if BTIF_AV_FLAG_REMOTE_SUSPEND is set
3321 ******************************************************************************/
3322 void btif_av_clear_remote_suspend_flag(void)
3325 for (i = 0; i < btif_max_av_clients; i++)
3327 BTIF_TRACE_DEBUG(" flag :%x",btif_av_cb[i].flags);
3328 btif_av_cb[i].flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
3332 /*******************************************************************************
3334 ** Function btif_av_move_idle
3336 ** Description Opening state is intermediate state. It cannot handle
3337 ** incoming/outgoing connect/disconnect requests.When ACL
3338 ** is disconnected and we are in opening state then move back
3339 ** to idle state which is proper to handle connections.
3343 *******************************************************************************/
3344 void btif_av_move_idle(bt_bdaddr_t bd_addr)
3347 /* inform the application that ACL is disconnected and move to idle state */
3348 index = btif_av_idx_by_bdaddr(bd_addr.address);
3349 if (index == btif_max_av_clients)
3351 BTIF_TRACE_DEBUG("btif_av_move_idle: Already in IDLE");
3354 btif_sm_state_t state = btif_sm_get_state(btif_av_cb[index].sm_handle);
3355 BTIF_TRACE_DEBUG("ACL Disconnected state %d is same device %d",state,
3356 memcmp (&bd_addr, &(btif_av_cb[index].peer_bda), sizeof(bd_addr)));
3357 if (state == BTIF_AV_STATE_OPENING &&
3358 (memcmp (&bd_addr, &(btif_av_cb[index].peer_bda), sizeof(bd_addr)) == 0))
3360 BTIF_TRACE_DEBUG("Moving BTIF State from Opening to Idle due to ACL disconnect");
3361 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb[index].peer_bda));
3362 BTA_AvClose(btif_av_cb[index].bta_handle);
3363 btif_sm_change_state(btif_av_cb[index].sm_handle, BTIF_AV_STATE_IDLE);
3364 btif_queue_advance();
3367 /******************************************************************************
3369 ** Function btif_av_get_num_playing_devices
3371 ** Description Return number of A2dp playing devices
3374 ******************************************************************************/
3375 UINT16 btif_av_get_num_playing_devices(void)
3378 UINT16 playing_devices = 0;
3379 for (i = 0; i < btif_max_av_clients; i++)
3381 btif_av_cb[i].state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3382 if (btif_av_cb[i].state == BTIF_AV_STATE_STARTED)
3387 BTIF_TRACE_DEBUG("AV devices playing: %d", playing_devices);
3389 return playing_devices;
3391 /*******************************************************************************
3393 ** Function btif_av_get_num_connected_devices
3395 ** Description Return number of A2dp connected devices
3398 ******************************************************************************/
3399 UINT16 btif_av_get_num_connected_devices(void)
3402 UINT16 connected_devies = 0;
3403 for (i = 0; i < btif_max_av_clients; i++)
3405 btif_av_cb[i].state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3406 if ((btif_av_cb[i].state == BTIF_AV_STATE_OPENED) ||
3407 (btif_av_cb[i].state == BTIF_AV_STATE_STARTED))
3412 BTIF_TRACE_DEBUG("AV Connection count: %d", connected_devies);
3414 return connected_devies;
3417 /******************************************************************************
3419 ** Function btif_av_update_multicast_state
3421 ** Description Enable Multicast only if below conditions are satisfied
3422 ** 1. Connected to only 2 EDR HS.
3423 ** 2. Connected to both HS as master.
3424 ** 3. Connected to 2 EDR HS and one BLE device
3425 ** Multicast will fall back to soft handsoff in below conditions
3426 ** 1. Number of ACL links is more than 2,like connected to HID
3427 ** initiating connection for HS1 and HS2.
3428 ** 2. Connected to BR and EDR HS.
3429 ** 3. Connected to more then 1 BLE device
3432 ******************************************************************************/
3433 void btif_av_update_multicast_state(int index)
3435 UINT16 num_connected_br_edr_devices = 0;
3436 UINT16 num_connected_le_devices = 0;
3437 UINT16 num_av_connected = 0;
3439 BOOLEAN is_slave = FALSE;
3440 BOOLEAN is_br_hs_connected = FALSE;
3441 BOOLEAN prev_multicast_state = enable_multicast;
3443 if (!is_multicast_supported)
3445 BTIF_TRACE_DEBUG("%s Multicast is Disabled", __FUNCTION__);
3449 if (multicast_disabled == TRUE)
3451 multicast_disabled = FALSE;
3452 enable_multicast = FALSE;
3453 BTA_AvEnableMultiCast(FALSE, btif_av_cb[index].bta_handle);
3457 BTIF_TRACE_DEBUG("%s Multicast previous state : %s", __FUNCTION__,
3458 enable_multicast ? "Enabled" : "Disabled" );
3460 num_connected_br_edr_devices = btif_dm_get_br_edr_links();
3461 num_connected_le_devices = btif_dm_get_le_links();
3462 num_av_connected = btif_av_get_num_connected_devices();
3463 is_br_hs_connected = btif_av_any_br_peer();
3465 for (i = 0; i < btif_max_av_clients; i++)
3467 if (btif_av_cb[i].is_slave == TRUE)
3469 BTIF_TRACE_WARNING("Conected as slave");
3475 if ((num_av_connected <= 2) && (is_br_hs_connected != TRUE) &&
3476 (is_slave == FALSE) && ((num_connected_br_edr_devices <= 2) &&
3477 (num_connected_le_devices <= 1)))
3479 enable_multicast = TRUE;
3483 enable_multicast = FALSE;
3486 BTIF_TRACE_DEBUG("%s Multicast current state : %s", __FUNCTION__,
3487 enable_multicast ? "Enabled" : "Disabled" );
3489 if (prev_multicast_state != enable_multicast)
3491 BTA_AvEnableMultiCast(enable_multicast,
3492 btif_av_cb[index].bta_handle);
3493 HAL_CBACK(bt_av_src_callbacks, multicast_state_cb,
3497 /******************************************************************************
3499 ** Function btif_av_get_multicast_state
3501 ** Description Returns TRUE if multicast is enabled else false
3504 ******************************************************************************/
3505 BOOLEAN btif_av_get_multicast_state()
3507 return enable_multicast;
3509 /******************************************************************************
3511 ** Function btif_av_get_ongoing_multicast
3513 ** Description Returns TRUE if multicast is ongoing
3516 ******************************************************************************/
3517 BOOLEAN btif_av_get_ongoing_multicast()
3520 if (!is_multicast_supported)
3522 BTIF_TRACE_DEBUG("Multicast is Disabled");
3525 for (i = 0; i < btif_max_av_clients; i++)
3527 if (btif_av_cb[i].is_device_playing)
3532 if (j == btif_max_av_clients)
3542 /******************************************************************************
3544 ** Function btif_av_is_multicast_supported
3546 ** Description Returns TRUE if multicast is supported
3549 ******************************************************************************/
3550 BOOLEAN btif_av_is_multicast_supported()
3552 return is_multicast_supported;
3555 /******************************************************************************
3557 ** Function btif_av_is_offload_supported
3559 ** Description Returns split mode status
3561 ** Returns TRUE if split mode is enabled, FALSE otherwise
3562 ********************************************************************************/
3563 BOOLEAN btif_av_is_offload_supported()
3565 return bt_split_a2dp_enabled;
3568 #ifdef BTA_AV_SPLIT_A2DP_ENABLED
3569 int btif_av_get_current_playing_dev_idx(void)
3573 for (i = 0; i < btif_max_av_clients; i++)
3575 if (btif_av_cb[i].current_playing == TRUE)
3577 BTIF_TRACE_DEBUG("current playing on index = %d",i);
3583 /******************************************************************************
3585 ** Function btif_av_get_streaming_channel_id
3587 ** Description Returns streaming channel id
3589 ** Returns channel id
3590 ********************************************************************************/
3591 UINT16 btif_av_get_streaming_channel_id(void)
3595 index = btif_av_get_current_playing_dev_idx();
3598 BTIF_TRACE_DEBUG("btif_av_get_streaming_channel_id: %u",
3599 btif_av_cb[index].channel_id);
3600 return btif_av_cb[index].channel_id;
3605 /******************************************************************************
3607 ** Function btif_av_get_peer_addr
3609 ** Description Returns peer device address
3611 ** Returns peer address
3612 ********************************************************************************/
3613 void btif_av_get_peer_addr(bt_bdaddr_t *peer_bda)
3615 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
3617 memset(peer_bda, 0, sizeof(bt_bdaddr_t));
3618 for (i = 0; i < btif_max_av_clients; i++)
3620 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3621 if (state == BTIF_AV_STATE_STARTED)
3623 BTIF_TRACE_DEBUG("btif_av_get_peer_addr: %u",
3624 btif_av_cb[i].peer_bda);
3625 memcpy(peer_bda, &btif_av_cb[i].peer_bda,
3626 sizeof(bt_bdaddr_t));
3631 /******************************************************************************
3633 ** Function btif_av_get_playing_device_hdl
3635 ** Description Returns current playing device's bta handle
3637 ** Returns BTA HANDLE
3638 ********************************************************************************/
3639 tBTA_AV_HNDL btif_av_get_playing_device_hdl()
3642 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
3644 for (i = 0; i < btif_max_av_clients; i++)
3646 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3647 if (state == BTIF_AV_STATE_STARTED)
3649 return btif_av_cb[i].bta_handle;
3655 /******************************************************************************
3657 ** Function btif_av_get_av_hdl_from_idx
3659 ** Description Returns bta handle from the device index
3661 ** Returns BTA HANDLE
3662 ********************************************************************************/
3663 tBTA_AV_HNDL btif_av_get_av_hdl_from_idx(UINT8 idx)
3665 if (idx == btif_max_av_clients)
3667 BTIF_TRACE_ERROR("%s: Invalid handle",__func__);
3670 return btif_av_cb[idx].bta_handle;
3673 /******************************************************************************
3675 ** Function btif_av_is_codec_offload_supported
3677 ** Description check if the correpsonding codec is supported in offload
3679 ** Returns TRUE if supported, FALSE otherwise
3680 ********************************************************************************/
3681 BOOLEAN btif_av_is_codec_offload_supported(int codec)
3683 BOOLEAN ret = FALSE;
3684 BTIF_TRACE_DEBUG("btif_av_is_codec_offload_supported = %s",dump_av_codec_name(codec));
3688 ret = btif_av_codec_offload.sbc_offload;
3691 ret = btif_av_codec_offload.aptx_offload;
3694 ret = btif_av_codec_offload.aac_offload;
3697 ret = btif_av_codec_offload.aptxhd_offload;
3702 BTIF_TRACE_DEBUG("btif_av_is_codec_offload_supported %s codec supported = %d",dump_av_codec_name(codec),ret);
3706 /******************************************************************************
3708 ** Function btif_av_is_under_handoff
3710 ** Description check if AV state is under handoff
3712 ** Returns TRUE if handoff is triggered, FALSE otherwise
3713 ********************************************************************************/
3714 BOOLEAN btif_av_is_under_handoff()
3717 btif_sm_state_t state = BTIF_AV_STATE_IDLE;
3719 BTIF_TRACE_DEBUG("btif_av_is_under_handoff");
3721 for (i = 0; i < btif_max_av_clients; i++)
3723 state = btif_sm_get_state(btif_av_cb[i].sm_handle);
3724 if (btif_av_cb[i].dual_handoff &&
3725 (state == BTIF_AV_STATE_STARTED || state == BTIF_AV_STATE_OPENED))
3727 /* If a2dp reconfigure is triggered when playing device disconnect is
3728 * initiated locally then return false, otherwise wait till the suspend cfm
3729 * is received from the remote.