btif_av.c revision 309243751678f395e6f7323e45433e5476dc17ef
1/****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 20/***************************************************************************** 21 * 22 * Filename: btif_av.c 23 * 24 * Description: Bluedroid AV implementation 25 * 26 *****************************************************************************/ 27 28#include <hardware/bluetooth.h> 29#include <system/audio.h> 30#include "hardware/bt_av.h" 31 32#define LOG_TAG "BTIF_AV" 33 34#include "btif_av.h" 35#include "btif_util.h" 36#include "btif_profile_queue.h" 37#include "bta_api.h" 38#include "btif_media.h" 39#include "bta_av_api.h" 40#include "gki.h" 41#include "bd.h" 42#include "btu.h" 43#include "bt_utils.h" 44 45/***************************************************************************** 46** Constants & Macros 47******************************************************************************/ 48#define BTIF_AV_SERVICE_NAME "Advanced Audio" 49 50#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2 51 52typedef enum { 53 BTIF_AV_STATE_IDLE = 0x0, 54 BTIF_AV_STATE_OPENING, 55 BTIF_AV_STATE_OPENED, 56 BTIF_AV_STATE_STARTED, 57 BTIF_AV_STATE_CLOSING 58} btif_av_state_t; 59 60/* Should not need dedicated suspend state as actual actions are no 61 different than open state. Suspend flags are needed however to prevent 62 media task from trying to restart stream during remote suspend or while 63 we are in the process of a local suspend */ 64 65#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1 66#define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2 67#define BTIF_AV_FLAG_PENDING_START 0x4 68#define BTIF_AV_FLAG_PENDING_STOP 0x8 69 70/***************************************************************************** 71** Local type definitions 72******************************************************************************/ 73 74typedef struct 75{ 76 tBTA_AV_HNDL bta_handle; 77 bt_bdaddr_t peer_bda; 78 btif_sm_handle_t sm_handle; 79 UINT8 flags; 80 tBTA_AV_EDR edr; 81 UINT8 peer_sep; /* sep type of peer device */ 82} btif_av_cb_t; 83 84typedef struct 85{ 86 bt_bdaddr_t *target_bda; 87 uint16_t uuid; 88} btif_av_connect_req_t; 89 90typedef struct 91{ 92 int sample_rate; 93 int channel_count; 94} btif_av_sink_config_req_t; 95 96/***************************************************************************** 97** Static variables 98******************************************************************************/ 99static btav_callbacks_t *bt_av_src_callbacks = NULL; 100static btav_callbacks_t *bt_av_sink_callbacks = NULL; 101static btif_av_cb_t btif_av_cb; 102static TIMER_LIST_ENT tle_av_open_on_rc; 103 104/* both interface and media task needs to be ready to alloc incoming request */ 105#define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \ 106 || (btif_av_cb.sm_handle == NULL))\ 107{\ 108 BTIF_TRACE_WARNING1("%s: BTAV not initialized", __FUNCTION__);\ 109 return BT_STATUS_NOT_READY;\ 110}\ 111else\ 112{\ 113 BTIF_TRACE_EVENT1("%s", __FUNCTION__);\ 114} 115 116/* Helper macro to avoid code duplication in the state machine handlers */ 117#define CHECK_RC_EVENT(e, d) \ 118 case BTA_AV_RC_OPEN_EVT: \ 119 case BTA_AV_RC_CLOSE_EVT: \ 120 case BTA_AV_REMOTE_CMD_EVT: \ 121 case BTA_AV_VENDOR_CMD_EVT: \ 122 case BTA_AV_META_MSG_EVT: \ 123 case BTA_AV_RC_FEAT_EVT: \ 124 case BTA_AV_REMOTE_RSP_EVT: \ 125 { \ 126 btif_rc_handler(e, d);\ 127 }break; \ 128 129static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data); 130static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data); 131static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data); 132static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data); 133static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data); 134 135static const btif_sm_handler_t btif_av_state_handlers[] = 136{ 137 btif_av_state_idle_handler, 138 btif_av_state_opening_handler, 139 btif_av_state_opened_handler, 140 btif_av_state_started_handler, 141 btif_av_state_closing_handler 142}; 143 144/************************************************************************* 145** Extern functions 146*************************************************************************/ 147extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data); 148extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr); 149extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp); 150 151/***************************************************************************** 152** Local helper functions 153******************************************************************************/ 154 155const char *dump_av_sm_state_name(btif_av_state_t state) 156{ 157 switch (state) 158 { 159 CASE_RETURN_STR(BTIF_AV_STATE_IDLE) 160 CASE_RETURN_STR(BTIF_AV_STATE_OPENING) 161 CASE_RETURN_STR(BTIF_AV_STATE_OPENED) 162 CASE_RETURN_STR(BTIF_AV_STATE_STARTED) 163 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING) 164 default: return "UNKNOWN_STATE"; 165 } 166} 167 168const char *dump_av_sm_event_name(btif_av_sm_event_t event) 169{ 170 switch((int)event) 171 { 172 CASE_RETURN_STR(BTA_AV_ENABLE_EVT) 173 CASE_RETURN_STR(BTA_AV_REGISTER_EVT) 174 CASE_RETURN_STR(BTA_AV_OPEN_EVT) 175 CASE_RETURN_STR(BTA_AV_CLOSE_EVT) 176 CASE_RETURN_STR(BTA_AV_START_EVT) 177 CASE_RETURN_STR(BTA_AV_STOP_EVT) 178 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT) 179 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT) 180 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT) 181 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT) 182 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT) 183 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT) 184 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT) 185 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT) 186 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT) 187 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT) 188 CASE_RETURN_STR(BTA_AV_PENDING_EVT) 189 CASE_RETURN_STR(BTA_AV_META_MSG_EVT) 190 CASE_RETURN_STR(BTA_AV_REJECT_EVT) 191 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT) 192 CASE_RETURN_STR(BTIF_SM_ENTER_EVT) 193 CASE_RETURN_STR(BTIF_SM_EXIT_EVT) 194 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT) 195 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT) 196 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT) 197 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT) 198 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT) 199 CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT) 200 default: return "UNKNOWN_EVENT"; 201 } 202} 203 204/**************************************************************************** 205** Local helper functions 206*****************************************************************************/ 207/******************************************************************************* 208** 209** Function btif_initiate_av_open_tmr_hdlr 210** 211** Description Timer to trigger AV open if the remote headset establishes 212** RC connection w/o AV connection. The timer is needed to IOP 213** with headsets that do establish AV after RC connection. 214** 215** Returns void 216** 217*******************************************************************************/ 218static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle) 219{ 220 BD_ADDR peer_addr; 221 UNUSED(tle); 222 btif_av_connect_req_t connect_req; 223 UNUSED(tle); 224 /* is there at least one RC connection - There should be */ 225 if (btif_rc_get_connected_peer(peer_addr)) { 226 BTIF_TRACE_DEBUG1("%s Issuing connect to the remote RC peer", __FUNCTION__); 227 /* In case of AVRCP connection request, we will initiate SRC connection */ 228 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr; 229 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE; 230 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req); 231 } 232 else 233 { 234 BTIF_TRACE_ERROR1("%s No connected RC peers", __FUNCTION__); 235 } 236} 237 238/***************************************************************************** 239** Static functions 240******************************************************************************/ 241 242static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr) 243{ 244 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) { 245 HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr); 246 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) { 247 HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr); 248 } 249} 250 251static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr) 252{ 253 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) { 254 HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr); 255 } else if (btif_av_cb.peer_sep == AVDT_TSEP_SNK && bt_av_src_callbacks != NULL) { 256 HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr); 257 } 258} 259 260/***************************************************************************** 261** 262** Function btif_av_state_idle_handler 263** 264** Description State managing disconnected AV link 265** 266** Returns TRUE if event was processed, FALSE otherwise 267** 268*******************************************************************************/ 269 270static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data) 271{ 272 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 273 dump_av_sm_event_name(event), btif_av_cb.flags); 274 275 switch (event) 276 { 277 case BTIF_SM_ENTER_EVT: 278 /* clear the peer_bda */ 279 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t)); 280 btif_av_cb.flags = 0; 281 btif_av_cb.edr = 0; 282 btif_a2dp_on_idle(); 283 break; 284 285 case BTIF_SM_EXIT_EVT: 286 break; 287 288 case BTA_AV_ENABLE_EVT: 289 break; 290 291 case BTA_AV_REGISTER_EVT: 292 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl; 293 break; 294 295 case BTA_AV_PENDING_EVT: 296 case BTIF_AV_CONNECT_REQ_EVT: 297 { 298 if (event == BTIF_AV_CONNECT_REQ_EVT) 299 { 300 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda, 301 sizeof(bt_bdaddr_t)); 302 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle, 303 TRUE, BTA_SEC_NONE, ((btif_av_connect_req_t*)p_data)->uuid); 304 } 305 else if (event == BTA_AV_PENDING_EVT) 306 { 307 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr); 308 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle, 309 TRUE, BTA_SEC_NONE, UUID_SERVCLASS_AUDIO_SOURCE); 310 } 311 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING); 312 } break; 313 314 case BTA_AV_RC_OPEN_EVT: 315 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So 316 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, 317 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state. 318 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the 319 * headsets, as some headsets initiate the AVRC connection first and then 320 * immediately initiate the AV connection 321 * 322 * TODO: We may need to do this only on an AVRCP Play. FixMe 323 */ 324 325 BTIF_TRACE_DEBUG0("BTA_AV_RC_OPEN_EVT received w/o AV"); 326 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc)); 327 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr; 328 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC, 329 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS); 330 btif_rc_handler(event, p_data); 331 break; 332 333 case BTA_AV_REMOTE_CMD_EVT: 334 case BTA_AV_VENDOR_CMD_EVT: 335 case BTA_AV_META_MSG_EVT: 336 case BTA_AV_RC_FEAT_EVT: 337 case BTA_AV_REMOTE_RSP_EVT: 338 btif_rc_handler(event, (tBTA_AV*)p_data); 339 break; 340 341 case BTA_AV_RC_CLOSE_EVT: 342 if (tle_av_open_on_rc.in_use) { 343 BTIF_TRACE_DEBUG0("BTA_AV_RC_CLOSE_EVT: Stopping AV timer."); 344 btu_stop_timer(&tle_av_open_on_rc); 345 } 346 btif_rc_handler(event, p_data); 347 break; 348 349 default: 350 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 351 dump_av_sm_event_name(event)); 352 return FALSE; 353 354 } 355 return TRUE; 356} 357/***************************************************************************** 358** 359** Function btif_av_state_opening_handler 360** 361** Description Intermediate state managing events during establishment 362** of avdtp channel 363** 364** Returns TRUE if event was processed, FALSE otherwise 365** 366*******************************************************************************/ 367 368static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data) 369{ 370 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 371 dump_av_sm_event_name(event), btif_av_cb.flags); 372 373 switch (event) 374 { 375 case BTIF_SM_ENTER_EVT: 376 /* inform the application that we are entering connecting state */ 377 btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda)); 378 break; 379 380 case BTIF_SM_EXIT_EVT: 381 break; 382 383 case BTA_AV_REJECT_EVT: 384 BTIF_TRACE_DEBUG0(" Received BTA_AV_REJECT_EVT "); 385 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 386 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 387 break; 388 389 case BTA_AV_OPEN_EVT: 390 { 391 tBTA_AV *p_bta_data = (tBTA_AV*)p_data; 392 btav_connection_state_t state; 393 btif_sm_state_t av_state; 394 BTIF_TRACE_DEBUG2("status:%d, edr 0x%x",p_bta_data->open.status, 395 p_bta_data->open.edr); 396 397 if (p_bta_data->open.status == BTA_AV_SUCCESS) 398 { 399 state = BTAV_CONNECTION_STATE_CONNECTED; 400 av_state = BTIF_AV_STATE_OPENED; 401 btif_av_cb.edr = p_bta_data->open.edr; 402 403 btif_av_cb.peer_sep = p_bta_data->open.sep; 404 btif_a2dp_set_peer_sep(p_bta_data->open.sep); 405 } 406 else 407 { 408 BTIF_TRACE_WARNING1("BTA_AV_OPEN_EVT::FAILED status: %d", 409 p_bta_data->open.status ); 410 state = BTAV_CONNECTION_STATE_DISCONNECTED; 411 av_state = BTIF_AV_STATE_IDLE; 412 } 413 414 /* inform the application of the event */ 415 btif_report_connection_state(state, &(btif_av_cb.peer_bda)); 416 /* change state to open/idle based on the status */ 417 btif_sm_change_state(btif_av_cb.sm_handle, av_state); 418 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 419 { 420 /* if queued PLAY command, send it now */ 421 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, 422 (p_bta_data->open.status == BTA_AV_SUCCESS)); 423 } 424 else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 425 { 426 /* if queued PLAY command, send it now */ 427 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE); 428 } 429 btif_queue_advance(); 430 } break; 431 432 case BTIF_AV_SINK_CONFIG_REQ_EVT: 433 { 434 btif_av_sink_config_req_t req; 435 // copy to avoid alignment problems 436 memcpy(&req, p_data, sizeof(req)); 437 438 BTIF_TRACE_WARNING2("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate, 439 req.channel_count); 440 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) { 441 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda), 442 req.sample_rate, req.channel_count); 443 } 444 } break; 445 446 CHECK_RC_EVENT(event, p_data); 447 448 default: 449 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 450 dump_av_sm_event_name(event)); 451 return FALSE; 452 453 } 454 return TRUE; 455} 456 457 458/***************************************************************************** 459** 460** Function btif_av_state_closing_handler 461** 462** Description Intermediate state managing events during closing 463** of avdtp channel 464** 465** Returns TRUE if event was processed, FALSE otherwise 466** 467*******************************************************************************/ 468 469static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data) 470{ 471 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 472 dump_av_sm_event_name(event), btif_av_cb.flags); 473 474 switch (event) 475 { 476 case BTIF_SM_ENTER_EVT: 477 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 478 { 479 /* immediately stop transmission of frames */ 480 btif_a2dp_set_tx_flush(TRUE); 481 /* wait for audioflinger to stop a2dp */ 482 } 483 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 484 { 485 btif_a2dp_set_rx_flush(TRUE); 486 } 487 break; 488 489 case BTA_AV_STOP_EVT: 490 case BTIF_AV_STOP_STREAM_REQ_EVT: 491 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 492 { 493 /* immediately flush any pending tx frames while suspend is pending */ 494 btif_a2dp_set_tx_flush(TRUE); 495 } 496 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 497 { 498 btif_a2dp_set_rx_flush(TRUE); 499 } 500 501 btif_a2dp_on_stopped(NULL); 502 break; 503 504 case BTIF_SM_EXIT_EVT: 505 break; 506 507 case BTA_AV_CLOSE_EVT: 508 509 /* inform the application that we are disconnecting */ 510 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 511 512 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 513 break; 514 515 /* Handle the RC_CLOSE event for the cleanup */ 516 case BTA_AV_RC_CLOSE_EVT: 517 btif_rc_handler(event, (tBTA_AV*)p_data); 518 break; 519 520 default: 521 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 522 dump_av_sm_event_name(event)); 523 return FALSE; 524 } 525 return TRUE; 526} 527 528 529/***************************************************************************** 530** 531** Function btif_av_state_opened_handler 532** 533** Description Handles AV events while AVDTP is in OPEN state 534** 535** Returns TRUE if event was processed, FALSE otherwise 536** 537*******************************************************************************/ 538 539static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) 540{ 541 tBTA_AV *p_av = (tBTA_AV*)p_data; 542 543 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 544 dump_av_sm_event_name(event), btif_av_cb.flags); 545 546 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) && 547 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) ) 548 { 549 BTIF_TRACE_EVENT1("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__); 550 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 551 } 552 553 switch (event) 554 { 555 case BTIF_SM_ENTER_EVT: 556 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP; 557 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 558 break; 559 560 case BTIF_SM_EXIT_EVT: 561 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 562 break; 563 564 case BTIF_AV_START_STREAM_REQ_EVT: 565 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 566 { 567 BTA_AvStart(); 568 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START; 569 break; 570 } 571 btif_a2dp_setup_codec(); 572 BTA_AvStart(); 573 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START; 574 break; 575 576 case BTA_AV_START_EVT: 577 { 578 BTIF_TRACE_EVENT3("BTA_AV_START_EVT status %d, suspending %d, init %d", 579 p_av->start.status, p_av->start.suspending, p_av->start.initiator); 580 581 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE)) 582 return TRUE; 583 584 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/ 585 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 586 { 587 if (btif_a2dp_on_started(&p_av->start, 588 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0))) 589 { 590 /* only clear pending flag after acknowledgement */ 591 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 592 } 593 } 594 595 /* remain in open state if status failed */ 596 if (p_av->start.status != BTA_AV_SUCCESS) 597 return FALSE; 598 599 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 600 { 601 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/ 602 } 603 604 /* change state to started, send acknowledgement if start is pending */ 605 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) { 606 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 607 btif_a2dp_on_started(NULL, TRUE); 608 /* pending start flag will be cleared when exit current state */ 609 } 610 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED); 611 612 } break; 613 614 case BTIF_AV_DISCONNECT_REQ_EVT: 615 BTA_AvClose(btif_av_cb.bta_handle); 616 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { 617 BTA_AvCloseRc(btif_av_cb.bta_handle); 618 } 619 620 /* inform the application that we are disconnecting */ 621 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda)); 622 break; 623 624 case BTA_AV_CLOSE_EVT: 625 /* avdtp link is closed */ 626 btif_a2dp_on_stopped(NULL); 627 628 /* inform the application that we are disconnected */ 629 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 630 631 /* change state to idle, send acknowledgement if start is pending */ 632 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) { 633 btif_a2dp_ack_fail(); 634 /* pending start flag will be cleared when exit current state */ 635 } 636 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 637 break; 638 639 case BTA_AV_RECONFIG_EVT: 640 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) && 641 (p_av->reconfig.status == BTA_AV_SUCCESS)) 642 { 643 APPL_TRACE_WARNING0("reconfig done BTA_AVstart()"); 644 BTA_AvStart(); 645 } 646 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) 647 { 648 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 649 btif_a2dp_ack_fail(); 650 } 651 break; 652 653 CHECK_RC_EVENT(event, p_data); 654 655 default: 656 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 657 dump_av_sm_event_name(event)); 658 return FALSE; 659 660 } 661 return TRUE; 662} 663 664/***************************************************************************** 665** 666** Function btif_av_state_started_handler 667** 668** Description Handles AV events while A2DP stream is started 669** 670** Returns TRUE if event was processed, FALSE otherwise 671** 672*******************************************************************************/ 673 674static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data) 675{ 676 tBTA_AV *p_av = (tBTA_AV*)p_data; 677 678 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 679 dump_av_sm_event_name(event), btif_av_cb.flags); 680 681 switch (event) 682 { 683 case BTIF_SM_ENTER_EVT: 684 685 /* we are again in started state, clear any remote suspend flags */ 686 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 687 688 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda)); 689 690 /* increase the a2dp consumer task priority temporarily when start 691 ** audio playing, to avoid overflow the audio packet queue. */ 692 adjust_priority_a2dp(TRUE); 693 694 break; 695 696 case BTIF_SM_EXIT_EVT: 697 /* restore the a2dp consumer task priority when stop audio playing. */ 698 adjust_priority_a2dp(FALSE); 699 700 break; 701 702 case BTIF_AV_START_STREAM_REQ_EVT: 703 /* we were remotely started, just ack back the local request */ 704 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 705 btif_a2dp_on_started(NULL, TRUE); 706 break; 707 708 /* fixme -- use suspend = true always to work around issue with BTA AV */ 709 case BTIF_AV_STOP_STREAM_REQ_EVT: 710 case BTIF_AV_SUSPEND_STREAM_REQ_EVT: 711 712 /* set pending flag to ensure btif task is not trying to restart 713 stream while suspend is in progress */ 714 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 715 716 /* if we were remotely suspended but suspend locally, local suspend 717 always overrides */ 718 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 719 720 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 721 { 722 /* immediately stop transmission of frames while suspend is pending */ 723 btif_a2dp_set_tx_flush(TRUE); 724 } 725 726 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { 727 btif_a2dp_set_rx_flush(TRUE); 728 btif_a2dp_on_stopped(NULL); 729 } 730 731 BTA_AvStop(TRUE); 732 break; 733 734 case BTIF_AV_DISCONNECT_REQ_EVT: 735 736 /* request avdtp to close */ 737 BTA_AvClose(btif_av_cb.bta_handle); 738 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { 739 BTA_AvCloseRc(btif_av_cb.bta_handle); 740 } 741 742 /* inform the application that we are disconnecting */ 743 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda)); 744 745 /* wait in closing state until fully closed */ 746 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING); 747 break; 748 749 case BTA_AV_SUSPEND_EVT: 750 751 BTIF_TRACE_EVENT2("BTA_AV_SUSPEND_EVT status %d, init %d", 752 p_av->suspend.status, p_av->suspend.initiator); 753 754 /* a2dp suspended, stop media task until resumed */ 755 btif_a2dp_on_suspended(&p_av->suspend); 756 757 /* if not successful, remain in current state */ 758 if (p_av->suspend.status != BTA_AV_SUCCESS) 759 { 760 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 761 762 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 763 { 764 /* suspend failed, reset back tx flush state */ 765 btif_a2dp_set_tx_flush(FALSE); 766 } 767 return FALSE; 768 } 769 770 if (p_av->suspend.initiator != TRUE) 771 { 772 /* remote suspend, notify HAL and await audioflinger to 773 suspend/stop stream */ 774 775 /* set remote suspend flag to block media task from restarting 776 stream only if we did not already initiate a local suspend */ 777 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0) 778 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND; 779 780 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda)); 781 } 782 else 783 { 784 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); 785 } 786 787 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); 788 789 /* suspend completed and state changed, clear pending status */ 790 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 791 break; 792 793 case BTA_AV_STOP_EVT: 794 795 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP; 796 btif_a2dp_on_stopped(&p_av->suspend); 797 798 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); 799 800 /* if stop was successful, change state to open */ 801 if (p_av->suspend.status == BTA_AV_SUCCESS) 802 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); 803 804 break; 805 806 case BTA_AV_CLOSE_EVT: 807 808 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP; 809 810 /* avdtp link is closed */ 811 btif_a2dp_on_stopped(NULL); 812 813 /* inform the application that we are disconnected */ 814 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 815 816 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 817 break; 818 819 CHECK_RC_EVENT(event, p_data); 820 821 default: 822 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 823 dump_av_sm_event_name(event)); 824 return FALSE; 825 826 } 827 return TRUE; 828} 829 830/***************************************************************************** 831** Local event handlers 832******************************************************************************/ 833 834static void btif_av_handle_event(UINT16 event, char* p_param) 835{ 836 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param); 837} 838 839static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data) 840{ 841 /* Switch to BTIF context */ 842 btif_transfer_context(btif_av_handle_event, event, 843 (char*)p_data, sizeof(tBTA_AV), NULL); 844} 845 846static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data) 847{ 848 btif_sm_state_t state; 849 UINT8 que_len; 850 tA2D_STATUS a2d_status; 851 tA2D_SBC_CIE sbc_cie; 852 btif_av_sink_config_req_t config_req; 853 854 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */ 855 { 856 state= btif_sm_get_state(btif_av_cb.sm_handle); 857 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */ 858 (state == BTIF_AV_STATE_OPENED) ) 859 { 860 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data); 861 BTIF_TRACE_DEBUG1(" Packets in Que %d",que_len); 862 } 863 else 864 return; 865 } 866 867 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) { 868 /* send a command to BT Media Task */ 869 btif_reset_decoder((UINT8*)p_data); 870 871 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE); 872 if (a2d_status == A2D_SUCCESS) { 873 /* Switch to BTIF context */ 874 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq); 875 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode); 876 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT, 877 (char*)&config_req, sizeof(config_req), NULL); 878 } else { 879 APPL_TRACE_ERROR1("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status); 880 } 881 } 882} 883/******************************************************************************* 884** 885** Function btif_av_init 886** 887** Description Initializes btif AV if not already done 888** 889** Returns bt_status_t 890** 891*******************************************************************************/ 892 893bt_status_t btif_av_init() 894{ 895 btif_av_cb.sm_handle = NULL; 896 897 if (btif_av_cb.sm_handle == NULL) 898 { 899 if (btif_a2dp_start_media_task() != GKI_SUCCESS) 900 return BT_STATUS_FAIL; 901 902 btif_enable_service(BTA_A2DP_SERVICE_ID); 903 904 /* Also initialize the AV state machine */ 905 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE); 906 907 btif_a2dp_on_init(); 908 909 return BT_STATUS_SUCCESS; 910 } 911 912 return BT_STATUS_DONE; 913} 914 915/******************************************************************************* 916** 917** Function init_src 918** 919** Description Initializes the AV interface for source mode 920** 921** Returns bt_status_t 922** 923*******************************************************************************/ 924 925static bt_status_t init_src(btav_callbacks_t* callbacks) 926{ 927 bt_status_t status; 928 929 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 930 931 if (bt_av_sink_callbacks != NULL) { 932 // already did btif_av_init() 933 status = BT_STATUS_SUCCESS; 934 } else { 935 status = btif_av_init(); 936 } 937 938 if (status == BT_STATUS_SUCCESS) { 939 bt_av_src_callbacks = callbacks; 940 } 941 942 return status; 943} 944 945/******************************************************************************* 946** 947** Function init_sink 948** 949** Description Initializes the AV interface for sink mode 950** 951** Returns bt_status_t 952** 953*******************************************************************************/ 954 955static bt_status_t init_sink(btav_callbacks_t* callbacks) 956{ 957 bt_status_t status; 958 959 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 960 961 if (bt_av_src_callbacks != NULL) { 962 // already did btif_av_init() 963 status = BT_STATUS_SUCCESS; 964 } else { 965 status = btif_av_init(); 966 } 967 968 if (status == BT_STATUS_SUCCESS) { 969 bt_av_sink_callbacks = callbacks; 970 BTA_AvEnable_Sink(TRUE); 971 } 972 973 return status; 974} 975 976/******************************************************************************* 977** 978** Function connect 979** 980** Description Establishes the AV signalling channel with the remote headset 981** 982** Returns bt_status_t 983** 984*******************************************************************************/ 985 986static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid) 987{ 988 btif_av_connect_req_t connect_req; 989 connect_req.target_bda = bd_addr; 990 connect_req.uuid = uuid; 991 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 992 993 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req); 994 995 return BT_STATUS_SUCCESS; 996} 997 998static bt_status_t connect_src(bt_bdaddr_t *bd_addr) 999{ 1000 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1001 CHECK_BTAV_INIT(); 1002 1003 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int); 1004} 1005 1006static bt_status_t connect_sink(bt_bdaddr_t *bd_addr) 1007{ 1008 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1009 CHECK_BTAV_INIT(); 1010 1011 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int); 1012} 1013 1014/******************************************************************************* 1015** 1016** Function disconnect 1017** 1018** Description Tears down the AV signalling channel with the remote headset 1019** 1020** Returns bt_status_t 1021** 1022*******************************************************************************/ 1023static bt_status_t disconnect(bt_bdaddr_t *bd_addr) 1024{ 1025 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1026 1027 CHECK_BTAV_INIT(); 1028 1029 /* Switch to BTIF context */ 1030 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT, 1031 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1032} 1033 1034/******************************************************************************* 1035** 1036** Function cleanup 1037** 1038** Description Shuts down the AV interface and does the cleanup 1039** 1040** Returns None 1041** 1042*******************************************************************************/ 1043static void cleanup(void) 1044{ 1045 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1046 1047 btif_a2dp_stop_media_task(); 1048 1049 btif_disable_service(BTA_A2DP_SERVICE_ID); 1050 1051 /* Also shut down the AV state machine */ 1052 btif_sm_shutdown(btif_av_cb.sm_handle); 1053 btif_av_cb.sm_handle = NULL; 1054} 1055 1056static void cleanup_src(void) { 1057 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1058 1059 if (bt_av_src_callbacks) 1060 { 1061 bt_av_src_callbacks = NULL; 1062 if (bt_av_sink_callbacks == NULL) 1063 cleanup(); 1064 } 1065} 1066 1067static void cleanup_sink(void) { 1068 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1069 1070 if (bt_av_sink_callbacks) 1071 { 1072 bt_av_sink_callbacks = NULL; 1073 if (bt_av_src_callbacks == NULL) 1074 cleanup(); 1075 } 1076} 1077 1078static const btav_interface_t bt_av_src_interface = { 1079 sizeof(btav_interface_t), 1080 init_src, 1081 connect_src, 1082 disconnect, 1083 cleanup_src, 1084}; 1085 1086static const btav_interface_t bt_av_sink_interface = { 1087 sizeof(btav_interface_t), 1088 init_sink, 1089 connect_sink, 1090 disconnect, 1091 cleanup_sink, 1092}; 1093 1094/******************************************************************************* 1095** 1096** Function btif_av_get_sm_handle 1097** 1098** Description Fetches current av SM handle 1099** 1100** Returns None 1101** 1102*******************************************************************************/ 1103 1104btif_sm_handle_t btif_av_get_sm_handle(void) 1105{ 1106 return btif_av_cb.sm_handle; 1107} 1108 1109/******************************************************************************* 1110** 1111** Function btif_av_stream_ready 1112** 1113** Description Checks whether AV is ready for starting a stream 1114** 1115** Returns None 1116** 1117*******************************************************************************/ 1118 1119BOOLEAN btif_av_stream_ready(void) 1120{ 1121 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 1122 1123 BTIF_TRACE_DEBUG3("btif_av_stream_ready : sm hdl %d, state %d, flags %x", 1124 btif_av_cb.sm_handle, state, btif_av_cb.flags); 1125 1126 /* also make sure main adapter is enabled */ 1127 if (btif_is_enabled() == 0) 1128 { 1129 BTIF_TRACE_EVENT0("main adapter not enabled"); 1130 return FALSE; 1131 } 1132 1133 /* check if we are remotely suspended or stop is pending */ 1134 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP)) 1135 return FALSE; 1136 1137 return (state == BTIF_AV_STATE_OPENED); 1138} 1139 1140/******************************************************************************* 1141** 1142** Function btif_av_stream_started_ready 1143** 1144** Description Checks whether AV ready for media start in streaming state 1145** 1146** Returns None 1147** 1148*******************************************************************************/ 1149 1150BOOLEAN btif_av_stream_started_ready(void) 1151{ 1152 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 1153 1154 BTIF_TRACE_DEBUG3("btif_av_stream_started : sm hdl %d, state %d, flags %x", 1155 btif_av_cb.sm_handle, state, btif_av_cb.flags); 1156 1157 /* disallow media task to start if we have pending actions */ 1158 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND 1159 | BTIF_AV_FLAG_PENDING_STOP)) 1160 return FALSE; 1161 1162 return (state == BTIF_AV_STATE_STARTED); 1163} 1164 1165/******************************************************************************* 1166** 1167** Function btif_dispatch_sm_event 1168** 1169** Description Send event to AV statemachine 1170** 1171** Returns None 1172** 1173*******************************************************************************/ 1174 1175/* used to pass events to AV statemachine from other tasks */ 1176void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len) 1177{ 1178 /* Switch to BTIF context */ 1179 btif_transfer_context(btif_av_handle_event, event, 1180 (char*)p_data, len, NULL); 1181} 1182 1183/******************************************************************************* 1184** 1185** Function btif_av_execute_service 1186** 1187** Description Initializes/Shuts down the service 1188** 1189** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 1190** 1191*******************************************************************************/ 1192bt_status_t btif_av_execute_service(BOOLEAN b_enable) 1193{ 1194 if (b_enable) 1195 { 1196 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not 1197 * handle this request in order to allow incoming connections to succeed. 1198 * We need to put this back once support for this is added */ 1199 1200 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not 1201 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall 1202 * be initiated by the app/audioflinger layers */ 1203#if (AVRC_METADATA_INCLUDED == TRUE) 1204 BTA_AvEnable(BTA_SEC_AUTHENTICATE, 1205 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD 1206#if (AVRC_ADV_CTRL_INCLUDED == TRUE) 1207 |BTA_AV_FEAT_RCCT 1208 |BTA_AV_FEAT_ADV_CTRL 1209#endif 1210 ,bte_av_callback); 1211#else 1212 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD), 1213 bte_av_callback); 1214#endif 1215 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback); 1216 } 1217 else { 1218 BTA_AvDeregister(btif_av_cb.bta_handle); 1219 BTA_AvDisable(); 1220 } 1221 return BT_STATUS_SUCCESS; 1222} 1223 1224/******************************************************************************* 1225** 1226** Function btif_av_get_src_interface 1227** 1228** Description Get the AV callback interface for A2DP source profile 1229** 1230** Returns btav_interface_t 1231** 1232*******************************************************************************/ 1233const btav_interface_t *btif_av_get_src_interface(void) 1234{ 1235 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1236 return &bt_av_src_interface; 1237} 1238 1239/******************************************************************************* 1240** 1241** Function btif_av_get_sink_interface 1242** 1243** Description Get the AV callback interface for A2DP sink profile 1244** 1245** Returns btav_interface_t 1246** 1247*******************************************************************************/ 1248const btav_interface_t *btif_av_get_sink_interface(void) 1249{ 1250 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1251 return &bt_av_sink_interface; 1252} 1253 1254/******************************************************************************* 1255** 1256** Function btif_av_is_connected 1257** 1258** Description Checks if av has a connected sink 1259** 1260** Returns BOOLEAN 1261** 1262*******************************************************************************/ 1263BOOLEAN btif_av_is_connected(void) 1264{ 1265 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 1266 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED)); 1267} 1268 1269/******************************************************************************* 1270** 1271** Function btif_av_is_peer_edr 1272** 1273** Description Check if the connected a2dp device supports 1274** EDR or not. Only when connected this function 1275** will accurately provide a true capability of 1276** remote peer. If not connected it will always be false. 1277** 1278** Returns TRUE if remote device is capable of EDR 1279** 1280*******************************************************************************/ 1281BOOLEAN btif_av_is_peer_edr(void) 1282{ 1283 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0); 1284 1285 if (btif_av_cb.edr) 1286 return TRUE; 1287 else 1288 return FALSE; 1289} 1290 1291