btif_av.c revision e8c3d75b75493911ebf0f99c83676359657178f7
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_WARNING("%s: BTAV not initialized", __FUNCTION__);\ 109 return BT_STATUS_NOT_READY;\ 110}\ 111else\ 112{\ 113 BTIF_TRACE_EVENT("%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_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__); 227 /* In case of AVRCP connection request, we will initiate SRC connection */ 228 connect_req.target_bda = (bt_bdaddr_t*)&peer_addr; 229 connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE; 230 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req); 231 } 232 else 233 { 234 BTIF_TRACE_ERROR("%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_DEBUG("%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_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV"); 326 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc)); 327 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr; 328 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC, 329 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS); 330 btif_rc_handler(event, p_data); 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_DEBUG("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_WARNING("%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_DEBUG("%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_DEBUG(" 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_DEBUG("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_WARNING("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 /* Bring up AVRCP connection too */ 429 BTA_AvOpenRc(btif_av_cb.bta_handle); 430 } 431 btif_queue_advance(); 432 } break; 433 434 case BTIF_AV_SINK_CONFIG_REQ_EVT: 435 { 436 btif_av_sink_config_req_t req; 437 // copy to avoid alignment problems 438 memcpy(&req, p_data, sizeof(req)); 439 440 BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate, 441 req.channel_count); 442 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) { 443 HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda), 444 req.sample_rate, req.channel_count); 445 } 446 } break; 447 448 CHECK_RC_EVENT(event, p_data); 449 450 default: 451 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__, 452 dump_av_sm_event_name(event)); 453 return FALSE; 454 455 } 456 return TRUE; 457} 458 459 460/***************************************************************************** 461** 462** Function btif_av_state_closing_handler 463** 464** Description Intermediate state managing events during closing 465** of avdtp channel 466** 467** Returns TRUE if event was processed, FALSE otherwise 468** 469*******************************************************************************/ 470 471static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data) 472{ 473 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__, 474 dump_av_sm_event_name(event), btif_av_cb.flags); 475 476 switch (event) 477 { 478 case BTIF_SM_ENTER_EVT: 479 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 480 { 481 /* immediately stop transmission of frames */ 482 btif_a2dp_set_tx_flush(TRUE); 483 /* wait for audioflinger to stop a2dp */ 484 } 485 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 486 { 487 btif_a2dp_set_rx_flush(TRUE); 488 } 489 break; 490 491 case BTA_AV_STOP_EVT: 492 case BTIF_AV_STOP_STREAM_REQ_EVT: 493 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 494 { 495 /* immediately flush any pending tx frames while suspend is pending */ 496 btif_a2dp_set_tx_flush(TRUE); 497 } 498 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 499 { 500 btif_a2dp_set_rx_flush(TRUE); 501 } 502 503 btif_a2dp_on_stopped(NULL); 504 break; 505 506 case BTIF_SM_EXIT_EVT: 507 break; 508 509 case BTA_AV_CLOSE_EVT: 510 511 /* inform the application that we are disconnecting */ 512 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 513 514 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 515 break; 516 517 /* Handle the RC_CLOSE event for the cleanup */ 518 case BTA_AV_RC_CLOSE_EVT: 519 btif_rc_handler(event, (tBTA_AV*)p_data); 520 break; 521 522 default: 523 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__, 524 dump_av_sm_event_name(event)); 525 return FALSE; 526 } 527 return TRUE; 528} 529 530 531/***************************************************************************** 532** 533** Function btif_av_state_opened_handler 534** 535** Description Handles AV events while AVDTP is in OPEN state 536** 537** Returns TRUE if event was processed, FALSE otherwise 538** 539*******************************************************************************/ 540 541static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) 542{ 543 tBTA_AV *p_av = (tBTA_AV*)p_data; 544 545 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__, 546 dump_av_sm_event_name(event), btif_av_cb.flags); 547 548 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) && 549 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) ) 550 { 551 BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__); 552 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 553 } 554 555 switch (event) 556 { 557 case BTIF_SM_ENTER_EVT: 558 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP; 559 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 560 break; 561 562 case BTIF_SM_EXIT_EVT: 563 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 564 break; 565 566 case BTIF_AV_START_STREAM_REQ_EVT: 567 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 568 { 569 BTA_AvStart(); 570 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START; 571 break; 572 } 573 btif_a2dp_setup_codec(); 574 BTA_AvStart(); 575 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START; 576 break; 577 578 case BTA_AV_START_EVT: 579 { 580 BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d", 581 p_av->start.status, p_av->start.suspending, p_av->start.initiator); 582 583 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE)) 584 return TRUE; 585 586 /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/ 587 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 588 { 589 if (btif_a2dp_on_started(&p_av->start, 590 ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0))) 591 { 592 /* only clear pending flag after acknowledgement */ 593 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 594 } 595 } 596 597 /* remain in open state if status failed */ 598 if (p_av->start.status != BTA_AV_SUCCESS) 599 return FALSE; 600 601 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) 602 { 603 btif_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/ 604 } 605 606 /* change state to started, send acknowledgement if start is pending */ 607 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) { 608 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 609 btif_a2dp_on_started(NULL, TRUE); 610 /* pending start flag will be cleared when exit current state */ 611 } 612 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED); 613 614 } break; 615 616 case BTIF_AV_DISCONNECT_REQ_EVT: 617 BTA_AvClose(btif_av_cb.bta_handle); 618 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { 619 BTA_AvCloseRc(btif_av_cb.bta_handle); 620 } 621 622 /* inform the application that we are disconnecting */ 623 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda)); 624 break; 625 626 case BTA_AV_CLOSE_EVT: 627 /* avdtp link is closed */ 628 btif_a2dp_on_stopped(NULL); 629 630 /* inform the application that we are disconnected */ 631 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 632 633 /* change state to idle, send acknowledgement if start is pending */ 634 if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) { 635 btif_a2dp_ack_fail(); 636 /* pending start flag will be cleared when exit current state */ 637 } 638 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 639 break; 640 641 case BTA_AV_RECONFIG_EVT: 642 if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) && 643 (p_av->reconfig.status == BTA_AV_SUCCESS)) 644 { 645 APPL_TRACE_WARNING("reconfig done BTA_AVstart()"); 646 BTA_AvStart(); 647 } 648 else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) 649 { 650 btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; 651 btif_a2dp_ack_fail(); 652 } 653 break; 654 655 CHECK_RC_EVENT(event, p_data); 656 657 default: 658 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__, 659 dump_av_sm_event_name(event)); 660 return FALSE; 661 662 } 663 return TRUE; 664} 665 666/***************************************************************************** 667** 668** Function btif_av_state_started_handler 669** 670** Description Handles AV events while A2DP stream is started 671** 672** Returns TRUE if event was processed, FALSE otherwise 673** 674*******************************************************************************/ 675 676static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data) 677{ 678 tBTA_AV *p_av = (tBTA_AV*)p_data; 679 680 BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__, 681 dump_av_sm_event_name(event), btif_av_cb.flags); 682 683 switch (event) 684 { 685 case BTIF_SM_ENTER_EVT: 686 687 /* we are again in started state, clear any remote suspend flags */ 688 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 689 690 btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda)); 691 692 /* increase the a2dp consumer task priority temporarily when start 693 ** audio playing, to avoid overflow the audio packet queue. */ 694 adjust_priority_a2dp(TRUE); 695 696 break; 697 698 case BTIF_SM_EXIT_EVT: 699 /* restore the a2dp consumer task priority when stop audio playing. */ 700 adjust_priority_a2dp(FALSE); 701 702 break; 703 704 case BTIF_AV_START_STREAM_REQ_EVT: 705 /* we were remotely started, just ack back the local request */ 706 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 707 btif_a2dp_on_started(NULL, TRUE); 708 break; 709 710 /* fixme -- use suspend = true always to work around issue with BTA AV */ 711 case BTIF_AV_STOP_STREAM_REQ_EVT: 712 case BTIF_AV_SUSPEND_STREAM_REQ_EVT: 713 714 /* set pending flag to ensure btif task is not trying to restart 715 stream while suspend is in progress */ 716 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 717 718 /* if we were remotely suspended but suspend locally, local suspend 719 always overrides */ 720 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 721 722 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 723 { 724 /* immediately stop transmission of frames while suspend is pending */ 725 btif_a2dp_set_tx_flush(TRUE); 726 } 727 728 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { 729 btif_a2dp_set_rx_flush(TRUE); 730 btif_a2dp_on_stopped(NULL); 731 } 732 733 BTA_AvStop(TRUE); 734 break; 735 736 case BTIF_AV_DISCONNECT_REQ_EVT: 737 738 /* request avdtp to close */ 739 BTA_AvClose(btif_av_cb.bta_handle); 740 if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { 741 BTA_AvCloseRc(btif_av_cb.bta_handle); 742 } 743 744 /* inform the application that we are disconnecting */ 745 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda)); 746 747 /* wait in closing state until fully closed */ 748 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING); 749 break; 750 751 case BTA_AV_SUSPEND_EVT: 752 753 BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d", 754 p_av->suspend.status, p_av->suspend.initiator); 755 756 /* a2dp suspended, stop media task until resumed */ 757 btif_a2dp_on_suspended(&p_av->suspend); 758 759 /* if not successful, remain in current state */ 760 if (p_av->suspend.status != BTA_AV_SUCCESS) 761 { 762 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 763 764 if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) 765 { 766 /* suspend failed, reset back tx flush state */ 767 btif_a2dp_set_tx_flush(FALSE); 768 } 769 return FALSE; 770 } 771 772 if (p_av->suspend.initiator != TRUE) 773 { 774 /* remote suspend, notify HAL and await audioflinger to 775 suspend/stop stream */ 776 777 /* set remote suspend flag to block media task from restarting 778 stream only if we did not already initiate a local suspend */ 779 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0) 780 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND; 781 782 btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda)); 783 } 784 else 785 { 786 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); 787 } 788 789 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); 790 791 /* suspend completed and state changed, clear pending status */ 792 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 793 break; 794 795 case BTA_AV_STOP_EVT: 796 797 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP; 798 btif_a2dp_on_stopped(&p_av->suspend); 799 800 btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); 801 802 /* if stop was successful, change state to open */ 803 if (p_av->suspend.status == BTA_AV_SUCCESS) 804 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); 805 806 break; 807 808 case BTA_AV_CLOSE_EVT: 809 810 btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP; 811 812 /* avdtp link is closed */ 813 btif_a2dp_on_stopped(NULL); 814 815 /* inform the application that we are disconnected */ 816 btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 817 818 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 819 break; 820 821 CHECK_RC_EVENT(event, p_data); 822 823 default: 824 BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__, 825 dump_av_sm_event_name(event)); 826 return FALSE; 827 828 } 829 return TRUE; 830} 831 832/***************************************************************************** 833** Local event handlers 834******************************************************************************/ 835 836static void btif_av_handle_event(UINT16 event, char* p_param) 837{ 838 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param); 839} 840 841static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data) 842{ 843 /* Switch to BTIF context */ 844 btif_transfer_context(btif_av_handle_event, event, 845 (char*)p_data, sizeof(tBTA_AV), NULL); 846} 847 848static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data) 849{ 850 btif_sm_state_t state; 851 UINT8 que_len; 852 tA2D_STATUS a2d_status; 853 tA2D_SBC_CIE sbc_cie; 854 btif_av_sink_config_req_t config_req; 855 856 if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */ 857 { 858 state= btif_sm_get_state(btif_av_cb.sm_handle); 859 if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */ 860 (state == BTIF_AV_STATE_OPENED) ) 861 { 862 que_len = btif_media_sink_enque_buf((BT_HDR *)p_data); 863 BTIF_TRACE_DEBUG(" Packets in Que %d",que_len); 864 } 865 else 866 return; 867 } 868 869 if (event == BTA_AV_MEDIA_SINK_CFG_EVT) { 870 /* send a command to BT Media Task */ 871 btif_reset_decoder((UINT8*)p_data); 872 873 a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE); 874 if (a2d_status == A2D_SUCCESS) { 875 /* Switch to BTIF context */ 876 config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq); 877 config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode); 878 btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT, 879 (char*)&config_req, sizeof(config_req), NULL); 880 } else { 881 APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status); 882 } 883 } 884} 885/******************************************************************************* 886** 887** Function btif_av_init 888** 889** Description Initializes btif AV if not already done 890** 891** Returns bt_status_t 892** 893*******************************************************************************/ 894 895bt_status_t btif_av_init() 896{ 897 btif_av_cb.sm_handle = NULL; 898 899 if (btif_av_cb.sm_handle == NULL) 900 { 901 if (btif_a2dp_start_media_task() != GKI_SUCCESS) 902 return BT_STATUS_FAIL; 903 904 btif_enable_service(BTA_A2DP_SERVICE_ID); 905 906 /* Also initialize the AV state machine */ 907 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE); 908 909 btif_a2dp_on_init(); 910 911 return BT_STATUS_SUCCESS; 912 } 913 914 return BT_STATUS_DONE; 915} 916 917/******************************************************************************* 918** 919** Function init_src 920** 921** Description Initializes the AV interface for source mode 922** 923** Returns bt_status_t 924** 925*******************************************************************************/ 926 927static bt_status_t init_src(btav_callbacks_t* callbacks) 928{ 929 bt_status_t status; 930 931 BTIF_TRACE_EVENT("%s", __FUNCTION__); 932 933 if (bt_av_sink_callbacks != NULL) { 934 // already did btif_av_init() 935 status = BT_STATUS_SUCCESS; 936 } else { 937 status = btif_av_init(); 938 } 939 940 if (status == BT_STATUS_SUCCESS) { 941 bt_av_src_callbacks = callbacks; 942 } 943 944 return status; 945} 946 947/******************************************************************************* 948** 949** Function init_sink 950** 951** Description Initializes the AV interface for sink mode 952** 953** Returns bt_status_t 954** 955*******************************************************************************/ 956 957static bt_status_t init_sink(btav_callbacks_t* callbacks) 958{ 959 bt_status_t status; 960 961 BTIF_TRACE_EVENT("%s", __FUNCTION__); 962 963 if (bt_av_src_callbacks != NULL) { 964 // already did btif_av_init() 965 status = BT_STATUS_SUCCESS; 966 } else { 967 status = btif_av_init(); 968 } 969 970 if (status == BT_STATUS_SUCCESS) { 971 bt_av_sink_callbacks = callbacks; 972 BTA_AvEnable_Sink(TRUE); 973 } 974 975 return status; 976} 977 978/******************************************************************************* 979** 980** Function connect 981** 982** Description Establishes the AV signalling channel with the remote headset 983** 984** Returns bt_status_t 985** 986*******************************************************************************/ 987 988static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid) 989{ 990 btif_av_connect_req_t connect_req; 991 connect_req.target_bda = bd_addr; 992 connect_req.uuid = uuid; 993 BTIF_TRACE_EVENT("%s", __FUNCTION__); 994 995 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req); 996 997 return BT_STATUS_SUCCESS; 998} 999 1000static bt_status_t connect_src(bt_bdaddr_t *bd_addr) 1001{ 1002 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1003 CHECK_BTAV_INIT(); 1004 1005 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int); 1006} 1007 1008static bt_status_t connect_sink(bt_bdaddr_t *bd_addr) 1009{ 1010 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1011 CHECK_BTAV_INIT(); 1012 1013 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int); 1014} 1015 1016/******************************************************************************* 1017** 1018** Function disconnect 1019** 1020** Description Tears down the AV signalling channel with the remote headset 1021** 1022** Returns bt_status_t 1023** 1024*******************************************************************************/ 1025static bt_status_t disconnect(bt_bdaddr_t *bd_addr) 1026{ 1027 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1028 1029 CHECK_BTAV_INIT(); 1030 1031 /* Switch to BTIF context */ 1032 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT, 1033 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 1034} 1035 1036/******************************************************************************* 1037** 1038** Function cleanup 1039** 1040** Description Shuts down the AV interface and does the cleanup 1041** 1042** Returns None 1043** 1044*******************************************************************************/ 1045static void cleanup(void) 1046{ 1047 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1048 1049 btif_a2dp_stop_media_task(); 1050 1051 btif_disable_service(BTA_A2DP_SERVICE_ID); 1052 1053 /* Also shut down the AV state machine */ 1054 btif_sm_shutdown(btif_av_cb.sm_handle); 1055 btif_av_cb.sm_handle = NULL; 1056} 1057 1058static void cleanup_src(void) { 1059 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1060 1061 if (bt_av_src_callbacks) 1062 { 1063 bt_av_src_callbacks = NULL; 1064 if (bt_av_sink_callbacks == NULL) 1065 cleanup(); 1066 } 1067} 1068 1069static void cleanup_sink(void) { 1070 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1071 1072 if (bt_av_sink_callbacks) 1073 { 1074 bt_av_sink_callbacks = NULL; 1075 if (bt_av_src_callbacks == NULL) 1076 cleanup(); 1077 } 1078} 1079 1080static const btav_interface_t bt_av_src_interface = { 1081 sizeof(btav_interface_t), 1082 init_src, 1083 connect_src, 1084 disconnect, 1085 cleanup_src, 1086}; 1087 1088static const btav_interface_t bt_av_sink_interface = { 1089 sizeof(btav_interface_t), 1090 init_sink, 1091 connect_sink, 1092 disconnect, 1093 cleanup_sink, 1094}; 1095 1096/******************************************************************************* 1097** 1098** Function btif_av_get_sm_handle 1099** 1100** Description Fetches current av SM handle 1101** 1102** Returns None 1103** 1104*******************************************************************************/ 1105 1106btif_sm_handle_t btif_av_get_sm_handle(void) 1107{ 1108 return btif_av_cb.sm_handle; 1109} 1110 1111/******************************************************************************* 1112** 1113** Function btif_av_stream_ready 1114** 1115** Description Checks whether AV is ready for starting a stream 1116** 1117** Returns None 1118** 1119*******************************************************************************/ 1120 1121BOOLEAN btif_av_stream_ready(void) 1122{ 1123 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 1124 1125 BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x", 1126 btif_av_cb.sm_handle, state, btif_av_cb.flags); 1127 1128 /* also make sure main adapter is enabled */ 1129 if (btif_is_enabled() == 0) 1130 { 1131 BTIF_TRACE_EVENT("main adapter not enabled"); 1132 return FALSE; 1133 } 1134 1135 /* check if we are remotely suspended or stop is pending */ 1136 if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP)) 1137 return FALSE; 1138 1139 return (state == BTIF_AV_STATE_OPENED); 1140} 1141 1142/******************************************************************************* 1143** 1144** Function btif_av_stream_started_ready 1145** 1146** Description Checks whether AV ready for media start in streaming state 1147** 1148** Returns None 1149** 1150*******************************************************************************/ 1151 1152BOOLEAN btif_av_stream_started_ready(void) 1153{ 1154 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 1155 1156 BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x", 1157 btif_av_cb.sm_handle, state, btif_av_cb.flags); 1158 1159 /* disallow media task to start if we have pending actions */ 1160 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND 1161 | BTIF_AV_FLAG_PENDING_STOP)) 1162 return FALSE; 1163 1164 return (state == BTIF_AV_STATE_STARTED); 1165} 1166 1167/******************************************************************************* 1168** 1169** Function btif_dispatch_sm_event 1170** 1171** Description Send event to AV statemachine 1172** 1173** Returns None 1174** 1175*******************************************************************************/ 1176 1177/* used to pass events to AV statemachine from other tasks */ 1178void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len) 1179{ 1180 /* Switch to BTIF context */ 1181 btif_transfer_context(btif_av_handle_event, event, 1182 (char*)p_data, len, NULL); 1183} 1184 1185/******************************************************************************* 1186** 1187** Function btif_av_execute_service 1188** 1189** Description Initializes/Shuts down the service 1190** 1191** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 1192** 1193*******************************************************************************/ 1194bt_status_t btif_av_execute_service(BOOLEAN b_enable) 1195{ 1196 if (b_enable) 1197 { 1198 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not 1199 * handle this request in order to allow incoming connections to succeed. 1200 * We need to put this back once support for this is added */ 1201 1202 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not 1203 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall 1204 * be initiated by the app/audioflinger layers */ 1205#if (AVRC_METADATA_INCLUDED == TRUE) 1206 BTA_AvEnable(BTA_SEC_AUTHENTICATE, 1207 BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD 1208#if (AVRC_ADV_CTRL_INCLUDED == TRUE) 1209 |BTA_AV_FEAT_RCCT 1210 |BTA_AV_FEAT_ADV_CTRL 1211#endif 1212 ,bte_av_callback); 1213#else 1214 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD), 1215 bte_av_callback); 1216#endif 1217 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback); 1218 } 1219 else { 1220 BTA_AvDeregister(btif_av_cb.bta_handle); 1221 BTA_AvDisable(); 1222 } 1223 return BT_STATUS_SUCCESS; 1224} 1225 1226/******************************************************************************* 1227** 1228** Function btif_av_get_src_interface 1229** 1230** Description Get the AV callback interface for A2DP source profile 1231** 1232** Returns btav_interface_t 1233** 1234*******************************************************************************/ 1235const btav_interface_t *btif_av_get_src_interface(void) 1236{ 1237 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1238 return &bt_av_src_interface; 1239} 1240 1241/******************************************************************************* 1242** 1243** Function btif_av_get_sink_interface 1244** 1245** Description Get the AV callback interface for A2DP sink profile 1246** 1247** Returns btav_interface_t 1248** 1249*******************************************************************************/ 1250const btav_interface_t *btif_av_get_sink_interface(void) 1251{ 1252 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1253 return &bt_av_sink_interface; 1254} 1255 1256/******************************************************************************* 1257** 1258** Function btif_av_is_connected 1259** 1260** Description Checks if av has a connected sink 1261** 1262** Returns BOOLEAN 1263** 1264*******************************************************************************/ 1265BOOLEAN btif_av_is_connected(void) 1266{ 1267 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 1268 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED)); 1269} 1270 1271/******************************************************************************* 1272** 1273** Function btif_av_is_peer_edr 1274** 1275** Description Check if the connected a2dp device supports 1276** EDR or not. Only when connected this function 1277** will accurately provide a true capability of 1278** remote peer. If not connected it will always be false. 1279** 1280** Returns TRUE if remote device is capable of EDR 1281** 1282*******************************************************************************/ 1283BOOLEAN btif_av_is_peer_edr(void) 1284{ 1285 ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0); 1286 1287 if (btif_av_cb.edr) 1288 return TRUE; 1289 else 1290 return FALSE; 1291} 1292 1293