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 "hardware/bt_av.h" 30 31#define LOG_TAG "BTIF_AV" 32 33#include "btif_av.h" 34#include "btif_util.h" 35#include "btif_profile_queue.h" 36#include "bta_api.h" 37#include "btif_media.h" 38#include "bta_av_api.h" 39#include "gki.h" 40#include "bd.h" 41#include "btu.h" 42 43/***************************************************************************** 44** Constants & Macros 45******************************************************************************/ 46#define BTIF_AV_SERVICE_NAME "Advanced Audio" 47 48#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS 2 49 50typedef enum { 51 BTIF_AV_STATE_IDLE = 0x0, 52 BTIF_AV_STATE_OPENING, 53 BTIF_AV_STATE_OPENED, 54 BTIF_AV_STATE_STARTED, 55 BTIF_AV_STATE_CLOSING 56} btif_av_state_t; 57 58/* Should not need dedicated suspend state as actual actions are no 59 different than open state. Suspend flags are needed however to prevent 60 media task from trying to restart stream during remote suspend or while 61 we are in the process of a local suspend */ 62 63#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1 64#define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2 65 66/***************************************************************************** 67** Local type definitions 68******************************************************************************/ 69 70typedef struct 71{ 72 tBTA_AV_HNDL bta_handle; 73 bt_bdaddr_t peer_bda; 74 btif_sm_handle_t sm_handle; 75 UINT8 flags; 76} btif_av_cb_t; 77 78/***************************************************************************** 79** Static variables 80******************************************************************************/ 81static btav_callbacks_t *bt_av_callbacks = NULL; 82static btif_av_cb_t btif_av_cb; 83static TIMER_LIST_ENT tle_av_open_on_rc; 84 85/* both interface and media task needs to be ready to alloc incoming request */ 86#define CHECK_BTAV_INIT() if ((bt_av_callbacks == NULL) || (btif_av_cb.sm_handle == NULL))\ 87{\ 88 BTIF_TRACE_WARNING1("%s: BTAV not initialized", __FUNCTION__);\ 89 return BT_STATUS_NOT_READY;\ 90}\ 91else\ 92{\ 93 BTIF_TRACE_EVENT1("%s", __FUNCTION__);\ 94} 95 96/* Helper macro to avoid code duplication in the state machine handlers */ 97#define CHECK_RC_EVENT(e, d) \ 98 case BTA_AV_RC_OPEN_EVT: \ 99 case BTA_AV_RC_CLOSE_EVT: \ 100 case BTA_AV_REMOTE_CMD_EVT: \ 101 case BTA_AV_VENDOR_CMD_EVT: \ 102 case BTA_AV_META_MSG_EVT: \ 103 case BTA_AV_RC_FEAT_EVT: \ 104 { \ 105 btif_rc_handler(e, d);\ 106 }break; \ 107 108static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data); 109static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data); 110static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data); 111static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data); 112static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data); 113 114static const btif_sm_handler_t btif_av_state_handlers[] = 115{ 116 btif_av_state_idle_handler, 117 btif_av_state_opening_handler, 118 btif_av_state_opened_handler, 119 btif_av_state_started_handler, 120 btif_av_state_closing_handler 121}; 122 123/************************************************************************* 124** Extern functions 125*************************************************************************/ 126extern void btif_rc_init(void); 127extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data); 128extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr); 129extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp); 130 131/***************************************************************************** 132** Local helper functions 133******************************************************************************/ 134 135const char *dump_av_sm_state_name(btif_av_state_t state) 136{ 137 switch (state) 138 { 139 CASE_RETURN_STR(BTIF_AV_STATE_IDLE) 140 CASE_RETURN_STR(BTIF_AV_STATE_OPENING) 141 CASE_RETURN_STR(BTIF_AV_STATE_OPENED) 142 CASE_RETURN_STR(BTIF_AV_STATE_STARTED) 143 CASE_RETURN_STR(BTIF_AV_STATE_CLOSING) 144 default: return "UNKNOWN_STATE"; 145 } 146} 147 148const char *dump_av_sm_event_name(btif_av_sm_event_t event) 149{ 150 switch((int)event) 151 { 152 CASE_RETURN_STR(BTA_AV_ENABLE_EVT) 153 CASE_RETURN_STR(BTA_AV_REGISTER_EVT) 154 CASE_RETURN_STR(BTA_AV_OPEN_EVT) 155 CASE_RETURN_STR(BTA_AV_CLOSE_EVT) 156 CASE_RETURN_STR(BTA_AV_START_EVT) 157 CASE_RETURN_STR(BTA_AV_STOP_EVT) 158 CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT) 159 CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT) 160 CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT) 161 CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT) 162 CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT) 163 CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT) 164 CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT) 165 CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT) 166 CASE_RETURN_STR(BTA_AV_RECONFIG_EVT) 167 CASE_RETURN_STR(BTA_AV_SUSPEND_EVT) 168 CASE_RETURN_STR(BTA_AV_PENDING_EVT) 169 CASE_RETURN_STR(BTA_AV_META_MSG_EVT) 170 CASE_RETURN_STR(BTA_AV_REJECT_EVT) 171 CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT) 172 CASE_RETURN_STR(BTIF_SM_ENTER_EVT) 173 CASE_RETURN_STR(BTIF_SM_EXIT_EVT) 174 CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT) 175 CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT) 176 CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT) 177 CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT) 178 CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT) 179 CASE_RETURN_STR(BTIF_AV_RECONFIGURE_REQ_EVT) 180 181 default: return "UNKNOWN_EVENT"; 182 } 183} 184 185/**************************************************************************** 186** Local helper functions 187*****************************************************************************/ 188/******************************************************************************* 189** 190** Function btif_initiate_av_open_tmr_hdlr 191** 192** Description Timer to trigger AV open if the remote headset establishes 193** RC connection w/o AV connection. The timer is needed to IOP 194** with headsets that do establish AV after RC connection. 195** 196** Returns void 197** 198*******************************************************************************/ 199static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle) 200{ 201 BD_ADDR peer_addr; 202 203 /* is there at least one RC connection - There should be */ 204 if (btif_rc_get_connected_peer(peer_addr)) { 205 BTIF_TRACE_DEBUG1("%s Issuing connect to the remote RC peer", __FUNCTION__); 206 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (void*)&peer_addr); 207 } 208 else 209 { 210 BTIF_TRACE_ERROR1("%s No connected RC peers", __FUNCTION__); 211 } 212} 213 214/***************************************************************************** 215** Static functions 216******************************************************************************/ 217 218/***************************************************************************** 219** 220** Function btif_av_state_idle_handler 221** 222** Description State managing disconnected AV link 223** 224** Returns TRUE if event was processed, FALSE otherwise 225** 226*******************************************************************************/ 227 228static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data) 229{ 230 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 231 dump_av_sm_event_name(event), btif_av_cb.flags); 232 233 switch (event) 234 { 235 case BTIF_SM_ENTER_EVT: 236 /* clear the peer_bda */ 237 memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t)); 238 btif_av_cb.flags = 0; 239 btif_a2dp_on_idle(); 240 break; 241 242 case BTIF_SM_EXIT_EVT: 243 break; 244 245 case BTA_AV_ENABLE_EVT: 246 break; 247 248 case BTA_AV_REGISTER_EVT: 249 btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl; 250 break; 251 252 case BTA_AV_PENDING_EVT: 253 case BTIF_AV_CONNECT_REQ_EVT: 254 { 255 if (event == BTIF_AV_CONNECT_REQ_EVT) 256 { 257 memcpy(&btif_av_cb.peer_bda, (bt_bdaddr_t*)p_data, sizeof(bt_bdaddr_t)); 258 } 259 else if (event == BTA_AV_PENDING_EVT) 260 { 261 bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr); 262 } 263 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle, 264 TRUE, BTA_SEC_NONE); 265 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING); 266 } break; 267 268 case BTA_AV_RC_OPEN_EVT: 269 /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So 270 * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore, 271 * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state. 272 * We initiate the AV connection after a small 3s timeout to avoid any collisions from the 273 * headsets, as some headsets initiate the AVRC connection first and then 274 * immediately initiate the AV connection 275 * 276 * TODO: We may need to do this only on an AVRCP Play. FixMe 277 */ 278 279 BTIF_TRACE_DEBUG0("BTA_AV_RC_OPEN_EVT received w/o AV"); 280 memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc)); 281 tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr; 282 btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC, 283 BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS); 284 btif_rc_handler(event, p_data); 285 break; 286 287 case BTA_AV_REMOTE_CMD_EVT: 288 case BTA_AV_VENDOR_CMD_EVT: 289 case BTA_AV_META_MSG_EVT: 290 case BTA_AV_RC_FEAT_EVT: 291 btif_rc_handler(event, (tBTA_AV*)p_data); 292 break; 293 294 case BTA_AV_RC_CLOSE_EVT: 295 if (tle_av_open_on_rc.in_use) { 296 BTIF_TRACE_DEBUG0("BTA_AV_RC_CLOSE_EVT: Stopping AV timer."); 297 btu_stop_timer(&tle_av_open_on_rc); 298 } 299 btif_rc_handler(event, p_data); 300 break; 301 302 default: 303 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 304 dump_av_sm_event_name(event)); 305 return FALSE; 306 307 } 308 return TRUE; 309} 310/***************************************************************************** 311** 312** Function btif_av_state_opening_handler 313** 314** Description Intermediate state managing events during establishment 315** of avdtp channel 316** 317** Returns TRUE if event was processed, FALSE otherwise 318** 319*******************************************************************************/ 320 321static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data) 322{ 323 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 324 dump_av_sm_event_name(event), btif_av_cb.flags); 325 326 switch (event) 327 { 328 case BTIF_SM_ENTER_EVT: 329 /* inform the application that we are entering connecting state */ 330 HAL_CBACK(bt_av_callbacks, connection_state_cb, 331 BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda)); 332 break; 333 334 case BTIF_SM_EXIT_EVT: 335 break; 336 337 case BTA_AV_OPEN_EVT: 338 { 339 tBTA_AV *p_bta_data = (tBTA_AV*)p_data; 340 btav_connection_state_t state; 341 btif_sm_state_t av_state; 342 BTIF_TRACE_DEBUG1("status:%d", p_bta_data->open.status); 343 344 if (p_bta_data->open.status == BTA_AV_SUCCESS) 345 { 346 state = BTAV_CONNECTION_STATE_CONNECTED; 347 av_state = BTIF_AV_STATE_OPENED; 348 } 349 else 350 { 351 BTIF_TRACE_WARNING1("BTA_AV_OPEN_EVT::FAILED status: %d", 352 p_bta_data->open.status ); 353 state = BTAV_CONNECTION_STATE_DISCONNECTED; 354 av_state = BTIF_AV_STATE_IDLE; 355 } 356 357 /* inform the application of the event */ 358 HAL_CBACK(bt_av_callbacks, connection_state_cb, 359 state, &(btif_av_cb.peer_bda)); 360 /* change state to open/idle based on the status */ 361 btif_sm_change_state(btif_av_cb.sm_handle, av_state); 362 /* if queued PLAY command, send it now */ 363 btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, 364 (p_bta_data->open.status == BTA_AV_SUCCESS)); 365 btif_queue_advance(); 366 } break; 367 368 CHECK_RC_EVENT(event, p_data); 369 370 default: 371 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 372 dump_av_sm_event_name(event)); 373 return FALSE; 374 375 } 376 return TRUE; 377} 378 379 380/***************************************************************************** 381** 382** Function btif_av_state_closing_handler 383** 384** Description Intermediate state managing events during closing 385** of avdtp channel 386** 387** Returns TRUE if event was processed, FALSE otherwise 388** 389*******************************************************************************/ 390 391static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data) 392{ 393 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 394 dump_av_sm_event_name(event), btif_av_cb.flags); 395 396 switch (event) 397 { 398 case BTIF_SM_ENTER_EVT: 399 400 /* immediately stop transmission of frames */ 401 btif_a2dp_set_tx_flush(TRUE); 402 /* wait for audioflinger to stop a2dp */ 403 break; 404 405 case BTIF_AV_STOP_STREAM_REQ_EVT: 406 /* immediately flush any pending tx frames while suspend is pending */ 407 btif_a2dp_set_tx_flush(TRUE); 408 409 btif_a2dp_on_stopped(NULL); 410 411 break; 412 413 case BTIF_SM_EXIT_EVT: 414 break; 415 416 case BTA_AV_CLOSE_EVT: 417 418 /* inform the application that we are disconnecting */ 419 HAL_CBACK(bt_av_callbacks, connection_state_cb, 420 BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 421 422 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 423 break; 424 425 /* Handle the RC_CLOSE event for the cleanup */ 426 case BTA_AV_RC_CLOSE_EVT: 427 btif_rc_handler(event, (tBTA_AV*)p_data); 428 break; 429 430 default: 431 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 432 dump_av_sm_event_name(event)); 433 return FALSE; 434 } 435 return TRUE; 436} 437 438 439/***************************************************************************** 440** 441** Function btif_av_state_opened_handler 442** 443** Description Handles AV events while AVDTP is in OPEN state 444** 445** Returns TRUE if event was processed, FALSE otherwise 446** 447*******************************************************************************/ 448 449static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) 450{ 451 tBTA_AV *p_av = (tBTA_AV*)p_data; 452 453 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 454 dump_av_sm_event_name(event), btif_av_cb.flags); 455 456 if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) && 457 (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) ) 458 { 459 BTIF_TRACE_EVENT1("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__); 460 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 461 } 462 463 switch (event) 464 { 465 case BTIF_SM_ENTER_EVT: 466 btif_media_check_iop_exceptions(btif_av_cb.peer_bda.address); 467 break; 468 469 case BTIF_SM_EXIT_EVT: 470 break; 471 472 case BTIF_AV_START_STREAM_REQ_EVT: 473 btif_a2dp_setup_codec(); 474 BTA_AvStart(); 475 break; 476 477 case BTA_AV_START_EVT: 478 { 479 BTIF_TRACE_EVENT3("BTA_AV_START_EVT status %d, suspending %d, init %d", 480 p_av->start.status, p_av->start.suspending, p_av->start.initiator); 481 482 if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE)) 483 return TRUE; 484 485 btif_a2dp_on_started(&p_av->start); 486 487 /* remain in open state if status failed */ 488 if (p_av->start.status != BTA_AV_SUCCESS) 489 return FALSE; 490 491 /* change state to started */ 492 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED); 493 494 } break; 495 496 case BTIF_AV_DISCONNECT_REQ_EVT: 497 BTA_AvClose(btif_av_cb.bta_handle); 498 499 /* inform the application that we are disconnecting */ 500 HAL_CBACK(bt_av_callbacks, connection_state_cb, 501 BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda)); 502 break; 503 504 case BTA_AV_CLOSE_EVT: 505 506 /* inform the application that we are disconnected */ 507 HAL_CBACK(bt_av_callbacks, connection_state_cb, 508 BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 509 510 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 511 break; 512 513 CHECK_RC_EVENT(event, p_data); 514 515 default: 516 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 517 dump_av_sm_event_name(event)); 518 return FALSE; 519 520 } 521 return TRUE; 522} 523 524/***************************************************************************** 525** 526** Function btif_av_state_started_handler 527** 528** Description Handles AV events while A2DP stream is started 529** 530** Returns TRUE if event was processed, FALSE otherwise 531** 532*******************************************************************************/ 533 534static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data) 535{ 536 tBTA_AV *p_av = (tBTA_AV*)p_data; 537 538 BTIF_TRACE_DEBUG3("%s event:%s flags %x", __FUNCTION__, 539 dump_av_sm_event_name(event), btif_av_cb.flags); 540 541 switch (event) 542 { 543 case BTIF_SM_ENTER_EVT: 544 545 /* we are again in started state, clear any remote suspend flags */ 546 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 547 548 HAL_CBACK(bt_av_callbacks, audio_state_cb, 549 BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda)); 550 break; 551 552 case BTIF_SM_EXIT_EVT: 553 break; 554 555 /* fixme -- use suspend = true always to work around issue with BTA AV */ 556 case BTIF_AV_STOP_STREAM_REQ_EVT: 557 case BTIF_AV_SUSPEND_STREAM_REQ_EVT: 558 559 /* set pending flag to ensure btif task is not trying to restart 560 stream while suspend is in progress */ 561 btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 562 563 /* if we were remotely suspended but suspend locally, local suspend 564 always overrides */ 565 btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; 566 567 /* immediately stop transmission of frames while suspend is pending */ 568 btif_a2dp_set_tx_flush(TRUE); 569 570 BTA_AvStop(TRUE); 571 break; 572 573 case BTIF_AV_DISCONNECT_REQ_EVT: 574 575 /* request avdtp to close */ 576 BTA_AvClose(btif_av_cb.bta_handle); 577 578 /* inform the application that we are disconnecting */ 579 HAL_CBACK(bt_av_callbacks, connection_state_cb, 580 BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda)); 581 582 /* wait in closing state until fully closed */ 583 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING); 584 break; 585 586 case BTA_AV_SUSPEND_EVT: 587 588 BTIF_TRACE_EVENT2("BTA_AV_SUSPEND_EVT status %d, init %d", 589 p_av->suspend.status, p_av->suspend.initiator); 590 591 /* a2dp suspended, stop media task until resumed */ 592 btif_a2dp_on_suspended(&p_av->suspend); 593 594 /* if not successful, remain in current state */ 595 if (p_av->suspend.status != BTA_AV_SUCCESS) 596 { 597 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 598 599 /* suspend failed, reset back tx flush state */ 600 btif_a2dp_set_tx_flush(FALSE); 601 return FALSE; 602 } 603 604 if (p_av->suspend.initiator != TRUE) 605 { 606 /* remote suspend, notify HAL and await audioflinger to 607 suspend/stop stream */ 608 609 /* set remote suspend flag to block media task from restarting 610 stream only if we did not already initiate a local suspend */ 611 if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0) 612 btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND; 613 614 HAL_CBACK(bt_av_callbacks, audio_state_cb, 615 BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda)); 616 } 617 else 618 { 619 HAL_CBACK(bt_av_callbacks, audio_state_cb, 620 BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); 621 } 622 623 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); 624 625 /* suspend completed and state changed, clear pending status */ 626 btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; 627 break; 628 629 case BTA_AV_STOP_EVT: 630 631 btif_a2dp_on_stopped(&p_av->suspend); 632 633 HAL_CBACK(bt_av_callbacks, audio_state_cb, 634 BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda)); 635 636 /* if stop was successful, change state to open */ 637 if (p_av->suspend.status == BTA_AV_SUCCESS) 638 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED); 639 640 break; 641 642 case BTA_AV_CLOSE_EVT: 643 644 /* avdtp link is closed */ 645 646 btif_a2dp_on_stopped(NULL); 647 648 /* inform the application that we are disconnected */ 649 HAL_CBACK(bt_av_callbacks, connection_state_cb, 650 BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); 651 652 btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE); 653 break; 654 655 CHECK_RC_EVENT(event, p_data); 656 657 default: 658 BTIF_TRACE_WARNING2("%s : unhandled event:%s", __FUNCTION__, 659 dump_av_sm_event_name(event)); 660 return FALSE; 661 662 } 663 return TRUE; 664} 665 666/***************************************************************************** 667** Local event handlers 668******************************************************************************/ 669 670static void btif_av_handle_event(UINT16 event, char* p_param) 671{ 672 btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param); 673} 674 675static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data) 676{ 677 /* Switch to BTIF context */ 678 btif_transfer_context(btif_av_handle_event, event, 679 (char*)p_data, sizeof(tBTA_AV), NULL); 680} 681 682/******************************************************************************* 683** 684** Function btif_av_init 685** 686** Description Initializes btif AV if not already done 687** 688** Returns bt_status_t 689** 690*******************************************************************************/ 691 692bt_status_t btif_av_init(void) 693{ 694 if (btif_av_cb.sm_handle == NULL) 695 { 696 if (btif_a2dp_start_media_task() != GKI_SUCCESS) 697 return BT_STATUS_FAIL; 698 699 btif_enable_service(BTA_A2DP_SERVICE_ID); 700 701 /* Initialize the AVRC CB */ 702 btif_rc_init(); 703 704 /* Also initialize the AV state machine */ 705 btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE); 706 707 btif_a2dp_on_init(); 708 709 return BT_STATUS_SUCCESS; 710 } 711 712 return BT_STATUS_DONE; 713} 714 715/******************************************************************************* 716** 717** Function init 718** 719** Description Initializes the AV interface 720** 721** Returns bt_status_t 722** 723*******************************************************************************/ 724 725static bt_status_t init(btav_callbacks_t* callbacks ) 726{ 727 int status; 728 729 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 730 731 if (bt_av_callbacks) 732 return BT_STATUS_DONE; 733 734 bt_av_callbacks = callbacks; 735 btif_av_cb.sm_handle = NULL; 736 737 return btif_av_init(); 738} 739 740/******************************************************************************* 741** 742** Function connect 743** 744** Description Establishes the AV signalling channel with the remote headset 745** 746** Returns bt_status_t 747** 748*******************************************************************************/ 749 750static bt_status_t connect_int(bt_bdaddr_t *bd_addr) 751{ 752 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 753 754 btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)bd_addr); 755 756 return BT_STATUS_SUCCESS; 757} 758 759static bt_status_t connect(bt_bdaddr_t *bd_addr) 760{ 761 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 762 CHECK_BTAV_INIT(); 763 764 return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int); 765} 766 767/******************************************************************************* 768** 769** Function disconnect 770** 771** Description Tears down the AV signalling channel with the remote headset 772** 773** Returns bt_status_t 774** 775*******************************************************************************/ 776static bt_status_t disconnect(bt_bdaddr_t *bd_addr) 777{ 778 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 779 780 CHECK_BTAV_INIT(); 781 782 /* Switch to BTIF context */ 783 return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT, 784 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL); 785} 786 787/******************************************************************************* 788** 789** Function cleanup 790** 791** Description Shuts down the AV interface and does the cleanup 792** 793** Returns None 794** 795*******************************************************************************/ 796static void cleanup(void) 797{ 798 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 799 800 if (bt_av_callbacks) 801 { 802 btif_a2dp_stop_media_task(); 803 804 btif_disable_service(BTA_A2DP_SERVICE_ID); 805 bt_av_callbacks = NULL; 806 807 /* Also shut down the AV state machine */ 808 btif_sm_shutdown(btif_av_cb.sm_handle); 809 btif_av_cb.sm_handle = NULL; 810 } 811 return; 812} 813 814static const btav_interface_t bt_av_interface = { 815 sizeof(btav_interface_t), 816 init, 817 connect, 818 disconnect, 819 cleanup, 820}; 821 822/******************************************************************************* 823** 824** Function btif_av_get_sm_handle 825** 826** Description Fetches current av SM handle 827** 828** Returns None 829** 830*******************************************************************************/ 831 832btif_sm_handle_t btif_av_get_sm_handle(void) 833{ 834 return btif_av_cb.sm_handle; 835} 836 837/******************************************************************************* 838** 839** Function btif_av_stream_ready 840** 841** Description Checks whether AV is ready for starting a stream 842** 843** Returns None 844** 845*******************************************************************************/ 846 847BOOLEAN btif_av_stream_ready(void) 848{ 849 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 850 851 BTIF_TRACE_DEBUG3("btif_av_stream_ready : sm hdl %d, state %d, flags %x", 852 btif_av_cb.sm_handle, state, btif_av_cb.flags); 853 854 /* also make sure main adapter is enabled */ 855 if (btif_is_enabled() == 0) 856 { 857 BTIF_TRACE_EVENT0("main adapter not enabled"); 858 return FALSE; 859 } 860 861 /* check if we are remotely suspended */ 862 if (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) 863 return FALSE; 864 865 return (state == BTIF_AV_STATE_OPENED); 866} 867 868/******************************************************************************* 869** 870** Function btif_av_stream_started_ready 871** 872** Description Checks whether AV ready for media start in streaming state 873** 874** Returns None 875** 876*******************************************************************************/ 877 878BOOLEAN btif_av_stream_started_ready(void) 879{ 880 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 881 882 BTIF_TRACE_DEBUG3("btif_av_stream_started : sm hdl %d, state %d, flags %x", 883 btif_av_cb.sm_handle, state, btif_av_cb.flags); 884 885 /* don't allow media task to start if we are suspending or 886 remotely suspended (not yet changed state) */ 887 if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND)) 888 return FALSE; 889 890 return (state == BTIF_AV_STATE_STARTED); 891} 892 893/******************************************************************************* 894** 895** Function btif_dispatch_sm_event 896** 897** Description Send event to AV statemachine 898** 899** Returns None 900** 901*******************************************************************************/ 902 903/* used to pass events to AV statemachine from other tasks */ 904void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len) 905{ 906 /* Switch to BTIF context */ 907 btif_transfer_context(btif_av_handle_event, event, 908 (char*)p_data, len, NULL); 909} 910 911/******************************************************************************* 912** 913** Function btif_av_execute_service 914** 915** Description Initializes/Shuts down the service 916** 917** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise 918** 919*******************************************************************************/ 920bt_status_t btif_av_execute_service(BOOLEAN b_enable) 921{ 922 if (b_enable) 923 { 924 /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not 925 * handle this request in order to allow incoming connections to succeed. 926 * We need to put this back once support for this is added */ 927 928 /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not 929 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall 930 * be initiated by the app/audioflinger layers */ 931 BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD), 932 bte_av_callback); 933 BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0); 934 } 935 else { 936 BTA_AvDeregister(btif_av_cb.bta_handle); 937 BTA_AvDisable(); 938 } 939 return BT_STATUS_SUCCESS; 940} 941 942/******************************************************************************* 943** 944** Function btif_av_get_interface 945** 946** Description Get the AV callback interface 947** 948** Returns btav_interface_t 949** 950*******************************************************************************/ 951const btav_interface_t *btif_av_get_interface(void) 952{ 953 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 954 return &bt_av_interface; 955} 956 957/******************************************************************************* 958** 959** Function btif_av_is_rc_open_without_a2dp 960** 961** Description Checks if GAVDTP Open notification to app is pending (2 second timer) 962** 963** Returns boolean 964** 965*******************************************************************************/ 966BOOLEAN btif_av_is_connected(void) 967{ 968 btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); 969 return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED)); 970} 971