bta_av_act.c revision ad2d45b15aae80ba254277c3d1fa036207d8b926
1/***************************************************************************** 2** 3** Name: bta_av_act.c 4** 5** Description: This file contains action functions for 6** advanced audio/video main state machine. 7** 8** Copyright (c) 2004-2011, Broadcom Corp., All Rights Reserved. 9** Broadcom Bluetooth Core. Proprietary and confidential. 10** 11*****************************************************************************/ 12 13#include "bt_target.h" 14#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) 15 16#include <string.h> 17#include "bta_av_api.h" 18#include "bta_av_int.h" 19#include "avdt_api.h" 20#include "bd.h" 21#include "utl.h" 22#include "l2c_api.h" 23#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) 24#include "bta_ar_api.h" 25#endif 26 27/***************************************************************************** 28** Constants 29*****************************************************************************/ 30/* the timer in milliseconds to wait for open req after setconfig for incoming connections */ 31#ifndef BTA_AV_SIG_TIME_VAL 32#define BTA_AV_SIG_TIME_VAL 8000 33#endif 34 35/* In millisec to wait for signalling from SNK when it is initiated from SNK. */ 36/* If not, we will start signalling from SRC. */ 37#ifndef BTA_AV_ACP_SIG_TIME_VAL 38#define BTA_AV_ACP_SIG_TIME_VAL 2000 39#endif 40 41static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle); 42 43/******************************************************************************* 44** 45** Function bta_av_get_rcb_by_shdl 46** 47** Description find the RCB associated with the given SCB handle. 48** 49** Returns tBTA_AV_RCB 50** 51*******************************************************************************/ 52tBTA_AV_RCB * bta_av_get_rcb_by_shdl(UINT8 shdl) 53{ 54 tBTA_AV_RCB *p_rcb = NULL; 55 int i; 56 57 for (i=0; i<BTA_AV_NUM_RCB; i++) 58 { 59 if (bta_av_cb.rcb[i].shdl == shdl && bta_av_cb.rcb[i].handle != BTA_AV_RC_HANDLE_NONE) 60 { 61 p_rcb = &bta_av_cb.rcb[i]; 62 break; 63 } 64 } 65 return p_rcb; 66} 67#define BTA_AV_STS_NO_RSP 0xFF /* a number not used by tAVRC_STS */ 68 69/******************************************************************************* 70** 71** Function bta_av_del_rc 72** 73** Description delete the given AVRC handle. 74** 75** Returns void 76** 77*******************************************************************************/ 78void bta_av_del_rc(tBTA_AV_RCB *p_rcb) 79{ 80 tBTA_AV_SCB *p_scb; 81 UINT8 rc_handle; /* connected AVRCP handle */ 82 83 if(p_rcb->handle != BTA_AV_RC_HANDLE_NONE) 84 { 85 if(p_rcb->shdl) 86 { 87 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; 88 if(p_scb) 89 { 90 APPL_TRACE_DEBUG3("bta_av_del_rc shdl:%d, srch:%d rc_handle:%d", p_rcb->shdl, 91 p_scb->rc_handle, p_rcb->handle); 92 if(p_scb->rc_handle == p_rcb->handle) 93 p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE; 94 /* just in case the RC timer is active 95 if(bta_av_cb.features & BTA_AV_FEAT_RCCT && p_scb->chnl == BTA_AV_CHNL_AUDIO) */ 96 bta_sys_stop_timer(&p_scb->timer); 97 } 98 } 99 100 APPL_TRACE_EVENT4("bta_av_del_rc handle: %d status=0x%x, rc_acp_handle:%d, idx:%d", 101 p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, bta_av_cb.rc_acp_idx); 102 rc_handle = p_rcb->handle; 103 if(!(p_rcb->status & BTA_AV_RC_CONN_MASK) || 104 ((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) ) 105 { 106 p_rcb->status = 0; 107 p_rcb->handle = BTA_AV_RC_HANDLE_NONE; 108 p_rcb->shdl = 0; 109 p_rcb->lidx = 0; 110 } 111 /* else ACP && connected. do not clear the handle yet */ 112 AVRC_Close(rc_handle); 113 if (rc_handle == bta_av_cb.rc_acp_handle) 114 bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE; 115 APPL_TRACE_EVENT4("end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d", 116 p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, p_rcb->lidx); 117 } 118} 119 120 121/******************************************************************************* 122** 123** Function bta_av_close_all_rc 124** 125** Description close the all AVRC handle. 126** 127** Returns void 128** 129*******************************************************************************/ 130static void bta_av_close_all_rc(tBTA_AV_CB *p_cb) 131{ 132 int i; 133 134 for(i=0; i<BTA_AV_NUM_RCB; i++) 135 { 136 if ((p_cb->disabling == TRUE) || (bta_av_cb.rcb[i].shdl != 0)) 137 bta_av_del_rc(&bta_av_cb.rcb[i]); 138 } 139} 140 141/******************************************************************************* 142** 143** Function bta_av_del_sdp_rec 144** 145** Description delete the given SDP record handle. 146** 147** Returns void 148** 149*******************************************************************************/ 150static void bta_av_del_sdp_rec(UINT32 *p_sdp_handle) 151{ 152 if(*p_sdp_handle != 0) 153 { 154 SDP_DeleteRecord(*p_sdp_handle); 155 *p_sdp_handle = 0; 156 } 157} 158 159/******************************************************************************* 160** 161** Function bta_av_avrc_sdp_cback 162** 163** Description AVRCP service discovery callback. 164** 165** Returns void 166** 167*******************************************************************************/ 168static void bta_av_avrc_sdp_cback(UINT16 status) 169{ 170 BT_HDR *p_msg; 171 172 if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) 173 { 174 p_msg->event = BTA_AV_SDP_AVRC_DISC_EVT; 175 bta_sys_sendmsg(p_msg); 176 } 177} 178 179/******************************************************************************* 180** 181** Function bta_av_rc_ctrl_cback 182** 183** Description AVRCP control callback. 184** 185** Returns void 186** 187*******************************************************************************/ 188static void bta_av_rc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result, BD_ADDR peer_addr) 189{ 190 tBTA_AV_RC_CONN_CHG *p_msg; 191 UINT16 msg_event = 0; 192 193#if (defined(BTA_AV_MIN_DEBUG_TRACES) && BTA_AV_MIN_DEBUG_TRACES == TRUE) 194 APPL_TRACE_EVENT2("rc_ctrl handle: %d event=0x%x", handle, event); 195#else 196 APPL_TRACE_EVENT2("bta_av_rc_ctrl_cback handle: %d event=0x%x", handle, event); 197#endif 198 if (event == AVRC_OPEN_IND_EVT) 199 { 200 /* save handle of opened connection 201 bta_av_cb.rc_handle = handle;*/ 202 203 msg_event = BTA_AV_AVRC_OPEN_EVT; 204 } 205 else if (event == AVRC_CLOSE_IND_EVT) 206 { 207 msg_event = BTA_AV_AVRC_CLOSE_EVT; 208 } 209 210 if (msg_event) 211 { 212 if ((p_msg = (tBTA_AV_RC_CONN_CHG *) GKI_getbuf(sizeof(tBTA_AV_RC_CONN_CHG))) != NULL) 213 { 214 p_msg->hdr.event = msg_event; 215 p_msg->handle = handle; 216 if(peer_addr) 217 bdcpy(p_msg->peer_addr, peer_addr); 218 bta_sys_sendmsg(p_msg); 219 } 220 } 221} 222 223/******************************************************************************* 224** 225** Function bta_av_rc_msg_cback 226** 227** Description AVRCP message callback. 228** 229** Returns void 230** 231*******************************************************************************/ 232static void bta_av_rc_msg_cback(UINT8 handle, UINT8 label, UINT8 opcode, tAVRC_MSG *p_msg) 233{ 234 tBTA_AV_RC_MSG *p_buf; 235 UINT8 *p_data = NULL; 236 UINT8 **p_p_data = NULL; 237 UINT16 data_len = 0; 238 239#if (defined(BTA_AV_MIN_DEBUG_TRACES) && BTA_AV_MIN_DEBUG_TRACES == TRUE) 240 APPL_TRACE_ERROR2("rc_msg handle: %d opcode=0x%x", handle, opcode); 241#else 242 APPL_TRACE_EVENT2("bta_av_rc_msg_cback handle: %d opcode=0x%x", handle, opcode); 243#endif 244 /* determine size of buffer we need */ 245 if (opcode == AVRC_OP_VENDOR && p_msg->vendor.p_vendor_data != NULL) 246 { 247 p_data = p_msg->vendor.p_vendor_data; 248 p_p_data = &p_msg->vendor.p_vendor_data; 249 data_len = (UINT16) p_msg->vendor.vendor_len; 250 } 251 else if (opcode == AVRC_OP_PASS_THRU && p_msg->pass.p_pass_data != NULL) 252 { 253 p_data = p_msg->pass.p_pass_data; 254 p_p_data = &p_msg->pass.p_pass_data; 255 data_len = (UINT16) p_msg->pass.pass_len; 256 } 257 258 if ((p_buf = (tBTA_AV_RC_MSG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_RC_MSG) + data_len))) != NULL) 259 { 260 p_buf->hdr.event = BTA_AV_AVRC_MSG_EVT; 261 p_buf->handle = handle; 262 p_buf->label = label; 263 p_buf->opcode = opcode; 264 memcpy(&p_buf->msg, p_msg, sizeof(tAVRC_MSG)); 265 if (p_data != NULL) 266 { 267 memcpy((UINT8 *)(p_buf + 1), p_data, data_len); 268 *p_p_data = (UINT8 *)(p_buf + 1); 269 } 270 bta_sys_sendmsg(p_buf); 271 } 272} 273 274/******************************************************************************* 275** 276** Function bta_av_rc_create 277** 278** Description alloc RCB and call AVRC_Open 279** 280** Returns the created rc handle 281** 282*******************************************************************************/ 283UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx) 284{ 285 tAVRC_CONN_CB ccb; 286 BD_ADDR_PTR bda = (BD_ADDR_PTR)bd_addr_any; 287 UINT8 status = BTA_AV_RC_ROLE_ACP; 288 tBTA_AV_SCB *p_scb = p_cb->p_scb[shdl - 1]; 289 int i; 290 UINT8 rc_handle; 291 tBTA_AV_RCB *p_rcb; 292 293 if(role == AVCT_INT) 294 { 295 bda = p_scb->peer_addr; 296 status = BTA_AV_RC_ROLE_INT; 297 } 298 else 299 { 300 if ((p_rcb = bta_av_get_rcb_by_shdl(shdl)) != NULL ) 301 { 302 APPL_TRACE_ERROR1("bta_av_rc_create ACP handle exist for shdl:%d", shdl); 303 return p_rcb->handle; 304 } 305 } 306 307 ccb.p_ctrl_cback = bta_av_rc_ctrl_cback; 308 ccb.p_msg_cback = bta_av_rc_msg_cback; 309 ccb.company_id = p_bta_av_cfg->company_id; 310 ccb.conn = role; 311 /* note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL */ 312 ccb.control = p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | AVRC_CT_PASSIVE); 313 314 315 if (AVRC_Open(&rc_handle, &ccb, bda) != AVRC_SUCCESS) 316 return BTA_AV_RC_HANDLE_NONE; 317 318 i = rc_handle; 319 p_rcb = &p_cb->rcb[i]; 320 321 if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) 322 { 323 APPL_TRACE_ERROR1("bta_av_rc_create found duplicated handle:%d", rc_handle); 324 } 325 326 p_rcb->handle = rc_handle; 327 p_rcb->status = status; 328 p_rcb->shdl = shdl; 329 p_rcb->lidx = lidx; 330 p_rcb->peer_features = 0; 331 if(lidx == (BTA_AV_NUM_LINKS + 1)) 332 { 333 /* this LIDX is reserved for the AVRCP ACP connection */ 334 p_cb->rc_acp_handle = p_rcb->handle; 335 p_cb->rc_acp_idx = (i + 1); 336 APPL_TRACE_DEBUG2("rc_acp_handle:%d idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx); 337 } 338 APPL_TRACE_DEBUG6("create %d, role: %d, shdl:%d, rc_handle:%d, lidx:%d, status:0x%x", 339 i, role, shdl, p_rcb->handle, lidx, p_rcb->status); 340 341 return rc_handle; 342} 343 344/******************************************************************************* 345** 346** Function bta_av_valid_group_navi_msg 347** 348** Description Check if it is Group Navigation Msg for Metadata 349** 350** Returns BTA_AV_RSP_ACCEPT or BTA_AV_RSP_NOT_IMPL. 351** 352*******************************************************************************/ 353static tBTA_AV_CODE bta_av_group_navi_supported(UINT8 len, UINT8 *p_data) 354{ 355 tBTA_AV_CODE ret=BTA_AV_RSP_NOT_IMPL; 356 UINT8 *p_ptr = p_data; 357 UINT16 u16; 358 UINT32 u32; 359 360 if (p_bta_av_cfg->avrc_group && len == BTA_GROUP_NAVI_MSG_OP_DATA_LEN) 361 { 362 BTA_AV_BE_STREAM_TO_CO_ID(u32, p_ptr); 363 BE_STREAM_TO_UINT16(u16, p_ptr); 364 365 if (u32 == AVRC_CO_METADATA) 366 { 367 if (u16 <= AVRC_PDU_PREV_GROUP) 368 ret = BTA_AV_RSP_ACCEPT; 369 else 370 ret = BTA_AV_RSP_REJ; 371 } 372 } 373 374 return ret; 375} 376 377/******************************************************************************* 378** 379** Function bta_av_op_supported 380** 381** Description Check if remote control operation is supported. 382** 383** Returns BTA_AV_RSP_ACCEPT of supported, BTA_AV_RSP_NOT_IMPL if not. 384** 385*******************************************************************************/ 386static tBTA_AV_CODE bta_av_op_supported(tBTA_AV_RC rc_id) 387{ 388 tBTA_AV_CODE ret_code = BTA_AV_RSP_NOT_IMPL; 389 390 if (p_bta_av_rc_id) 391 { 392 if (p_bta_av_rc_id[rc_id >> 4] & (1 << (rc_id & 0x0F))) 393 { 394 ret_code = BTA_AV_RSP_ACCEPT; 395 } 396 else if ((p_bta_av_cfg->rc_pass_rsp == BTA_AV_RSP_INTERIM) && p_bta_av_rc_id_ac) 397 { 398 if (p_bta_av_rc_id_ac[rc_id >> 4] & (1 << (rc_id & 0x0F))) 399 { 400 ret_code = BTA_AV_RSP_INTERIM; 401 } 402 } 403 } 404 return ret_code; 405} 406 407/******************************************************************************* 408** 409** Function bta_av_find_lcb 410** 411** Description Given BD_addr, find the associated LCB. 412** 413** Returns NULL, if not found. 414** 415*******************************************************************************/ 416tBTA_AV_LCB * bta_av_find_lcb(BD_ADDR addr, UINT8 op) 417{ 418 tBTA_AV_CB *p_cb = &bta_av_cb; 419 int xx; 420 UINT8 mask; 421 tBTA_AV_LCB *p_lcb = NULL; 422 423 for(xx=0; xx<BTA_AV_NUM_LINKS; xx++) 424 { 425 mask = 1 << xx; /* the used mask for this lcb */ 426 if((mask & p_cb->conn_lcb) && 0 ==( bdcmp(p_cb->lcb[xx].addr, addr))) 427 { 428 p_lcb = &p_cb->lcb[xx]; 429 if(op == BTA_AV_LCB_FREE) 430 { 431 p_cb->conn_lcb &= ~mask; /* clear the connect mask */ 432 APPL_TRACE_DEBUG1("conn_lcb: 0x%x", p_cb->conn_lcb); 433 } 434 break; 435 } 436 } 437 return p_lcb; 438} 439 440/******************************************************************************* 441** 442** Function bta_av_rc_opened 443** 444** Description Set AVRCP state to opened. 445** 446** Returns void 447** 448*******************************************************************************/ 449void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 450{ 451 tBTA_AV_RC_OPEN rc_open; 452 tBTA_AV_SCB *p_scb; 453 int i; 454 UINT8 shdl = 0; 455 tBTA_AV_LCB *p_lcb; 456 tBTA_AV_RCB *p_rcb; 457 UINT8 tmp; 458 UINT8 disc = 0; 459 460 /* find the SCB & stop the timer */ 461 for(i=0; i<BTA_AV_NUM_STRS; i++) 462 { 463 p_scb = p_cb->p_scb[i]; 464 if(p_scb && bdcmp(p_scb->peer_addr, p_data->rc_conn_chg.peer_addr) == 0) 465 { 466 p_scb->rc_handle = p_data->rc_conn_chg.handle; 467 APPL_TRACE_DEBUG2("bta_av_rc_opened shdl:%d, srch %d", i + 1, p_scb->rc_handle); 468 shdl = i+1; 469 APPL_TRACE_ERROR1("use_rc:%d", p_scb->use_rc); 470 bta_sys_stop_timer(&p_scb->timer); 471 disc = p_scb->hndl; 472 break; 473 } 474 } 475 476 i = p_data->rc_conn_chg.handle; 477 if (p_cb->rcb[i].handle == BTA_AV_RC_HANDLE_NONE) 478 { 479 APPL_TRACE_ERROR1("not a valid handle:%d any more", i); 480 return; 481 } 482 483 484 if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0) 485 { 486 /* rc is opened on the RC only ACP channel, but is for a specific 487 * SCB -> need to switch RCBs */ 488 p_rcb = bta_av_get_rcb_by_shdl(shdl); 489 if (p_rcb) 490 { 491 p_rcb->shdl = p_cb->rcb[i].shdl; 492 tmp = p_rcb->lidx; 493 p_rcb->lidx = p_cb->rcb[i].lidx; 494 p_cb->rcb[i].lidx = tmp; 495 p_cb->rc_acp_handle = p_rcb->handle; 496 p_cb->rc_acp_idx = (p_rcb - p_cb->rcb) + 1; 497 APPL_TRACE_DEBUG2("switching RCB rc_acp_handle:%d idx:%d", 498 p_cb->rc_acp_handle, p_cb->rc_acp_idx); 499 } 500 } 501 502 p_cb->rcb[i].shdl = shdl; 503 rc_open.rc_handle = i; 504 APPL_TRACE_ERROR4("bta_av_rc_opened rcb[%d] shdl:%d lidx:%d/%d", 505 i, shdl, p_cb->rcb[i].lidx, p_cb->lcb[BTA_AV_NUM_LINKS].lidx); 506 p_cb->rcb[i].status |= BTA_AV_RC_CONN_MASK; 507 508 if(!shdl && 0 == p_cb->lcb[BTA_AV_NUM_LINKS].lidx) 509 { 510 /* no associated SCB -> connected to an RC only device 511 * update the index to the extra LCB */ 512 p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS]; 513 bdcpy(p_lcb->addr, p_data->rc_conn_chg.peer_addr); 514 APPL_TRACE_DEBUG6("rc_only bd_addr:%02x-%02x-%02x-%02x-%02x-%02x", 515 p_lcb->addr[0], p_lcb->addr[1], 516 p_lcb->addr[2], p_lcb->addr[3], 517 p_lcb->addr[4], p_lcb->addr[5]); 518 p_lcb->lidx = BTA_AV_NUM_LINKS + 1; 519 p_cb->rcb[i].lidx = p_lcb->lidx; 520 p_lcb->conn_msk = 1; 521 APPL_TRACE_ERROR3("rcb[%d].lidx=%d, lcb.conn_msk=x%x", 522 i, p_cb->rcb[i].lidx, p_lcb->conn_msk); 523 disc = p_data->rc_conn_chg.handle|BTA_AV_CHNL_MSK; 524 } 525 526 bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr); 527 rc_open.peer_features = p_cb->rcb[i].peer_features; 528 rc_open.status = BTA_AV_SUCCESS; 529 APPL_TRACE_DEBUG2("local features:x%x peer_features:x%x", p_cb->features, 530 rc_open.peer_features); 531 if(rc_open.peer_features == 0) 532 { 533 /* we have not done SDP on peer RC capabilities. 534 * peer must have initiated the RC connection */ 535 rc_open.peer_features = BTA_AV_FEAT_RCCT; 536 bta_av_rc_disc(disc); 537 } 538 (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); 539 540} 541 542 543/******************************************************************************* 544** 545** Function bta_av_rc_remote_cmd 546** 547** Description Send an AVRCP remote control command. 548** 549** Returns void 550** 551*******************************************************************************/ 552void bta_av_rc_remote_cmd(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 553{ 554 tBTA_AV_RCB *p_rcb; 555 if (p_cb->features & BTA_AV_FEAT_RCCT) 556 { 557 if(p_data->hdr.layer_specific < BTA_AV_NUM_RCB) 558 { 559 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific]; 560 if(p_rcb->status & BTA_AV_RC_CONN_MASK) 561 { 562 AVRC_PassCmd(p_rcb->handle, p_data->api_remote_cmd.label, 563 &p_data->api_remote_cmd.msg); 564 } 565 } 566 } 567} 568 569/******************************************************************************* 570** 571** Function bta_av_rc_vendor_cmd 572** 573** Description Send an AVRCP vendor specific command. 574** 575** Returns void 576** 577*******************************************************************************/ 578void bta_av_rc_vendor_cmd(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 579{ 580 tBTA_AV_RCB *p_rcb; 581 if ( (p_cb->features & (BTA_AV_FEAT_RCCT | BTA_AV_FEAT_VENDOR)) == 582 (BTA_AV_FEAT_RCCT | BTA_AV_FEAT_VENDOR)) 583 { 584 if(p_data->hdr.layer_specific < BTA_AV_NUM_RCB) 585 { 586 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific]; 587 AVRC_VendorCmd(p_rcb->handle, p_data->api_vendor.label, &p_data->api_vendor.msg); 588 } 589 } 590} 591 592/******************************************************************************* 593** 594** Function bta_av_rc_vendor_rsp 595** 596** Description Send an AVRCP vendor specific response. 597** 598** Returns void 599** 600*******************************************************************************/ 601void bta_av_rc_vendor_rsp(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 602{ 603 tBTA_AV_RCB *p_rcb; 604 if ( (p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_VENDOR)) == 605 (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_VENDOR)) 606 { 607 if(p_data->hdr.layer_specific < BTA_AV_NUM_RCB) 608 { 609 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific]; 610 AVRC_VendorRsp(p_rcb->handle, p_data->api_vendor.label, &p_data->api_vendor.msg); 611 } 612 } 613} 614 615/******************************************************************************* 616** 617** Function bta_av_rc_meta_rsp 618** 619** Description Send an AVRCP metadata/advanced control command/response. 620** 621** Returns void 622** 623*******************************************************************************/ 624void bta_av_rc_meta_rsp(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 625{ 626 tBTA_AV_RCB *p_rcb; 627 BOOLEAN free = TRUE; 628 629 if ((p_cb->features & BTA_AV_FEAT_METADATA) && (p_data->hdr.layer_specific < BTA_AV_NUM_RCB)) 630 { 631 if ((p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCTG)) || 632 (!p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCCT)) ) 633 { 634 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific]; 635 AVRC_MsgReq(p_rcb->handle, p_data->api_meta_rsp.label, p_data->api_meta_rsp.rsp_code, 636 p_data->api_meta_rsp.p_pkt); 637 free = FALSE; 638 } 639 } 640 641 if (free) 642 GKI_freebuf (p_data->api_meta_rsp.p_pkt); 643} 644 645/******************************************************************************* 646** 647** Function bta_av_rc_free_rsp 648** 649** Description free an AVRCP metadata command buffer. 650** 651** Returns void 652** 653*******************************************************************************/ 654void bta_av_rc_free_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 655{ 656 GKI_freebuf (p_data->api_meta_rsp.p_pkt); 657} 658 659/******************************************************************************* 660** 661** Function bta_av_rc_meta_req 662** 663** Description Send an AVRCP metadata command. 664** 665** Returns void 666** 667*******************************************************************************/ 668void bta_av_rc_free_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 669{ 670} 671 672 673 674/******************************************************************************* 675** 676** Function bta_av_chk_notif_evt_id 677** 678** Description make sure the requested player id is valid. 679** 680** Returns BTA_AV_STS_NO_RSP, if no error 681** 682*******************************************************************************/ 683static tAVRC_STS bta_av_chk_notif_evt_id(tAVRC_MSG_VENDOR *p_vendor) 684{ 685 tAVRC_STS status = BTA_AV_STS_NO_RSP; 686 UINT8 xx; 687 UINT16 u16; 688 UINT8 *p = p_vendor->p_vendor_data + 2; 689 690 BE_STREAM_TO_UINT16 (u16, p); 691 /* double check the fixed length */ 692 if ((u16 != 5) || (p_vendor->vendor_len != 9)) 693 { 694 status = AVRC_STS_INTERNAL_ERR; 695 } 696 else 697 { 698 /* make sure the player_id is valid */ 699 for (xx=0; xx<p_bta_av_cfg->num_evt_ids; xx++) 700 { 701 if (*p == p_bta_av_cfg->p_meta_evt_ids[xx]) 702 { 703 break; 704 } 705 } 706 if (xx == p_bta_av_cfg->num_evt_ids) 707 { 708 status = AVRC_STS_BAD_PARAM; 709 } 710 } 711 712 return status; 713} 714 715/******************************************************************************* 716** 717** Function bta_av_proc_meta_cmd 718** 719** Description Process an AVRCP metadata command from the peer. 720** 721** Returns TRUE to respond immediately 722** 723*******************************************************************************/ 724tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE *p_rc_rsp, tBTA_AV_RC_MSG *p_msg, UINT8 *p_ctype) 725{ 726 tBTA_AV_EVT evt = BTA_AV_META_MSG_EVT; 727 UINT8 u8, pdu, *p; 728 UINT16 u16; 729 tAVRC_MSG_VENDOR *p_vendor = &p_msg->msg.vendor; 730 731 pdu = *(p_vendor->p_vendor_data); 732 p_rc_rsp->pdu = pdu; 733 *p_ctype = AVRC_RSP_REJ; 734 /* Metadata messages only use PANEL sub-unit type */ 735 if (p_vendor->hdr.subunit_type != AVRC_SUB_PANEL) 736 { 737 APPL_TRACE_DEBUG0("SUBUNIT must be PANEL"); 738 /* reject it */ 739 evt=0; 740 p_vendor->hdr.ctype = BTA_AV_RSP_NOT_IMPL; 741 AVRC_VendorRsp(p_msg->handle, p_msg->label, &p_msg->msg.vendor); 742 } 743 else 744 { 745 switch (pdu) 746 { 747 case AVRC_PDU_GET_CAPABILITIES: 748 /* process GetCapabilities command without reporting the event to app */ 749 evt = 0; 750 u8 = *(p_vendor->p_vendor_data + 4); 751 p = p_vendor->p_vendor_data + 2; 752 p_rc_rsp->get_caps.capability_id = u8; 753 BE_STREAM_TO_UINT16 (u16, p); 754 if ((u16 != 1) || (p_vendor->vendor_len != 5)) 755 { 756 p_rc_rsp->get_caps.status = AVRC_STS_INTERNAL_ERR; 757 } 758 else 759 { 760 p_rc_rsp->get_caps.status = AVRC_STS_NO_ERROR; 761 if (u8 == AVRC_CAP_COMPANY_ID) 762 { 763 *p_ctype = AVRC_RSP_IMPL_STBL; 764 p_rc_rsp->get_caps.count = p_bta_av_cfg->num_co_ids; 765 memcpy(p_rc_rsp->get_caps.param.company_id, p_bta_av_cfg->p_meta_co_ids, 766 (p_bta_av_cfg->num_co_ids << 2)); 767 } 768 else if (u8 == AVRC_CAP_EVENTS_SUPPORTED) 769 { 770 *p_ctype = AVRC_RSP_IMPL_STBL; 771 p_rc_rsp->get_caps.count = p_bta_av_cfg->num_evt_ids; 772 memcpy(p_rc_rsp->get_caps.param.event_id, p_bta_av_cfg->p_meta_evt_ids, 773 p_bta_av_cfg->num_evt_ids); 774 } 775 else 776 { 777 APPL_TRACE_DEBUG1("Invalid capability ID: 0x%x", u8); 778 /* reject - unknown capability ID */ 779 p_rc_rsp->get_caps.status = AVRC_STS_BAD_PARAM; 780 } 781 } 782 break; 783 784 785 case AVRC_PDU_REGISTER_NOTIFICATION: 786 /* make sure the event_id is implemented */ 787 p_rc_rsp->rsp.status = bta_av_chk_notif_evt_id (p_vendor); 788 if (p_rc_rsp->rsp.status != BTA_AV_STS_NO_RSP) 789 evt = 0; 790 break; 791 792 } 793 } 794 795 return evt; 796} 797 798 799/******************************************************************************* 800** 801** Function bta_av_rc_msg 802** 803** Description Process an AVRCP message from the peer. 804** 805** Returns void 806** 807*******************************************************************************/ 808void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 809{ 810 tBTA_AV_EVT evt = 0; 811 tBTA_AV av; 812 BT_HDR *p_pkt = NULL; 813 tAVRC_MSG_VENDOR *p_vendor = &p_data->rc_msg.msg.vendor; 814 815 if (p_data->rc_msg.opcode == AVRC_OP_PASS_THRU) 816 { 817 /* if this is a pass thru command */ 818 if (p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_CTRL) 819 { 820 /* check if operation is supported */ 821 if (p_data->rc_msg.msg.pass.op_id == AVRC_ID_VENDOR) 822 { 823 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_NOT_IMPL; 824 } 825 else 826 { 827 p_data->rc_msg.msg.hdr.ctype = bta_av_op_supported(p_data->rc_msg.msg.pass.op_id); 828 } 829 830 /* send response */ 831 if (p_data->rc_msg.msg.hdr.ctype != BTA_AV_RSP_INTERIM) 832 AVRC_PassRsp(p_data->rc_msg.handle, p_data->rc_msg.label, &p_data->rc_msg.msg.pass); 833 834 /* set up for callback if supported */ 835 if (p_data->rc_msg.msg.hdr.ctype == BTA_AV_RSP_ACCEPT || p_data->rc_msg.msg.hdr.ctype == BTA_AV_RSP_INTERIM) 836 { 837 evt = BTA_AV_REMOTE_CMD_EVT; 838 av.remote_cmd.rc_id = p_data->rc_msg.msg.pass.op_id; 839 av.remote_cmd.key_state = p_data->rc_msg.msg.pass.state; 840 av.remote_cmd.p_data = p_data->rc_msg.msg.pass.p_pass_data; 841 av.remote_cmd.len = p_data->rc_msg.msg.pass.pass_len; 842 memcpy(&av.remote_cmd.hdr, &p_data->rc_msg.msg.hdr, sizeof (tAVRC_HDR)); 843 av.remote_cmd.label = p_data->rc_msg.label; 844 } 845 } 846 /* else if this is a pass thru response */ 847 else if (p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_ACCEPT) 848 { 849 /* set up for callback */ 850 evt = BTA_AV_REMOTE_RSP_EVT; 851 av.remote_rsp.rc_id = p_data->rc_msg.msg.pass.op_id; 852 av.remote_rsp.key_state = p_data->rc_msg.msg.pass.state; 853 av.remote_rsp.rsp_code = p_data->rc_msg.msg.hdr.ctype; 854 av.remote_rsp.label = p_data->rc_msg.label; 855 } 856 /* must be a bad ctype -> reject*/ 857 else 858 { 859 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_REJ; 860 AVRC_PassRsp(p_data->rc_msg.handle, p_data->rc_msg.label, &p_data->rc_msg.msg.pass); 861 } 862 } 863 /* else if this is a vendor specific command or response */ 864 else if (p_data->rc_msg.opcode == AVRC_OP_VENDOR) 865 { 866 /* set up for callback */ 867 av.vendor_cmd.code = p_data->rc_msg.msg.hdr.ctype; 868 av.vendor_cmd.company_id = p_vendor->company_id; 869 av.vendor_cmd.label = p_data->rc_msg.label; 870 av.vendor_cmd.p_data = p_vendor->p_vendor_data; 871 av.vendor_cmd.len = p_vendor->vendor_len; 872 873 /* if configured to support vendor specific and it's a command */ 874 if ((p_cb->features & BTA_AV_FEAT_VENDOR) && 875 p_data->rc_msg.msg.hdr.ctype <= AVRC_CMD_GEN_INQ) 876 { 877 evt = BTA_AV_VENDOR_CMD_EVT; 878 } 879 /* else if configured to support vendor specific and it's a response */ 880 else if ((p_cb->features & BTA_AV_FEAT_VENDOR) && 881 p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_ACCEPT) 882 { 883 evt = BTA_AV_VENDOR_RSP_EVT; 884 885 } 886 /* else if not configured to support vendor specific and it's a command */ 887 else if (!(p_cb->features & BTA_AV_FEAT_VENDOR) && 888 p_data->rc_msg.msg.hdr.ctype <= AVRC_CMD_GEN_INQ) 889 { 890 if(p_data->rc_msg.msg.vendor.p_vendor_data[0] == AVRC_PDU_INVALID) 891 { 892 /* reject it */ 893 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_REJ; 894 p_data->rc_msg.msg.vendor.p_vendor_data[4] = AVRC_STS_BAD_CMD; 895 } 896 else 897 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_NOT_IMPL; 898 AVRC_VendorRsp(p_data->rc_msg.handle, p_data->rc_msg.label, &p_data->rc_msg.msg.vendor); 899 } 900 } 901 902 /* call callback */ 903 if (evt != 0) 904 { 905 av.remote_cmd.rc_handle = p_data->rc_msg.handle; 906 (*p_cb->p_cback)(evt, &av); 907 } 908} 909 910/******************************************************************************* 911** 912** Function bta_av_rc_close 913** 914** Description close the specified AVRC handle. 915** 916** Returns void 917** 918*******************************************************************************/ 919void bta_av_rc_close (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 920{ 921 UINT16 handle = p_data->hdr.layer_specific; 922 tBTA_AV_SCB *p_scb; 923 tBTA_AV_RCB *p_rcb; 924 925 if(handle < BTA_AV_NUM_RCB) 926 { 927 p_rcb = &p_cb->rcb[handle]; 928 929 APPL_TRACE_DEBUG2("bta_av_rc_close handle: %d, status=0x%x", p_rcb->handle, p_rcb->status); 930 if(p_rcb->handle != BTA_AV_RC_HANDLE_NONE) 931 { 932 if(p_rcb->shdl) 933 { 934 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; 935 if(p_scb) 936 { 937 /* just in case the RC timer is active 938 if(bta_av_cb.features & BTA_AV_FEAT_RCCT && 939 p_scb->chnl == BTA_AV_CHNL_AUDIO) */ 940 bta_sys_stop_timer(&p_scb->timer); 941 } 942 } 943 944 AVRC_Close(p_rcb->handle); 945 } 946 } 947} 948 949/******************************************************************************* 950** 951** Function bta_av_get_shdl 952** 953** Returns The index to p_scb[] 954** 955*******************************************************************************/ 956static UINT8 bta_av_get_shdl(tBTA_AV_SCB *p_scb) 957{ 958 int i; 959 UINT8 shdl = 0; 960 /* find the SCB & stop the timer */ 961 for(i=0; i<BTA_AV_NUM_STRS; i++) 962 { 963 if(p_scb == bta_av_cb.p_scb[i]) 964 { 965 shdl = i+1; 966 break; 967 } 968 } 969 return shdl; 970} 971 972/******************************************************************************* 973** 974** Function bta_av_stream_chg 975** 976** Description audio streaming status changed. 977** 978** Returns void 979** 980*******************************************************************************/ 981void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started) 982{ 983 UINT8 started_msk; 984 int i; 985 UINT8 *p_streams; 986 BOOLEAN no_streams = FALSE; 987 tBTA_AV_SCB *p_scbi; 988 989 started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi); 990 APPL_TRACE_DEBUG3 ("bta_av_stream_chg started:%d started_msk:x%x chnl:x%x", started, 991 started_msk, p_scb->chnl); 992 if (BTA_AV_CHNL_AUDIO == p_scb->chnl) 993 p_streams = &bta_av_cb.audio_streams; 994 else 995 p_streams = &bta_av_cb.video_streams; 996 997 if (started) 998 { 999 /* Let L2CAP know this channel is processed with high priority */ 1000 L2CA_SetAclPriority(p_scb->peer_addr, L2CAP_PRIORITY_HIGH); 1001 (*p_streams) |= started_msk; 1002 } 1003 else 1004 { 1005 (*p_streams) &= ~started_msk; 1006 } 1007 1008 if (!started) 1009 { 1010 i=0; 1011 if (BTA_AV_CHNL_AUDIO == p_scb->chnl) 1012 { 1013 if (bta_av_cb.video_streams == 0) 1014 no_streams = TRUE; 1015 } 1016 else 1017 { 1018 no_streams = TRUE; 1019 if ( bta_av_cb.audio_streams ) 1020 { 1021 for (; i<BTA_AV_NUM_STRS; i++) 1022 { 1023 p_scbi = bta_av_cb.p_scb[i]; 1024 /* scb is used and started */ 1025 if ( p_scbi && (bta_av_cb.audio_streams & BTA_AV_HNDL_TO_MSK(i)) 1026 && bdcmp(p_scbi->peer_addr, p_scb->peer_addr) == 0) 1027 { 1028 no_streams = FALSE; 1029 break; 1030 } 1031 } 1032 1033 } 1034 } 1035 1036 APPL_TRACE_DEBUG4 ("no_streams:%d i:%d, audio_streams:x%x, video_streams:x%x", no_streams, i, 1037 bta_av_cb.audio_streams, bta_av_cb.video_streams); 1038 if (no_streams) 1039 { 1040 /* Let L2CAP know this channel is processed with low priority */ 1041 L2CA_SetAclPriority(p_scb->peer_addr, L2CAP_PRIORITY_NORMAL); 1042 } 1043 } 1044} 1045 1046 1047/******************************************************************************* 1048** 1049** Function bta_av_conn_chg 1050** 1051** Description connetion status changed. 1052** Open an AVRCP acceptor channel, if new conn. 1053** 1054** Returns void 1055** 1056*******************************************************************************/ 1057void bta_av_conn_chg(tBTA_AV_DATA *p_data) 1058{ 1059 tBTA_AV_CB *p_cb = &bta_av_cb; 1060 tBTA_AV_SCB *p_scb; 1061 tBTA_AV_SCB *p_scbi; 1062 UINT8 mask; 1063 UINT8 conn_msk; 1064 UINT8 old_msk; 1065 int i; 1066 int index = (p_data->hdr.layer_specific & BTA_AV_HNDL_MSK) - 1; 1067 tBTA_AV_LCB *p_lcb; 1068 tBTA_AV_LCB *p_lcb_rc; 1069 tBTA_AV_RCB *p_rcb, *p_rcb2; 1070 BOOLEAN chk_restore = FALSE; 1071 1072 p_scb = p_cb->p_scb[index]; 1073 1074 mask = BTA_AV_HNDL_TO_MSK(index); 1075 p_lcb = bta_av_find_lcb(p_data->conn_chg.peer_addr, BTA_AV_LCB_FIND); 1076 conn_msk = 1 << (index + 1); 1077 if(p_data->conn_chg.is_up) 1078 { 1079 /* set the conned mask for this channel */ 1080 if(p_scb) 1081 { 1082 if(p_lcb) 1083 { 1084 p_lcb->conn_msk |= conn_msk; 1085 for (i=0; i<BTA_AV_NUM_RCB; i++) 1086 { 1087 if (bta_av_cb.rcb[i].lidx == p_lcb->lidx) 1088 { 1089 bta_av_cb.rcb[i].shdl = index + 1; 1090 APPL_TRACE_DEBUG5("conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i, 1091 bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, 1092 bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx); 1093 break; 1094 } 1095 } 1096 } 1097 if (p_scb->chnl == BTA_AV_CHNL_AUDIO) 1098 { 1099 old_msk = p_cb->conn_audio; 1100 p_cb->conn_audio |= mask; 1101 } 1102 else 1103 { 1104 old_msk = p_cb->conn_video; 1105 p_cb->conn_video |= mask; 1106 } 1107 1108 if ((old_msk & mask) == 0) 1109 { 1110 /* increase the audio open count, if not set yet */ 1111 bta_av_cb.audio_open_cnt++; 1112 } 1113 1114 1115 APPL_TRACE_DEBUG2("rc_acp_handle:%d rc_acp_idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx); 1116 /* check if the AVRCP ACP channel is already connected */ 1117 if(p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE && p_cb->rc_acp_idx) 1118 { 1119 p_lcb_rc = &p_cb->lcb[BTA_AV_NUM_LINKS]; 1120 APPL_TRACE_DEBUG1("rc_acp is connected && conn_chg on same addr p_lcb_rc->conn_msk:x%x", 1121 p_lcb_rc->conn_msk); 1122 /* check if the RC is connected to the scb addr */ 1123 APPL_TRACE_DEBUG6 ("p_lcb_rc->addr: %02x:%02x:%02x:%02x:%02x:%02x", 1124 p_lcb_rc->addr[0], p_lcb_rc->addr[1], p_lcb_rc->addr[2], p_lcb_rc->addr[3], 1125 p_lcb_rc->addr[4], p_lcb_rc->addr[5]); 1126 APPL_TRACE_DEBUG6 ("conn_chg.peer_addr: %02x:%02x:%02x:%02x:%02x:%02x", 1127 p_data->conn_chg.peer_addr[0], p_data->conn_chg.peer_addr[1], 1128 p_data->conn_chg.peer_addr[2], 1129 p_data->conn_chg.peer_addr[3], p_data->conn_chg.peer_addr[4], 1130 p_data->conn_chg.peer_addr[5]); 1131 if (p_lcb_rc->conn_msk && bdcmp(p_lcb_rc->addr, p_data->conn_chg.peer_addr) == 0) 1132 { 1133 /* AVRCP is already connected. 1134 * need to update the association betwen SCB and RCB */ 1135 p_lcb_rc->conn_msk = 0; /* indicate RC ONLY is not connected */ 1136 p_lcb_rc->lidx = 0; 1137 p_scb->rc_handle = p_cb->rc_acp_handle; 1138 p_rcb = &p_cb->rcb[p_cb->rc_acp_idx - 1]; 1139 p_rcb->shdl = bta_av_get_shdl(p_scb); 1140 APPL_TRACE_DEBUG3("update rc_acp shdl:%d/%d srch:%d", index + 1, p_rcb->shdl, 1141 p_scb->rc_handle ); 1142 1143 p_rcb2 = bta_av_get_rcb_by_shdl(p_rcb->shdl); 1144 if (p_rcb2) 1145 { 1146 /* found the RCB that was created to associated with this SCB */ 1147 p_cb->rc_acp_handle = p_rcb2->handle; 1148 p_cb->rc_acp_idx = (p_rcb2 - p_cb->rcb) + 1; 1149 APPL_TRACE_DEBUG2("new rc_acp_handle:%d, idx:%d", p_cb->rc_acp_handle, 1150 p_cb->rc_acp_idx); 1151 p_rcb2->lidx = (BTA_AV_NUM_LINKS + 1); 1152 APPL_TRACE_DEBUG3("rc2 handle:%d lidx:%d/%d",p_rcb2->handle, p_rcb2->lidx, 1153 p_cb->lcb[p_rcb2->lidx-1].lidx); 1154 } 1155 p_rcb->lidx = p_lcb->lidx; 1156 APPL_TRACE_DEBUG3("rc handle:%d lidx:%d/%d",p_rcb->handle, p_rcb->lidx, 1157 p_cb->lcb[p_rcb->lidx-1].lidx); 1158 } 1159 } 1160 } 1161 } 1162 else 1163 { 1164 if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) 1165 { 1166 /* this channel is still marked as open. decrease the count */ 1167 bta_av_cb.audio_open_cnt--; 1168 } 1169 1170 /* clear the conned mask for this channel */ 1171 p_cb->conn_audio &= ~mask; 1172 p_cb->conn_video &= ~mask; 1173 if(p_scb) 1174 { 1175 /* the stream is closed. 1176 * clear the peer address, so it would not mess up the AVRCP for the next round of operation */ 1177 bdcpy(p_scb->peer_addr, bd_addr_null); 1178 if(p_scb->chnl == BTA_AV_CHNL_AUDIO) 1179 { 1180 if(p_lcb) 1181 { 1182 p_lcb->conn_msk &= ~conn_msk; 1183 } 1184 /* audio channel is down. make sure the INT channel is down */ 1185 /* just in case the RC timer is active 1186 if(p_cb->features & BTA_AV_FEAT_RCCT) */ 1187 { 1188 bta_sys_stop_timer(&p_scb->timer); 1189 } 1190 /* one audio channel goes down. check if we need to restore high priority */ 1191 chk_restore = TRUE; 1192 } 1193 } 1194 1195 APPL_TRACE_DEBUG1("bta_av_conn_chg shdl:%d", index + 1); 1196 for (i=0; i<BTA_AV_NUM_RCB; i++) 1197 { 1198 APPL_TRACE_DEBUG5("conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i, 1199 bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, 1200 bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx); 1201 if(bta_av_cb.rcb[i].shdl == index + 1) 1202 { 1203 bta_av_del_rc(&bta_av_cb.rcb[i]); 1204 break; 1205 } 1206 } 1207 1208 if(p_cb->conn_audio == 0 && p_cb->conn_video == 0) 1209 { 1210 /* if both channels are not connected, 1211 * close all RC channels */ 1212 bta_av_close_all_rc(p_cb); 1213 } 1214 1215 /* if the AVRCP is no longer listening, create the listening channel */ 1216 if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) 1217 bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1); 1218 } 1219 1220 APPL_TRACE_DEBUG6("bta_av_conn_chg audio:%x video:%x up:%d conn_msk:0x%x chk_restore:%d audio_open_cnt:%d", 1221 p_cb->conn_audio, p_cb->conn_video, p_data->conn_chg.is_up, conn_msk, chk_restore, p_cb->audio_open_cnt); 1222 1223 if (chk_restore) 1224 { 1225 if (p_cb->audio_open_cnt == 1) 1226 { 1227 /* one audio channel goes down and there's one audio channel remains open. 1228 * restore the switch role in default link policy */ 1229 bta_sys_set_default_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH); 1230 /* allow role switch, if this is the last connection */ 1231 bta_av_restore_switch(); 1232 } 1233 if (p_cb->audio_open_cnt) 1234 { 1235 /* adjust flush timeout settings to longer period */ 1236 for (i=0; i<BTA_AV_NUM_STRS; i++) 1237 { 1238 p_scbi = bta_av_cb.p_scb[i]; 1239 if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) 1240 { 1241 /* may need to update the flush timeout of this already started stream */ 1242 if (p_scbi->co_started != bta_av_cb.audio_open_cnt) 1243 { 1244 p_scbi->co_started = bta_av_cb.audio_open_cnt; 1245 L2CA_SetFlushTimeout(p_scbi->peer_addr, p_bta_av_cfg->p_audio_flush_to[p_scbi->co_started - 1] ); 1246 } 1247 } 1248 } 1249 } 1250 } 1251} 1252 1253/******************************************************************************* 1254** 1255** Function bta_av_disable 1256** 1257** Description disable AV. 1258** 1259** Returns void 1260** 1261*******************************************************************************/ 1262void bta_av_disable(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data) 1263{ 1264 BT_HDR hdr; 1265 UINT16 xx; 1266 1267 p_cb->disabling = TRUE; 1268 1269 bta_av_close_all_rc(p_cb); 1270 1271 utl_freebuf((void **) &p_cb->p_disc_db); 1272 1273 /* disable audio/video - de-register all channels, 1274 * expect BTA_AV_DEREG_COMP_EVT when deregister is complete */ 1275 for(xx=0; xx<BTA_AV_NUM_STRS; xx++) 1276 { 1277 hdr.layer_specific = xx + 1; 1278 bta_av_api_deregister((tBTA_AV_DATA *)&hdr); 1279 } 1280} 1281 1282/******************************************************************************* 1283** 1284** Function bta_av_api_disconnect 1285** 1286** Description . 1287** 1288** Returns void 1289** 1290*******************************************************************************/ 1291void bta_av_api_disconnect(tBTA_AV_DATA *p_data) 1292{ 1293 AVDT_DisconnectReq(p_data->api_discnt.bd_addr, bta_av_conn_cback); 1294 bta_sys_stop_timer(&bta_av_cb.sig_tmr); 1295} 1296 1297/******************************************************************************* 1298** 1299** Function bta_av_sig_chg 1300** 1301** Description process AVDT signal channel up/down. 1302** 1303** Returns void 1304** 1305*******************************************************************************/ 1306void bta_av_sig_chg(tBTA_AV_DATA *p_data) 1307{ 1308 UINT16 event = p_data->str_msg.hdr.layer_specific; 1309 tBTA_AV_CB *p_cb = &bta_av_cb; 1310 int xx; 1311 UINT8 mask; 1312 tBTA_AV_LCB *p_lcb = NULL; 1313 1314 APPL_TRACE_DEBUG1("bta_av_sig_chg event: %d", event); 1315 if(event == AVDT_CONNECT_IND_EVT) 1316 { 1317 p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FIND); 1318 if(!p_lcb) 1319 { 1320 /* if the address does not have an LCB yet, alloc one */ 1321 for(xx=0; xx<BTA_AV_NUM_LINKS; xx++) 1322 { 1323 mask = 1 << xx; 1324 APPL_TRACE_DEBUG1("conn_lcb: 0x%x", p_cb->conn_lcb); 1325 if(!(mask & p_cb->conn_lcb)) 1326 { 1327 if (!p_cb->p_scb[xx]) 1328 { 1329 /* We do not have scb for this avdt connection. */ 1330 /* Silently close the connection. */ 1331 APPL_TRACE_ERROR0("av scb not available for avdt connection"); 1332 AVDT_DisconnectReq (p_data->str_msg.bd_addr, NULL); 1333 return; 1334 } 1335 1336 p_lcb = &p_cb->lcb[xx]; 1337 p_lcb->lidx = xx + 1; 1338 bdcpy(p_lcb->addr, p_data->str_msg.bd_addr); 1339 p_lcb->conn_msk = 0; /* clear the connect mask */ 1340 /* start listening when the signal channel is open */ 1341 if (p_cb->features & BTA_AV_FEAT_RCTG) 1342 { 1343 bta_av_rc_create(p_cb, AVCT_ACP, 0, p_lcb->lidx); 1344 } 1345 /* this entry is not used yet. */ 1346 p_cb->conn_lcb |= mask; /* mark it as used */ 1347 APPL_TRACE_DEBUG1("start sig timer %d", p_data->hdr.offset); 1348 if (p_data->hdr.offset == AVDT_ACP) 1349 { 1350 APPL_TRACE_DEBUG1("Incoming L2CAP acquired, set state as incoming", NULL); 1351 bdcpy(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr); 1352 p_cb->p_scb[xx]->use_rc = TRUE; /* allowing RC for incoming connection */ 1353 bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_ACP_CONNECT_EVT, p_data); 1354 1355 /* The Pending Event should be sent as soon as the L2CAP signalling channel 1356 * is set up, which is NOW. Earlier this was done only after 1357 * BTA_AV_SIG_TIME_VAL milliseconds. 1358 * The following function shall send the event and start the recurring timer 1359 */ 1360 bta_av_sig_timer(NULL); 1361 1362 /* Possible collision : need to avoid outgoing processing while the timer is running */ 1363 p_cb->p_scb[xx]->coll_mask = BTA_AV_COLL_INC_TMR; 1364 1365 p_cb->acp_sig_tmr.param = (UINT32)xx; 1366 p_cb->acp_sig_tmr.p_cback = (TIMER_CBACK*)&bta_av_acp_sig_timer_cback; 1367 bta_sys_start_timer(&p_cb->acp_sig_tmr, 0, BTA_AV_ACP_SIG_TIME_VAL); 1368 } 1369 break; 1370 } 1371 } 1372 } 1373 } 1374#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) 1375 else if (event == BTA_AR_AVDT_CONN_EVT) 1376 { 1377 bta_sys_stop_timer(&bta_av_cb.sig_tmr); 1378 } 1379#endif 1380 else 1381 { 1382 /* disconnected. */ 1383 p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FREE); 1384 if(p_lcb && p_lcb->conn_msk) 1385 { 1386 APPL_TRACE_DEBUG1("conn_msk: 0x%x", p_lcb->conn_msk); 1387 /* clean up ssm */ 1388 for(xx=0; xx < BTA_AV_NUM_STRS; xx++) 1389 { 1390 mask = 1 << (xx + 1); 1391 if ((mask & p_lcb->conn_msk) && (p_cb->p_scb[xx]) && 1392 (bdcmp(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr) == 0)) 1393 { 1394 bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_AVDT_DISCONNECT_EVT, NULL); 1395 } 1396 } 1397 } 1398 } 1399 APPL_TRACE_DEBUG1("conn_lcb: 0x%x", p_cb->conn_lcb); 1400} 1401 1402/******************************************************************************* 1403** 1404** Function bta_av_sig_timer 1405** 1406** Description process the signal channel timer. This timer is started 1407** when the AVDTP signal channel is connected. If no profile 1408** is connected, the timer goes off every BTA_AV_SIG_TIME_VAL 1409** 1410** Returns void 1411** 1412*******************************************************************************/ 1413void bta_av_sig_timer(tBTA_AV_DATA *p_data) 1414{ 1415 tBTA_AV_CB *p_cb = &bta_av_cb; 1416 int xx; 1417 UINT8 mask; 1418 tBTA_AV_LCB *p_lcb = NULL; 1419 tBTA_AV_PEND pend; 1420 1421 APPL_TRACE_DEBUG0("bta_av_sig_timer"); 1422 for(xx=0; xx<BTA_AV_NUM_LINKS; xx++) 1423 { 1424 mask = 1 << xx; 1425 if(mask & p_cb->conn_lcb) 1426 { 1427 /* this entry is used. check if it is connected */ 1428 p_lcb = &p_cb->lcb[xx]; 1429 if(!p_lcb->conn_msk) 1430 { 1431 bta_sys_start_timer(&p_cb->sig_tmr, BTA_AV_SIG_TIMER_EVT, BTA_AV_SIG_TIME_VAL); 1432 bdcpy(pend.bd_addr, p_lcb->addr); 1433 (*p_cb->p_cback)(BTA_AV_PENDING_EVT, (tBTA_AV *) &pend); 1434 } 1435 } 1436 } 1437} 1438 1439/******************************************************************************* 1440** 1441** Function bta_av_acp_sig_timer_cback 1442** 1443** Description Process the timeout when SRC is accepting connection 1444** and SNK did not start signalling. 1445** 1446** Returns void 1447** 1448*******************************************************************************/ 1449static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle) 1450{ 1451 UINT8 inx = (UINT8)p_tle->param; 1452 tBTA_AV_CB *p_cb = &bta_av_cb; 1453 tBTA_AV_SCB *p_scb = p_cb->p_scb[inx]; 1454 tBTA_AV_API_OPEN *p_buf; 1455 1456 if (p_scb) 1457 { 1458 APPL_TRACE_DEBUG1("bta_av_acp_sig_timer_cback, coll_mask = 0x%02X", p_scb->coll_mask); 1459 1460 if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) 1461 { 1462 p_scb->coll_mask &= ~BTA_AV_COLL_INC_TMR; 1463 1464 if (bta_av_is_scb_opening(p_scb)) 1465 { 1466 if (p_scb->p_disc_db) 1467 { 1468 /* We are still doing SDP. Run the timer again. */ 1469 p_scb->coll_mask |= BTA_AV_COLL_INC_TMR; 1470 1471 p_cb->acp_sig_tmr.param = (UINT32)inx; 1472 p_cb->acp_sig_tmr.p_cback = (TIMER_CBACK *)&bta_av_acp_sig_timer_cback; 1473 bta_sys_start_timer(&p_cb->acp_sig_tmr, 0, BTA_AV_ACP_SIG_TIME_VAL); 1474 } 1475 else 1476 { 1477 /* SNK did not start signalling, resume signalling process. */ 1478 bta_av_discover_req (p_scb, NULL); 1479 } 1480 } 1481 else if (bta_av_is_scb_incoming(p_scb)) 1482 { 1483 /* Stay in incoming state if SNK does not start signalling */ 1484 1485 /* API open was called right after SNK opened L2C connection. */ 1486 if (p_scb->coll_mask & BTA_AV_COLL_API_CALLED) 1487 { 1488 p_scb->coll_mask &= ~BTA_AV_COLL_API_CALLED; 1489 1490 /* BTA_AV_API_OPEN_EVT */ 1491 if ((p_buf = (tBTA_AV_API_OPEN *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL) 1492 { 1493 memcpy(p_buf, &(p_scb->open_api), sizeof(tBTA_AV_API_OPEN)); 1494 bta_sys_sendmsg(p_buf); 1495 } 1496 } 1497 } 1498 } 1499 } 1500} 1501 1502/******************************************************************************* 1503** 1504** Function bta_av_check_peer_features 1505** 1506** Description checks 1507** 1508** Returns void 1509** 1510*******************************************************************************/ 1511tBTA_AV_FEAT bta_av_check_peer_features (UINT16 service_uuid) 1512{ 1513 tBTA_AV_FEAT peer_features = 0; 1514 tBTA_AV_CB *p_cb = &bta_av_cb; 1515 tSDP_DISC_REC *p_rec = NULL; 1516 tSDP_DISC_ATTR *p_attr; 1517 UINT16 peer_rc_version=0; 1518 UINT16 categories = 0; 1519 1520 APPL_TRACE_DEBUG1("bta_av_check_peer_features service_uuid:x%x", service_uuid); 1521 /* loop through all records we found */ 1522 while (TRUE) 1523 { 1524 /* get next record; if none found, we're done */ 1525 if ((p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec)) == NULL) 1526 { 1527 break; 1528 } 1529 1530 if (( SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) != NULL) 1531 { 1532 /* find peer features */ 1533 if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL)) 1534 { 1535 peer_features |= BTA_AV_FEAT_RCCT; 1536 } 1537 if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) 1538 { 1539 peer_features |= BTA_AV_FEAT_RCTG; 1540 } 1541 } 1542 1543 if (( SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) 1544 { 1545 /* get profile version (if failure, version parameter is not updated) */ 1546 SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version); 1547 APPL_TRACE_DEBUG1("peer_rc_version 0x%x", peer_rc_version); 1548 1549 if (peer_rc_version >= AVRC_REV_1_3) 1550 peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA); 1551 1552 if (peer_rc_version >= AVRC_REV_1_4) 1553 { 1554 peer_features |= (BTA_AV_FEAT_ADV_CTRL); 1555 /* get supported categories */ 1556 if ((p_attr = SDP_FindAttributeInRec(p_rec, 1557 ATTR_ID_SUPPORTED_FEATURES)) != NULL) 1558 { 1559 categories = p_attr->attr_value.v.u16; 1560 if (categories & AVRC_SUPF_CT_BROWSE) 1561 peer_features |= (BTA_AV_FEAT_BROWSE); 1562 } 1563 } 1564 } 1565 } 1566 APPL_TRACE_DEBUG1("peer_features:x%x", peer_features); 1567 return peer_features; 1568} 1569 1570/******************************************************************************* 1571** 1572** Function bta_av_rc_disc_done 1573** 1574** Description Handle AVRCP service discovery results. If matching 1575** service found, open AVRCP connection. 1576** 1577** Returns void 1578** 1579*******************************************************************************/ 1580void bta_av_rc_disc_done(tBTA_AV_DATA *p_data) 1581{ 1582 tBTA_AV_CB *p_cb = &bta_av_cb; 1583 tBTA_AV_SCB *p_scb = NULL; 1584 tBTA_AV_LCB *p_lcb; 1585 tBTA_AV_RC_OPEN rc_open; 1586 tBTA_AV_RC_FEAT rc_feat; 1587 UINT8 rc_handle; 1588 tBTA_AV_FEAT peer_features; /* peer features mask */ 1589 1590 APPL_TRACE_DEBUG1("bta_av_rc_disc_done disc:x%x", p_cb->disc); 1591 if (!p_cb->disc) 1592 { 1593 return; 1594 } 1595 1596 if ((p_cb->disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) 1597 { 1598 /* this is the rc handle/index to tBTA_AV_RCB */ 1599 rc_handle = p_cb->disc & (~BTA_AV_CHNL_MSK); 1600 } 1601 else 1602 { 1603 p_scb = p_cb->p_scb[(p_cb->disc & BTA_AV_HNDL_MSK) - 1]; 1604 if (p_scb) 1605 rc_handle = p_scb->rc_handle; 1606 else 1607 { 1608 p_cb->disc = 0; 1609 return; 1610 } 1611 } 1612 1613 APPL_TRACE_DEBUG1("rc_handle %d", rc_handle); 1614 peer_features = bta_av_check_peer_features (UUID_SERVCLASS_AV_REMOTE_CONTROL); 1615 if ((p_cb->features & BTA_AV_FEAT_ADV_CTRL) && ((peer_features&BTA_AV_FEAT_ADV_CTRL) == 0)) 1616 { 1617 /* if we support advance control and peer does not, check their support on TG role 1618 * some implementation uses 1.3 on CT ans 1.4 on TG */ 1619 peer_features |= bta_av_check_peer_features (UUID_SERVCLASS_AV_REM_CTRL_TARGET); 1620 } 1621 1622 p_cb->disc = 0; 1623 utl_freebuf((void **) &p_cb->p_disc_db); 1624 1625 APPL_TRACE_DEBUG2("peer_features 0x%x, features 0x%x", peer_features, p_cb->features); 1626 1627 /* if we have no rc connection */ 1628 if (rc_handle == BTA_AV_RC_HANDLE_NONE) 1629 { 1630 if (p_scb) 1631 { 1632 /* if peer remote control service matches ours and USE_RC is TRUE */ 1633 if ((((p_cb->features & BTA_AV_FEAT_RCCT) && (peer_features & BTA_AV_FEAT_RCTG)) || 1634 ((p_cb->features & BTA_AV_FEAT_RCTG) && (peer_features & BTA_AV_FEAT_RCCT))) ) 1635 { 1636 p_lcb = bta_av_find_lcb(p_scb->peer_addr, BTA_AV_LCB_FIND); 1637 if(p_lcb) 1638 { 1639 rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (UINT8)(p_scb->hdi + 1), p_lcb->lidx); 1640 p_cb->rcb[rc_handle].peer_features = peer_features; 1641 } 1642#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE) 1643 else 1644 { 1645 APPL_TRACE_ERROR0("can not find LCB!!"); 1646 } 1647#endif 1648 } 1649 else if(p_scb->use_rc) 1650 { 1651 /* can not find AVRC on peer device. report failure */ 1652 p_scb->use_rc = FALSE; 1653 bdcpy(rc_open.peer_addr, p_scb->peer_addr); 1654 rc_open.peer_features = 0; 1655 rc_open.status = BTA_AV_FAIL_SDP; 1656 (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open); 1657 } 1658 } 1659 } 1660 else 1661 { 1662 p_cb->rcb[rc_handle].peer_features = peer_features; 1663 rc_feat.rc_handle = rc_handle; 1664 rc_feat.peer_features = peer_features; 1665 (*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, (tBTA_AV *) &rc_feat); 1666 } 1667} 1668 1669/******************************************************************************* 1670** 1671** Function bta_av_rc_closed 1672** 1673** Description Set AVRCP state to closed. 1674** 1675** Returns void 1676** 1677*******************************************************************************/ 1678void bta_av_rc_closed(tBTA_AV_DATA *p_data) 1679{ 1680 tBTA_AV_CB *p_cb = &bta_av_cb; 1681 tBTA_AV_RC_CLOSE rc_close; 1682 tBTA_AV_RC_CONN_CHG *p_msg = (tBTA_AV_RC_CONN_CHG *)p_data; 1683 tBTA_AV_RCB *p_rcb; 1684 tBTA_AV_SCB *p_scb; 1685 int i; 1686 BOOLEAN conn = FALSE; 1687 tBTA_AV_LCB *p_lcb; 1688 1689 rc_close.rc_handle = BTA_AV_RC_HANDLE_NONE; 1690 APPL_TRACE_DEBUG1("bta_av_rc_closed rc_handle:%d", p_msg->handle); 1691 for(i=0; i<BTA_AV_NUM_RCB; i++) 1692 { 1693 p_rcb = &p_cb->rcb[i]; 1694 APPL_TRACE_DEBUG3("bta_av_rc_closed rcb[%d] rc_handle:%d, status=0x%x", i, p_rcb->handle, p_rcb->status); 1695 if(p_rcb->handle == p_msg->handle) 1696 { 1697 rc_close.rc_handle = i; 1698 p_rcb->status &= ~BTA_AV_RC_CONN_MASK; 1699 p_rcb->peer_features = 0; 1700 APPL_TRACE_DEBUG2(" shdl:%d, lidx:%d", p_rcb->shdl, p_rcb->lidx); 1701 if(p_rcb->shdl) 1702 { 1703 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; 1704 if(p_scb) 1705 { 1706 bdcpy(rc_close.peer_addr, p_scb->peer_addr); 1707 if(p_scb->rc_handle == p_rcb->handle) 1708 p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE; 1709 APPL_TRACE_DEBUG2("shdl:%d, srch:%d", p_rcb->shdl, p_scb->rc_handle); 1710 } 1711 p_rcb->shdl = 0; 1712 } 1713 else if(p_rcb->lidx == (BTA_AV_NUM_LINKS + 1) ) 1714 { 1715 /* if the RCB uses the extra LCB, use the addr for event and clean it */ 1716 p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS]; 1717 bdcpy(rc_close.peer_addr, p_msg->peer_addr); 1718 APPL_TRACE_DEBUG6("rc_only closed bd_addr:%02x-%02x-%02x-%02x-%02x-%02x", 1719 p_msg->peer_addr[0], p_msg->peer_addr[1], 1720 p_msg->peer_addr[2], p_msg->peer_addr[3], 1721 p_msg->peer_addr[4], p_msg->peer_addr[5]); 1722 p_lcb->conn_msk = 0; 1723 p_lcb->lidx = 0; 1724 } 1725 p_rcb->lidx = 0; 1726 1727 if((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) 1728 { 1729 /* AVCT CCB is deallocated */ 1730 p_rcb->handle = BTA_AV_RC_HANDLE_NONE; 1731 p_rcb->status = 0; 1732 } 1733 else 1734 { 1735 /* AVCT CCB is still there. dealloc */ 1736 bta_av_del_rc(p_rcb); 1737 1738 /* if the AVRCP is no longer listening, create the listening channel */ 1739 if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) 1740 bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1); 1741 } 1742 } 1743 else if((p_rcb->handle != BTA_AV_RC_HANDLE_NONE) && (p_rcb->status & BTA_AV_RC_CONN_MASK)) 1744 { 1745 /* at least one channel is still connected */ 1746 conn = TRUE; 1747 } 1748 } 1749 1750 if(!conn) 1751 { 1752 /* no AVRC channels are connected, go back to INIT state */ 1753 bta_av_sm_execute(p_cb, BTA_AV_AVRC_NONE_EVT, NULL); 1754 } 1755 1756 if (rc_close.rc_handle == BTA_AV_RC_HANDLE_NONE) 1757 { 1758 rc_close.rc_handle = p_msg->handle; 1759 bdcpy(rc_close.peer_addr, p_msg->peer_addr); 1760 } 1761 (*p_cb->p_cback)(BTA_AV_RC_CLOSE_EVT, (tBTA_AV *) &rc_close); 1762} 1763 1764/******************************************************************************* 1765** 1766** Function bta_av_rc_disc 1767** 1768** Description start AVRC SDP discovery. 1769** 1770** Returns void 1771** 1772*******************************************************************************/ 1773void bta_av_rc_disc(UINT8 disc) 1774{ 1775 tBTA_AV_CB *p_cb = &bta_av_cb; 1776 tAVRC_SDP_DB_PARAMS db_params; 1777 UINT16 attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST, 1778 ATTR_ID_BT_PROFILE_DESC_LIST, 1779 ATTR_ID_SUPPORTED_FEATURES}; 1780 UINT8 hdi; 1781 tBTA_AV_SCB *p_scb; 1782 UINT8 *p_addr = NULL; 1783 UINT8 rc_handle; 1784 1785 APPL_TRACE_DEBUG2("bta_av_rc_disc 0x%x, %d", disc, bta_av_cb.disc); 1786 if ((bta_av_cb.disc != 0) || (disc == 0)) 1787 return; 1788 1789 if ((disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) 1790 { 1791 /* this is the rc handle/index to tBTA_AV_RCB */ 1792 rc_handle = disc & (~BTA_AV_CHNL_MSK); 1793 if (p_cb->rcb[rc_handle].lidx) 1794 { 1795 p_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx-1].addr; 1796 } 1797 } 1798 else 1799 { 1800 hdi = (disc & BTA_AV_HNDL_MSK) - 1; 1801 p_scb = p_cb->p_scb[hdi]; 1802 1803 if (p_scb) 1804 { 1805 APPL_TRACE_DEBUG1("rc_handle %d", p_scb->rc_handle); 1806 p_addr = p_scb->peer_addr; 1807 } 1808 } 1809 1810 if (p_addr) 1811 { 1812 /* allocate discovery database */ 1813 if (p_cb->p_disc_db == NULL) 1814 { 1815 p_cb->p_disc_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(BTA_AV_DISC_BUF_SIZE); 1816 } 1817 1818 if (p_cb->p_disc_db) 1819 { 1820 /* set up parameters */ 1821 db_params.db_len = BTA_AV_DISC_BUF_SIZE; 1822 db_params.num_attr = 3; 1823 db_params.p_db = p_cb->p_disc_db; 1824 db_params.p_attrs = attr_list; 1825 1826 /* searching for UUID_SERVCLASS_AV_REMOTE_CONTROL gets both TG and CT */ 1827 if (AVRC_FindService(UUID_SERVCLASS_AV_REMOTE_CONTROL, p_addr, &db_params, 1828 bta_av_avrc_sdp_cback) == AVRC_SUCCESS) 1829 { 1830 p_cb->disc = disc; 1831 APPL_TRACE_DEBUG1("disc %d", p_cb->disc); 1832 } 1833 } 1834 } 1835} 1836 1837/******************************************************************************* 1838** 1839** Function bta_av_dereg_comp 1840** 1841** Description deregister complete. free the stream control block. 1842** 1843** Returns void 1844** 1845*******************************************************************************/ 1846void bta_av_dereg_comp(tBTA_AV_DATA *p_data) 1847{ 1848 tBTA_AV_CB *p_cb = &bta_av_cb; 1849 tBTA_AV_SCB *p_scb; 1850 tBTA_UTL_COD cod; 1851 UINT8 mask; 1852 BT_HDR *p_buf; 1853 1854 /* find the stream control block */ 1855 p_scb = bta_av_hndl_to_scb(p_data->hdr.layer_specific); 1856 1857 if(p_scb) 1858 { 1859 APPL_TRACE_DEBUG2("deregistered %d(h%d)", p_scb->chnl, p_scb->hndl); 1860 mask = BTA_AV_HNDL_TO_MSK(p_scb->hdi); 1861 if(p_scb->chnl == BTA_AV_CHNL_AUDIO) 1862 { 1863 p_cb->reg_audio &= ~mask; 1864 if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) 1865 { 1866 /* this channel is still marked as open. decrease the count */ 1867 bta_av_cb.audio_open_cnt--; 1868 } 1869 p_cb->conn_audio &= ~mask; 1870 1871 if (p_scb->q_tag == BTA_AV_Q_TAG_STREAM) 1872 { 1873 /* make sure no buffers are in q_info.a2d */ 1874 while((p_buf = (BT_HDR*)GKI_dequeue (&p_scb->q_info.a2d)) != NULL) 1875 GKI_freebuf(p_buf); 1876 } 1877 1878 /* remove the A2DP SDP record, if no more audio stream is left */ 1879 if(!p_cb->reg_audio) 1880 { 1881#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) 1882 bta_ar_dereg_avrc (UUID_SERVCLASS_AV_REMOTE_CONTROL, BTA_ID_AV); 1883#endif 1884 bta_av_del_sdp_rec(&p_cb->sdp_a2d_handle); 1885 bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE); 1886 } 1887 } 1888 else 1889 { 1890 p_cb->reg_video &= ~mask; 1891 /* make sure that this channel is not connected */ 1892 p_cb->conn_video &= ~mask; 1893 /* remove the VDP SDP record, (only one video stream at most) */ 1894 bta_av_del_sdp_rec(&p_cb->sdp_vdp_handle); 1895 bta_sys_remove_uuid(UUID_SERVCLASS_VIDEO_SOURCE); 1896 } 1897 1898 /* make sure that the timer is not active */ 1899 bta_sys_stop_timer(&p_scb->timer); 1900 utl_freebuf((void **)&p_cb->p_scb[p_scb->hdi]); 1901 } 1902 1903 APPL_TRACE_DEBUG3("audio 0x%x, video: 0x%x, disable:%d", 1904 p_cb->reg_audio, p_cb->reg_video, p_cb->disabling); 1905 /* if no stream control block is active */ 1906 if((p_cb->reg_audio + p_cb->reg_video) == 0) 1907 { 1908#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) 1909 /* deregister from AVDT */ 1910 bta_ar_dereg_avdt(BTA_ID_AV); 1911 1912 /* deregister from AVCT */ 1913 bta_ar_dereg_avrc (UUID_SERVCLASS_AV_REM_CTRL_TARGET, BTA_ID_AV); 1914 bta_ar_dereg_avct(BTA_ID_AV); 1915#endif 1916 1917 if(p_cb->disabling) 1918 { 1919 p_cb->disabling = FALSE; 1920 bta_av_cb.features = 0; 1921 } 1922 1923 /* Clear the Capturing service class bit */ 1924 cod.service = BTM_COD_SERVICE_CAPTURING; 1925 utl_set_device_class(&cod, BTA_UTL_CLR_COD_SERVICE_CLASS); 1926 } 1927} 1928#endif /* BTA_AV_INCLUDED */ 1929