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