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_rc.c 23 * 24 * Description: Bluetooth AVRC implementation 25 * 26 *****************************************************************************/ 27#include <hardware/bluetooth.h> 28#include <fcntl.h> 29#include <string.h> 30#include "bta_api.h" 31#include "bta_av_api.h" 32#include "avrc_defs.h" 33#include "gki.h" 34 35#define LOG_TAG "bt_btif_avrc" 36#include "btif_common.h" 37#include "btif_util.h" 38#include "btif_av.h" 39#include "hardware/bt_rc.h" 40#include "uinput.h" 41 42/***************************************************************************** 43** Constants & Macros 44******************************************************************************/ 45 46/* cod value for Headsets */ 47#define COD_AV_HEADSETS 0x0404 48/* for AVRC 1.4 need to change this */ 49#define MAX_RC_NOTIFICATIONS AVRC_EVT_APP_SETTING_CHANGE 50 51#define IDX_GET_PLAY_STATUS_RSP 0 52#define IDX_LIST_APP_ATTR_RSP 1 53#define IDX_LIST_APP_VALUE_RSP 2 54#define IDX_GET_CURR_APP_VAL_RSP 3 55#define IDX_SET_APP_VAL_RSP 4 56#define IDX_GET_APP_ATTR_TXT_RSP 5 57#define IDX_GET_APP_VAL_TXT_RSP 6 58#define IDX_GET_ELEMENT_ATTR_RSP 7 59#define MAX_VOLUME 128 60#define MAX_LABEL 16 61#define MAX_TRANSACTIONS_PER_SESSION 16 62#define MAX_CMD_QUEUE_LEN 8 63#define PLAY_STATUS_PLAYING 1 64 65#define CHECK_RC_CONNECTED \ 66 BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__); \ 67 if(btif_rc_cb.rc_connected == FALSE) \ 68 { \ 69 BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \ 70 return BT_STATUS_NOT_READY; \ 71 } 72 73#define FILL_PDU_QUEUE(index, ctype, label, pending) \ 74{ \ 75 btif_rc_cb.rc_pdu_info[index].ctype = ctype; \ 76 btif_rc_cb.rc_pdu_info[index].label = label; \ 77 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \ 78} 79 80#define SEND_METAMSG_RSP(index, avrc_rsp) \ 81{ \ 82 if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \ 83 { \ 84 BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \ 85 return BT_STATUS_UNHANDLED; \ 86 } \ 87 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \ 88 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \ 89 btif_rc_cb.rc_pdu_info[index].ctype = 0; \ 90 btif_rc_cb.rc_pdu_info[index].label = 0; \ 91 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \ 92} 93 94/***************************************************************************** 95** Local type definitions 96******************************************************************************/ 97typedef struct { 98 UINT8 bNotify; 99 UINT8 label; 100} btif_rc_reg_notifications_t; 101 102typedef struct 103{ 104 UINT8 label; 105 UINT8 ctype; 106 BOOLEAN is_rsp_pending; 107} btif_rc_cmd_ctxt_t; 108 109/* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */ 110typedef struct { 111 BOOLEAN rc_connected; 112 UINT8 rc_handle; 113 tBTA_AV_FEAT rc_features; 114 BD_ADDR rc_addr; 115 UINT16 rc_pending_play; 116 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN]; 117 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS]; 118 unsigned int rc_volume; 119 uint8_t rc_vol_label; 120} btif_rc_cb_t; 121 122typedef struct { 123 BOOLEAN in_use; 124 UINT8 lbl; 125 UINT8 handle; 126} rc_transaction_t; 127 128typedef struct 129{ 130 pthread_mutex_t lbllock; 131 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION]; 132} rc_device_t; 133 134 135rc_device_t device; 136 137#define MAX_UINPUT_PATHS 3 138static const char* uinput_dev_path[] = 139 {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" }; 140static int uinput_fd = -1; 141 142static int send_event (int fd, uint16_t type, uint16_t code, int32_t value); 143static void send_key (int fd, uint16_t key, int pressed); 144static int uinput_driver_check(); 145static int uinput_create(char *name); 146static int init_uinput (void); 147static void close_uinput (void); 148 149static const struct { 150 const char *name; 151 uint8_t avrcp; 152 uint16_t mapped_id; 153 uint8_t release_quirk; 154} key_map[] = { 155 { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 }, 156 { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 }, 157 { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 }, 158 { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 }, 159 { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 }, 160 { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 }, 161 { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 }, 162 { NULL, 0, 0, 0 } 163}; 164 165static void send_reject_response (UINT8 rc_handle, UINT8 label, 166 UINT8 pdu, UINT8 status); 167static UINT8 opcode_from_pdu(UINT8 pdu); 168static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, 169 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp); 170static void register_volumechange(UINT8 label); 171static void lbl_init(); 172static void lbl_destroy(); 173static void init_all_transactions(); 174static bt_status_t get_transaction(rc_transaction_t **ptransaction); 175static void release_transaction(UINT8 label); 176static rc_transaction_t* get_transaction_by_lbl(UINT8 label); 177static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg); 178static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label); 179static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label); 180 181/***************************************************************************** 182** Static variables 183******************************************************************************/ 184static btif_rc_cb_t btif_rc_cb; 185static btrc_callbacks_t *bt_rc_callbacks = NULL; 186static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL; 187 188/***************************************************************************** 189** Static functions 190******************************************************************************/ 191 192/***************************************************************************** 193** Externs 194******************************************************************************/ 195extern BOOLEAN btif_hf_call_terminated_recently(); 196extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod); 197 198 199/***************************************************************************** 200** Functions 201******************************************************************************/ 202 203/***************************************************************************** 204** Local uinput helper functions 205******************************************************************************/ 206int send_event (int fd, uint16_t type, uint16_t code, int32_t value) 207{ 208 struct uinput_event event; 209 BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__, 210 type, code, value); 211 memset(&event, 0, sizeof(event)); 212 event.type = type; 213 event.code = code; 214 event.value = value; 215 216 return write(fd, &event, sizeof(event)); 217} 218 219void send_key (int fd, uint16_t key, int pressed) 220{ 221 BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__, 222 fd, key, pressed); 223 224 if (fd < 0) 225 { 226 return; 227 } 228 229 BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd); 230 send_event(fd, EV_KEY, key, pressed); 231 send_event(fd, EV_SYN, SYN_REPORT, 0); 232} 233 234/************** uinput related functions **************/ 235int uinput_driver_check() 236{ 237 uint32_t i; 238 for (i=0; i < MAX_UINPUT_PATHS; i++) 239 { 240 if (access(uinput_dev_path[i], O_RDWR) == 0) { 241 return 0; 242 } 243 } 244 BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__); 245 return -1; 246} 247 248int uinput_create(char *name) 249{ 250 struct uinput_dev dev; 251 int fd, x = 0; 252 253 for(x=0; x < MAX_UINPUT_PATHS; x++) 254 { 255 fd = open(uinput_dev_path[x], O_RDWR); 256 if (fd < 0) 257 continue; 258 break; 259 } 260 if (x == MAX_UINPUT_PATHS) { 261 BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__); 262 return -1; 263 } 264 memset(&dev, 0, sizeof(dev)); 265 if (name) 266 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1); 267 268 dev.id.bustype = BUS_BLUETOOTH; 269 dev.id.vendor = 0x0000; 270 dev.id.product = 0x0000; 271 dev.id.version = 0x0000; 272 273 if (write(fd, &dev, sizeof(dev)) < 0) { 274 BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__); 275 close(fd); 276 return -1; 277 } 278 279 ioctl(fd, UI_SET_EVBIT, EV_KEY); 280 ioctl(fd, UI_SET_EVBIT, EV_REL); 281 ioctl(fd, UI_SET_EVBIT, EV_SYN); 282 283 for (x = 0; key_map[x].name != NULL; x++) 284 ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id); 285 286 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) { 287 BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__); 288 close(fd); 289 return -1; 290 } 291 return fd; 292} 293 294int init_uinput (void) 295{ 296 char *name = "AVRCP"; 297 298 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 299 uinput_fd = uinput_create(name); 300 if (uinput_fd < 0) { 301 BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)", 302 __FUNCTION__, name, uinput_fd); 303 } else { 304 BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)", 305 __FUNCTION__, name, uinput_fd); 306 } 307 return uinput_fd; 308} 309 310void close_uinput (void) 311{ 312 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 313 if (uinput_fd > 0) { 314 ioctl(uinput_fd, UI_DEV_DESTROY); 315 316 close(uinput_fd); 317 uinput_fd = -1; 318 } 319} 320 321void handle_rc_features() 322{ 323 btrc_remote_features_t rc_features = BTRC_FEAT_NONE; 324 bt_bdaddr_t rc_addr; 325 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 326 327 // TODO(eisenbach): If devices need to be blacklisted for absolute 328 // volume, it should be added to device/include/interop_database.h 329 // For now, everything goes... If blacklisting is necessary, exclude 330 // the following bit here: 331 // btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL; 332 333 if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE) 334 { 335 rc_features |= BTRC_FEAT_BROWSE; 336 } 337 338 if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) && 339 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)) 340 { 341 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME; 342 } 343 344 if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA) 345 { 346 rc_features |= BTRC_FEAT_METADATA; 347 } 348 349 BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features); 350 HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features) 351 352#if (AVRC_ADV_CTRL_INCLUDED == TRUE) 353 BTIF_TRACE_DEBUG("Checking for feature flags in btif_rc_handler with label %d", 354 btif_rc_cb.rc_vol_label); 355 // Register for volume change on connect 356 if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL && 357 btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 358 { 359 rc_transaction_t *p_transaction=NULL; 360 bt_status_t status = BT_STATUS_NOT_READY; 361 if(MAX_LABEL==btif_rc_cb.rc_vol_label) 362 { 363 status=get_transaction(&p_transaction); 364 } 365 else 366 { 367 p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label); 368 if(NULL!=p_transaction) 369 { 370 BTIF_TRACE_DEBUG("register_volumechange already in progress for label %d", 371 btif_rc_cb.rc_vol_label); 372 return; 373 } 374 else 375 status=get_transaction(&p_transaction); 376 } 377 378 if(BT_STATUS_SUCCESS == status && NULL!=p_transaction) 379 { 380 btif_rc_cb.rc_vol_label=p_transaction->lbl; 381 register_volumechange(btif_rc_cb.rc_vol_label); 382 } 383 } 384#endif 385} 386 387 388/*************************************************************************** 389 * Function handle_rc_connect 390 * 391 * - Argument: tBTA_AV_RC_OPEN RC open data structure 392 * 393 * - Description: RC connection event handler 394 * 395 ***************************************************************************/ 396void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) 397{ 398 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle); 399 bt_status_t result = BT_STATUS_SUCCESS; 400#if (AVRC_CTLR_INCLUDED == TRUE) 401 bt_bdaddr_t rc_addr; 402#endif 403 404 if(p_rc_open->status == BTA_AV_SUCCESS) 405 { 406 //check if already some RC is connected 407 if (btif_rc_cb.rc_connected) 408 { 409 BTIF_TRACE_ERROR("Got RC OPEN in connected state, Connected RC: %d \ 410 and Current RC: %d", btif_rc_cb.rc_handle,p_rc_open->rc_handle ); 411 if ((btif_rc_cb.rc_handle != p_rc_open->rc_handle) 412 && (bdcmp(btif_rc_cb.rc_addr, p_rc_open->peer_addr))) 413 { 414 BTIF_TRACE_DEBUG("Got RC connected for some other handle"); 415 BTA_AvCloseRc(p_rc_open->rc_handle); 416 return; 417 } 418 } 419 memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR)); 420 btif_rc_cb.rc_features = p_rc_open->peer_features; 421 btif_rc_cb.rc_vol_label=MAX_LABEL; 422 btif_rc_cb.rc_volume=MAX_VOLUME; 423 424 btif_rc_cb.rc_connected = TRUE; 425 btif_rc_cb.rc_handle = p_rc_open->rc_handle; 426 427 /* on locally initiated connection we will get remote features as part of connect */ 428 if (btif_rc_cb.rc_features != 0) 429 handle_rc_features(); 430 431 result = uinput_driver_check(); 432 if(result == BT_STATUS_SUCCESS) 433 { 434 init_uinput(); 435 } 436#if (AVRC_CTLR_INCLUDED == TRUE) 437 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 438 /* report connection state if device is AVRCP target */ 439 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) { 440 if (bt_rc_ctrl_callbacks != NULL) { 441 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr); 442 } 443 } 444#endif 445 } 446 else 447 { 448 BTIF_TRACE_ERROR("%s Connect failed with error code: %d", 449 __FUNCTION__, p_rc_open->status); 450 btif_rc_cb.rc_connected = FALSE; 451 } 452} 453 454/*************************************************************************** 455 * Function handle_rc_disconnect 456 * 457 * - Argument: tBTA_AV_RC_CLOSE RC close data structure 458 * 459 * - Description: RC disconnection event handler 460 * 461 ***************************************************************************/ 462void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close) 463{ 464#if (AVRC_CTLR_INCLUDED == TRUE) 465 bt_bdaddr_t rc_addr; 466 tBTA_AV_FEAT features; 467#endif 468 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle); 469 if ((p_rc_close->rc_handle != btif_rc_cb.rc_handle) 470 && (bdcmp(btif_rc_cb.rc_addr, p_rc_close->peer_addr))) 471 { 472 BTIF_TRACE_ERROR("Got disconnect of unknown device"); 473 return; 474 } 475 476 btif_rc_cb.rc_handle = 0; 477 btif_rc_cb.rc_connected = FALSE; 478 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR)); 479 memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif)); 480#if (AVRC_CTLR_INCLUDED == TRUE) 481 features = btif_rc_cb.rc_features; 482#endif 483 btif_rc_cb.rc_features = 0; 484 btif_rc_cb.rc_vol_label=MAX_LABEL; 485 btif_rc_cb.rc_volume=MAX_VOLUME; 486 init_all_transactions(); 487 close_uinput(); 488#if (AVRC_CTLR_INCLUDED == TRUE) 489 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 490#endif 491 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR)); 492#if (AVRC_CTLR_INCLUDED == TRUE) 493 /* report connection state if device is AVRCP target */ 494 if (features & BTA_AV_FEAT_RCTG) { 495 if (bt_rc_ctrl_callbacks != NULL) { 496 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr); 497 } 498 } 499#endif 500} 501 502/*************************************************************************** 503 * Function handle_rc_passthrough_cmd 504 * 505 * - Argument: tBTA_AV_RC rc_id remote control command ID 506 * tBTA_AV_STATE key_state status of key press 507 * 508 * - Description: Remote control command handler 509 * 510 ***************************************************************************/ 511void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd) 512{ 513 const char *status; 514 int pressed, i; 515 516 BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id); 517 518 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */ 519 if (p_remote_cmd) 520 { 521 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */ 522 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected())) 523 { 524 if (p_remote_cmd->key_state == AVRC_STATE_PRESS) 525 { 526 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__); 527 btif_rc_cb.rc_pending_play = TRUE; 528 } 529 return; 530 } 531 532 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play)) 533 { 534 APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__); 535 btif_rc_cb.rc_pending_play = FALSE; 536 return; 537 } 538 } 539 540 if ((p_remote_cmd->rc_id == BTA_AV_RC_STOP) && (!btif_av_stream_started_ready())) 541 { 542 APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd",__FUNCTION__); 543 return; 544 } 545 546 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) { 547 status = "released"; 548 pressed = 0; 549 } else { 550 status = "pressed"; 551 pressed = 1; 552 } 553 554 /* If this is Play/Pause command (press or release) before processing, check the following 555 * a voice call has ended recently 556 * the remote device is not of type headset 557 * If the above conditions meet, drop the Play/Pause command 558 * This fix is to interop with certain carkits which sends an automatic PLAY or PAUSE 559 * commands right after call ends 560 */ 561 if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&& 562 (btif_hf_call_terminated_recently() == TRUE) && 563 (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE)) 564 { 565 BTIF_TRACE_DEBUG("%s:Dropping the play/Pause command received right after call end cmd:%d", 566 __FUNCTION__,p_remote_cmd->rc_id); 567 return; 568 } 569 570 if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) { 571 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed); 572 return; 573 } 574 575 for (i = 0; key_map[i].name != NULL; i++) { 576 if (p_remote_cmd->rc_id == key_map[i].avrcp) { 577 BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status); 578 579 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button 580 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE 581 * comes 1 second after the press, the MediaPlayer UI goes into a bad state. 582 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc. 583 * The fix is to generate a release right after the press and drown the 'actual' 584 * release. 585 */ 586 if ((key_map[i].release_quirk == 1) && (pressed == 0)) 587 { 588 BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now", 589 __FUNCTION__, key_map[i].name); 590 return; 591 } 592 send_key(uinput_fd, key_map[i].mapped_id, pressed); 593 if ((key_map[i].release_quirk == 1) && (pressed == 1)) 594 { 595 GKI_delay(30); // 30ms 596 BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now", 597 __FUNCTION__, key_map[i].name); 598 send_key(uinput_fd, key_map[i].mapped_id, 0); 599 } 600 break; 601 } 602 } 603 604 if (key_map[i].name == NULL) 605 BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__, 606 p_remote_cmd->rc_id, status); 607} 608 609/*************************************************************************** 610 * Function handle_rc_passthrough_rsp 611 * 612 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response 613 * 614 * - Description: Remote control passthrough response handler 615 * 616 ***************************************************************************/ 617void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp) 618{ 619#if (AVRC_CTLR_INCLUDED == TRUE) 620 const char *status; 621 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 622 { 623 int key_state; 624 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) 625 { 626 status = "released"; 627 key_state = 1; 628 } 629 else 630 { 631 status = "pressed"; 632 key_state = 0; 633 } 634 635 BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status); 636 637 release_transaction(p_remote_rsp->label); 638 if (bt_rc_ctrl_callbacks != NULL) { 639 HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state); 640 } 641 } 642 else 643 { 644 BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__); 645 } 646#else 647 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__); 648#endif 649} 650 651void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command) 652{ 653 tAVRC_RESPONSE avrc_rsp = {0}; 654 avrc_rsp.rsp.pdu = pavrc_command->pdu; 655 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR; 656 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode; 657 658 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id; 659 avrc_rsp.reg_notif.param.uid_counter = 0; 660 661 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp); 662 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp); 663 664} 665 666 667/*************************************************************************** 668 * Function handle_rc_metamsg_cmd 669 * 670 * - Argument: tBTA_AV_VENDOR Structure containing the received 671 * metamsg command 672 * 673 * - Description: Remote control metamsg command handler (AVRCP 1.3) 674 * 675 ***************************************************************************/ 676void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg) 677{ 678 /* Parse the metamsg command and pass it on to BTL-IFS */ 679 UINT8 scratch_buf[512] = {0}; 680 tAVRC_COMMAND avrc_command = {0}; 681 tAVRC_STS status; 682 683 BTIF_TRACE_EVENT("+ %s", __FUNCTION__); 684 685 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR) 686 { 687 BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode); 688 return; 689 } 690 if (pmeta_msg->len < 3) 691 { 692 BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode, 693 pmeta_msg->len); 694 return; 695 } 696 697 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) 698 { 699#if (AVRC_ADV_CTRL_INCLUDED == TRUE) 700{ 701 rc_transaction_t *transaction=NULL; 702 transaction=get_transaction_by_lbl(pmeta_msg->label); 703 if(NULL!=transaction) 704 { 705 handle_rc_metamsg_rsp(pmeta_msg); 706 } 707 else 708 { 709 BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.", 710 __FUNCTION__, pmeta_msg->code, pmeta_msg->label); 711 } 712 return; 713} 714#else 715{ 716 BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.", 717 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 718 return; 719} 720#endif 721 } 722 723 status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf)); 724 BTIF_TRACE_DEBUG("Received vendor command.code,PDU and label: %d, %d,%d",pmeta_msg->code, 725 avrc_command.cmd.pdu, pmeta_msg->label); 726 727 if (status != AVRC_STS_NO_ERROR) 728 { 729 /* return error */ 730 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x", 731 __FUNCTION__, status); 732 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status); 733 } 734 else 735 { 736 /* if RegisterNotification, add it to our registered queue */ 737 738 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) 739 { 740 UINT8 event_id = avrc_command.reg_notif.event_id; 741 BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x", 742 __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code); 743 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE; 744 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label; 745 746 if(event_id == AVRC_EVT_UIDS_CHANGE) 747 { 748 handle_uid_changed_notification(pmeta_msg, &avrc_command); 749 return; 750 } 751 752 } 753 754 BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s", 755 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu)); 756 757 /* Since handle_rc_metamsg_cmd() itself is called from 758 *btif context, no context switching is required. Invoke 759 * btif_rc_upstreams_evt directly from here. */ 760 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code, 761 pmeta_msg->label); 762 } 763} 764 765/*************************************************************************** 766 ** 767 ** Function btif_rc_handler 768 ** 769 ** Description RC event handler 770 ** 771 ***************************************************************************/ 772void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data) 773{ 774 BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event)); 775 switch (event) 776 { 777 case BTA_AV_RC_OPEN_EVT: 778 { 779 BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_open.peer_features); 780 handle_rc_connect( &(p_data->rc_open) ); 781 }break; 782 783 case BTA_AV_RC_CLOSE_EVT: 784 { 785 handle_rc_disconnect( &(p_data->rc_close) ); 786 }break; 787 788 case BTA_AV_REMOTE_CMD_EVT: 789 { 790 BTIF_TRACE_DEBUG("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id, 791 p_data->remote_cmd.key_state); 792 handle_rc_passthrough_cmd( (&p_data->remote_cmd) ); 793 } 794 break; 795#if (AVRC_CTLR_INCLUDED == TRUE) 796 case BTA_AV_REMOTE_RSP_EVT: 797 { 798 BTIF_TRACE_DEBUG("RSP: rc_id:0x%x key_state:%d", p_data->remote_rsp.rc_id, 799 p_data->remote_rsp.key_state); 800 handle_rc_passthrough_rsp( (&p_data->remote_rsp) ); 801 } 802 break; 803#endif 804 case BTA_AV_RC_FEAT_EVT: 805 { 806 BTIF_TRACE_DEBUG("Peer_features:%x", p_data->rc_feat.peer_features); 807 btif_rc_cb.rc_features = p_data->rc_feat.peer_features; 808 handle_rc_features(); 809 } 810 break; 811 case BTA_AV_META_MSG_EVT: 812 { 813 BTIF_TRACE_DEBUG("BTA_AV_META_MSG_EVT code:%d label:%d", p_data->meta_msg.code, 814 p_data->meta_msg.label); 815 BTIF_TRACE_DEBUG(" company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id, 816 p_data->meta_msg.len, p_data->meta_msg.rc_handle); 817 /* handle the metamsg command */ 818 handle_rc_metamsg_cmd(&(p_data->meta_msg)); 819 } 820 break; 821 default: 822 BTIF_TRACE_DEBUG("Unhandled RC event : 0x%x", event); 823 } 824} 825 826/*************************************************************************** 827 ** 828 ** Function btif_rc_get_connected_peer 829 ** 830 ** Description Fetches the connected headset's BD_ADDR if any 831 ** 832 ***************************************************************************/ 833BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr) 834{ 835 if (btif_rc_cb.rc_connected == TRUE) { 836 bdcpy(peer_addr, btif_rc_cb.rc_addr); 837 return TRUE; 838 } 839 return FALSE; 840} 841 842/*************************************************************************** 843 ** 844 ** Function btif_rc_check_handle_pending_play 845 ** 846 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app 847 ** 848 ***************************************************************************/ 849 850/* clear the queued PLAY command. if bSend is TRUE, forward to app */ 851void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp) 852{ 853 UNUSED(peer_addr); 854 855 BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp); 856 if (btif_rc_cb.rc_pending_play) 857 { 858 if (bSendToApp) 859 { 860 tBTA_AV_REMOTE_CMD remote_cmd; 861 APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__); 862 863 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); 864 remote_cmd.rc_handle = btif_rc_cb.rc_handle; 865 remote_cmd.rc_id = AVRC_ID_PLAY; 866 remote_cmd.hdr.ctype = AVRC_CMD_CTRL; 867 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU; 868 869 /* delay sending to app, else there is a timing issue in the framework, 870 ** which causes the audio to be on th device's speaker. Delay between 871 ** OPEN & RC_PLAYs 872 */ 873 GKI_delay (200); 874 /* send to app - both PRESSED & RELEASED */ 875 remote_cmd.key_state = AVRC_STATE_PRESS; 876 handle_rc_passthrough_cmd( &remote_cmd ); 877 878 GKI_delay (100); 879 880 remote_cmd.key_state = AVRC_STATE_RELEASE; 881 handle_rc_passthrough_cmd( &remote_cmd ); 882 } 883 btif_rc_cb.rc_pending_play = FALSE; 884 } 885} 886 887/* Generic reject response */ 888static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status) 889{ 890 UINT8 ctype = AVRC_RSP_REJ; 891 tAVRC_RESPONSE avrc_rsp; 892 BT_HDR *p_msg = NULL; 893 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 894 895 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu); 896 avrc_rsp.rsp.pdu = pdu; 897 avrc_rsp.rsp.status = status; 898 899 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) ) 900 { 901 BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x", 902 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status); 903 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 904 } 905} 906 907/*************************************************************************** 908 * Function send_metamsg_rsp 909 * 910 * - Argument: 911 * rc_handle RC handle corresponding to the connected RC 912 * label Label of the RC response 913 * code Response type 914 * pmetamsg_resp Vendor response 915 * 916 * - Description: Remote control metamsg response handler (AVRCP 1.3) 917 * 918 ***************************************************************************/ 919static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code, 920 tAVRC_RESPONSE *pmetamsg_resp) 921{ 922 UINT8 ctype; 923 924 if (!pmetamsg_resp) 925 { 926 BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__); 927 return; 928 } 929 930 BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__, 931 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu)); 932 933 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR) 934 { 935 ctype = AVRC_RSP_REJ; 936 } 937 else 938 { 939 if ( code < AVRC_RSP_NOT_IMPL) 940 { 941 if (code == AVRC_CMD_NOTIF) 942 { 943 ctype = AVRC_RSP_INTERIM; 944 } 945 else if (code == AVRC_CMD_STATUS) 946 { 947 ctype = AVRC_RSP_IMPL_STBL; 948 } 949 else 950 { 951 ctype = AVRC_RSP_ACCEPT; 952 } 953 } 954 else 955 { 956 ctype = code; 957 } 958 } 959 /* if response is for register_notification, make sure the rc has 960 actually registered for this */ 961 if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED)) 962 { 963 BOOLEAN bSent = FALSE; 964 UINT8 event_id = pmetamsg_resp->reg_notif.event_id; 965 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify); 966 967 /* de-register this notification for a CHANGED response */ 968 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE; 969 BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__, 970 btif_rc_cb.rc_handle, event_id, bNotify); 971 if (bNotify) 972 { 973 BT_HDR *p_msg = NULL; 974 tAVRC_STS status; 975 976 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle, 977 pmetamsg_resp, &p_msg)) ) 978 { 979 BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d", 980 __FUNCTION__, btif_rc_cb.rc_handle, event_id); 981 bSent = TRUE; 982 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 983 ctype, p_msg); 984 } 985 else 986 { 987 BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x", 988 __FUNCTION__, status); 989 } 990 991 } 992 993 if (!bSent) 994 { 995 BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \ 996 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 997 } 998 } 999 else 1000 { 1001 /* All other commands go here */ 1002 1003 BT_HDR *p_msg = NULL; 1004 tAVRC_STS status; 1005 1006 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg); 1007 1008 if (status == AVRC_STS_NO_ERROR) 1009 { 1010 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 1011 } 1012 else 1013 { 1014 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x", 1015 __FUNCTION__, status); 1016 } 1017 } 1018} 1019 1020static UINT8 opcode_from_pdu(UINT8 pdu) 1021{ 1022 UINT8 opcode = 0; 1023 1024 switch (pdu) 1025 { 1026 case AVRC_PDU_NEXT_GROUP: 1027 case AVRC_PDU_PREV_GROUP: /* pass thru */ 1028 opcode = AVRC_OP_PASS_THRU; 1029 break; 1030 1031 default: /* vendor */ 1032 opcode = AVRC_OP_VENDOR; 1033 break; 1034 } 1035 1036 return opcode; 1037} 1038 1039/******************************************************************************* 1040** 1041** Function btif_rc_upstreams_evt 1042** 1043** Description Executes AVRC UPSTREAMS events in btif context. 1044** 1045** Returns void 1046** 1047*******************************************************************************/ 1048static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label) 1049{ 1050 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__, 1051 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label); 1052 1053 switch (event) 1054 { 1055 case AVRC_PDU_GET_PLAY_STATUS: 1056 { 1057 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE) 1058 HAL_CBACK(bt_rc_callbacks, get_play_status_cb); 1059 } 1060 break; 1061 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 1062 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 1063 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 1064 case AVRC_PDU_SET_PLAYER_APP_VALUE: 1065 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 1066 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 1067 { 1068 /* TODO: Add support for Application Settings */ 1069 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD); 1070 } 1071 break; 1072 case AVRC_PDU_GET_ELEMENT_ATTR: 1073 { 1074 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1075 UINT8 num_attr; 1076 memset(&element_attrs, 0, sizeof(element_attrs)); 1077 if (pavrc_cmd->get_elem_attrs.num_attr == 0) 1078 { 1079 /* CT requests for all attributes */ 1080 int attr_cnt; 1081 num_attr = BTRC_MAX_ELEM_ATTR_SIZE; 1082 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++) 1083 { 1084 element_attrs[attr_cnt] = attr_cnt + 1; 1085 } 1086 } 1087 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF) 1088 { 1089 /* 0xff indicates, no attributes requested - reject */ 1090 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 1091 AVRC_STS_BAD_PARAM); 1092 return; 1093 } 1094 else 1095 { 1096 int attr_cnt, filled_attr_count; 1097 1098 num_attr = 0; 1099 /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid, 1100 * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID. 1101 * Fill only valid entries. 1102 */ 1103 for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) && 1104 (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++) 1105 { 1106 if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) && 1107 (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID)) 1108 { 1109 /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases 1110 */ 1111 for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++) 1112 { 1113 if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt]) 1114 break; 1115 } 1116 if (filled_attr_count == num_attr) 1117 { 1118 element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt]; 1119 num_attr++; 1120 } 1121 } 1122 } 1123 } 1124 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE); 1125 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs); 1126 } 1127 break; 1128 case AVRC_PDU_REGISTER_NOTIFICATION: 1129 { 1130 if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED && 1131 pavrc_cmd->reg_notif.param == 0) 1132 { 1133 BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.", 1134 __FUNCTION__); 1135 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM); 1136 /* de-register this notification for a rejected response */ 1137 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE; 1138 return; 1139 } 1140 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id, 1141 pavrc_cmd->reg_notif.param); 1142 } 1143 break; 1144 case AVRC_PDU_INFORM_DISPLAY_CHARSET: 1145 { 1146 tAVRC_RESPONSE avrc_rsp; 1147 BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__); 1148 if(btif_rc_cb.rc_connected == TRUE) 1149 { 1150 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP)); 1151 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET); 1152 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET; 1153 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR; 1154 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp); 1155 } 1156 } 1157 break; 1158 default: 1159 { 1160 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 1161 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD); 1162 return; 1163 } 1164 break; 1165 } 1166 1167} 1168 1169 1170/******************************************************************************* 1171** 1172** Function btif_rc_upstreams_rsp_evt 1173** 1174** Description Executes AVRC UPSTREAMS response events in btif context. 1175** 1176** Returns void 1177** 1178*******************************************************************************/ 1179static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label) 1180{ 1181 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__, 1182 dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label); 1183 1184#if (AVRC_ADV_CTRL_INCLUDED == TRUE) 1185 switch (event) 1186 { 1187 case AVRC_PDU_REGISTER_NOTIFICATION: 1188 { 1189 if(AVRC_RSP_CHANGED==ctype) 1190 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume; 1191 HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype) 1192 } 1193 break; 1194 1195 case AVRC_PDU_SET_ABSOLUTE_VOLUME: 1196 { 1197 BTIF_TRACE_DEBUG("Set absolute volume change event received: volume %d,ctype %d", 1198 pavrc_resp->volume.volume,ctype); 1199 if(AVRC_RSP_ACCEPT==ctype) 1200 btif_rc_cb.rc_volume=pavrc_resp->volume.volume; 1201 HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype) 1202 } 1203 break; 1204 1205 default: 1206 return; 1207 } 1208#endif 1209} 1210 1211/************************************************************************************ 1212** AVRCP API Functions 1213************************************************************************************/ 1214 1215/******************************************************************************* 1216** 1217** Function init 1218** 1219** Description Initializes the AVRC interface 1220** 1221** Returns bt_status_t 1222** 1223*******************************************************************************/ 1224static bt_status_t init(btrc_callbacks_t* callbacks ) 1225{ 1226 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 1227 bt_status_t result = BT_STATUS_SUCCESS; 1228 1229 if (bt_rc_callbacks) 1230 return BT_STATUS_DONE; 1231 1232 bt_rc_callbacks = callbacks; 1233 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb)); 1234 btif_rc_cb.rc_vol_label=MAX_LABEL; 1235 btif_rc_cb.rc_volume=MAX_VOLUME; 1236 lbl_init(); 1237 1238 return result; 1239} 1240 1241/******************************************************************************* 1242** 1243** Function init_ctrl 1244** 1245** Description Initializes the AVRC interface 1246** 1247** Returns bt_status_t 1248** 1249*******************************************************************************/ 1250static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks ) 1251{ 1252 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 1253 bt_status_t result = BT_STATUS_SUCCESS; 1254 1255 if (bt_rc_ctrl_callbacks) 1256 return BT_STATUS_DONE; 1257 1258 bt_rc_ctrl_callbacks = callbacks; 1259 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb)); 1260 btif_rc_cb.rc_vol_label=MAX_LABEL; 1261 btif_rc_cb.rc_volume=MAX_VOLUME; 1262 lbl_init(); 1263 1264 return result; 1265} 1266 1267/*************************************************************************** 1268** 1269** Function get_play_status_rsp 1270** 1271** Description Returns the current play status. 1272** This method is called in response to 1273** GetPlayStatus request. 1274** 1275** Returns bt_status_t 1276** 1277***************************************************************************/ 1278static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len, 1279 uint32_t song_pos) 1280{ 1281 tAVRC_RESPONSE avrc_rsp; 1282 CHECK_RC_CONNECTED 1283 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP)); 1284 avrc_rsp.get_play_status.song_len = song_len; 1285 avrc_rsp.get_play_status.song_pos = song_pos; 1286 avrc_rsp.get_play_status.play_status = play_status; 1287 1288 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 1289 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS); 1290 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1291 /* Send the response */ 1292 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp); 1293 return BT_STATUS_SUCCESS; 1294} 1295 1296/*************************************************************************** 1297** 1298** Function get_element_attr_rsp 1299** 1300** Description Returns the current songs' element attributes 1301** in text. 1302** 1303** Returns bt_status_t 1304** 1305***************************************************************************/ 1306static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs) 1307{ 1308 tAVRC_RESPONSE avrc_rsp; 1309 UINT32 i; 1310 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1311 CHECK_RC_CONNECTED 1312 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); 1313 1314 if (num_attr == 0) 1315 { 1316 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM; 1317 } 1318 else 1319 { 1320 for (i=0; i<num_attr; i++) { 1321 element_attrs[i].attr_id = p_attrs[i].attr_id; 1322 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8; 1323 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text); 1324 element_attrs[i].name.p_str = p_attrs[i].text; 1325 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s", 1326 __FUNCTION__, (unsigned int)element_attrs[i].attr_id, 1327 element_attrs[i].name.charset_id, element_attrs[i].name.str_len, 1328 element_attrs[i].name.p_str); 1329 } 1330 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1331 } 1332 avrc_rsp.get_elem_attrs.num_attr = num_attr; 1333 avrc_rsp.get_elem_attrs.p_attrs = element_attrs; 1334 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 1335 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR); 1336 /* Send the response */ 1337 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp); 1338 return BT_STATUS_SUCCESS; 1339} 1340 1341/*************************************************************************** 1342** 1343** Function register_notification_rsp 1344** 1345** Description Response to the register notification request. 1346** in text. 1347** 1348** Returns bt_status_t 1349** 1350***************************************************************************/ 1351static bt_status_t register_notification_rsp(btrc_event_id_t event_id, 1352 btrc_notification_type_t type, btrc_register_notification_t *p_param) 1353{ 1354 tAVRC_RESPONSE avrc_rsp; 1355 CHECK_RC_CONNECTED 1356 BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 1357 if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE) 1358 { 1359 BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id); 1360 return BT_STATUS_NOT_READY; 1361 } 1362 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP)); 1363 avrc_rsp.reg_notif.event_id = event_id; 1364 1365 switch(event_id) 1366 { 1367 case BTRC_EVT_PLAY_STATUS_CHANGED: 1368 avrc_rsp.reg_notif.param.play_status = p_param->play_status; 1369 if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING) 1370 btif_av_clear_remote_suspend_flag(); 1371 break; 1372 case BTRC_EVT_TRACK_CHANGE: 1373 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t)); 1374 break; 1375 case BTRC_EVT_PLAY_POS_CHANGED: 1376 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos; 1377 break; 1378 default: 1379 BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id); 1380 return BT_STATUS_UNHANDLED; 1381 } 1382 1383 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1384 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION); 1385 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1386 1387 /* Send the response. */ 1388 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 1389 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp); 1390 return BT_STATUS_SUCCESS; 1391} 1392 1393/*************************************************************************** 1394** 1395** Function set_volume 1396** 1397** Description Send current volume setting to remote side. 1398** Support limited to SetAbsoluteVolume 1399** This can be enhanced to support Relative Volume (AVRCP 1.0). 1400** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN 1401** as opposed to absolute volume level 1402** volume: Should be in the range 0-127. bit7 is reseved and cannot be set 1403** 1404** Returns bt_status_t 1405** 1406***************************************************************************/ 1407static bt_status_t set_volume(uint8_t volume) 1408{ 1409 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 1410 CHECK_RC_CONNECTED 1411 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 1412 rc_transaction_t *p_transaction=NULL; 1413 1414 if(btif_rc_cb.rc_volume==volume) 1415 { 1416 status=BT_STATUS_DONE; 1417 BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume); 1418 return status; 1419 } 1420 1421 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) && 1422 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)) 1423 { 1424 tAVRC_COMMAND avrc_cmd = {0}; 1425 BT_HDR *p_msg = NULL; 1426 1427 BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume); 1428 avrc_cmd.volume.opcode = AVRC_OP_VENDOR; 1429 avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME; 1430 avrc_cmd.volume.status = AVRC_STS_NO_ERROR; 1431 avrc_cmd.volume.volume = volume; 1432 1433 if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR) 1434 { 1435 bt_status_t tran_status=get_transaction(&p_transaction); 1436 if(BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction) 1437 { 1438 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 1439 __FUNCTION__,p_transaction->lbl); 1440 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg); 1441 status = BT_STATUS_SUCCESS; 1442 } 1443 else 1444 { 1445 if(NULL!=p_msg) 1446 GKI_freebuf(p_msg); 1447 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x", 1448 __FUNCTION__, tran_status); 1449 status = BT_STATUS_FAIL; 1450 } 1451 } 1452 else 1453 { 1454 BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x", 1455 __FUNCTION__, status); 1456 status = BT_STATUS_FAIL; 1457 } 1458 } 1459 else 1460 status=BT_STATUS_NOT_READY; 1461 return status; 1462} 1463 1464 1465/*************************************************************************** 1466** 1467** Function register_volumechange 1468** 1469** Description Register for volume change notification from remote side. 1470** 1471** Returns void 1472** 1473***************************************************************************/ 1474 1475static void register_volumechange (UINT8 lbl) 1476{ 1477 tAVRC_COMMAND avrc_cmd = {0}; 1478 BT_HDR *p_msg = NULL; 1479 tAVRC_STS BldResp=AVRC_STS_BAD_CMD; 1480 rc_transaction_t *p_transaction=NULL; 1481 1482 BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl); 1483 1484 avrc_cmd.cmd.opcode=0x00; 1485 avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1486 avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE; 1487 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR; 1488 1489 BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg); 1490 if(AVRC_STS_NO_ERROR==BldResp && p_msg) 1491 { 1492 p_transaction=get_transaction_by_lbl(lbl); 1493 if(NULL!=p_transaction) 1494 { 1495 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_NOTIF, p_msg); 1496 BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called",__FUNCTION__); 1497 } 1498 else 1499 { 1500 if(NULL!=p_msg) 1501 GKI_freebuf(p_msg); 1502 BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",__FUNCTION__,lbl); 1503 } 1504 } 1505 else 1506 BTIF_TRACE_ERROR("%s failed to build command:%d",__FUNCTION__,BldResp); 1507} 1508 1509 1510/*************************************************************************** 1511** 1512** Function handle_rc_metamsg_rsp 1513** 1514** Description Handle RC metamessage response 1515** 1516** Returns void 1517** 1518***************************************************************************/ 1519static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg) 1520{ 1521 tAVRC_RESPONSE avrc_response = {0}; 1522 UINT8 scratch_buf[512] = {0}; 1523 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 1524 1525 if(AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code 1526 || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code 1527 || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code)) 1528 { 1529 status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf)); 1530 BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d", 1531 __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu, 1532 status, pmeta_msg->label); 1533 1534 if (status != AVRC_STS_NO_ERROR) 1535 { 1536 if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu 1537 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id 1538 && btif_rc_cb.rc_vol_label==pmeta_msg->label) 1539 { 1540 btif_rc_cb.rc_vol_label=MAX_LABEL; 1541 release_transaction(btif_rc_cb.rc_vol_label); 1542 } 1543 else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu) 1544 { 1545 release_transaction(pmeta_msg->label); 1546 } 1547 return; 1548 } 1549 else if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu 1550 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id 1551 && btif_rc_cb.rc_vol_label!=pmeta_msg->label) 1552 { 1553 // Just discard the message, if the device sends back with an incorrect label 1554 BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d", 1555 __FUNCTION__, pmeta_msg->code, pmeta_msg->label); 1556 return; 1557 } 1558 } 1559 else 1560 { 1561 BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.", 1562 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 1563 return; 1564 } 1565 1566 if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu 1567 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id 1568 && AVRC_RSP_CHANGED==pmeta_msg->code) 1569 { 1570 /* re-register for volume change notification */ 1571 // Do not re-register for rejected case, as it might get into endless loop 1572 register_volumechange(btif_rc_cb.rc_vol_label); 1573 } 1574 else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu) 1575 { 1576 /* free up the label here */ 1577 release_transaction(pmeta_msg->label); 1578 } 1579 1580 BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s", 1581 __FUNCTION__, dump_rc_pdu(avrc_response.pdu)); 1582 btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code, 1583 pmeta_msg->label); 1584} 1585 1586 1587/*************************************************************************** 1588** 1589** Function cleanup 1590** 1591** Description Closes the AVRC interface 1592** 1593** Returns void 1594** 1595***************************************************************************/ 1596static void cleanup() 1597{ 1598 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 1599 close_uinput(); 1600 if (bt_rc_callbacks) 1601 { 1602 bt_rc_callbacks = NULL; 1603 } 1604 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t)); 1605 lbl_destroy(); 1606 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__); 1607} 1608 1609/*************************************************************************** 1610** 1611** Function cleanup_ctrl 1612** 1613** Description Closes the AVRC Controller interface 1614** 1615** Returns void 1616** 1617***************************************************************************/ 1618static void cleanup_ctrl() 1619{ 1620 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 1621 1622 if (bt_rc_ctrl_callbacks) 1623 { 1624 bt_rc_ctrl_callbacks = NULL; 1625 } 1626 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t)); 1627 lbl_destroy(); 1628 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__); 1629} 1630 1631static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state) 1632{ 1633 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 1634#if (AVRC_CTLR_INCLUDED == TRUE) 1635 CHECK_RC_CONNECTED 1636 rc_transaction_t *p_transaction=NULL; 1637 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__, 1638 key_code, key_state); 1639 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 1640 { 1641 bt_status_t tran_status = get_transaction(&p_transaction); 1642 if(BT_STATUS_SUCCESS == tran_status && NULL != p_transaction) 1643 { 1644 BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl, 1645 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state); 1646 status = BT_STATUS_SUCCESS; 1647 BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__); 1648 } 1649 else 1650 { 1651 status = BT_STATUS_FAIL; 1652 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__); 1653 } 1654 } 1655 else 1656 { 1657 status = BT_STATUS_FAIL; 1658 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__); 1659 } 1660#else 1661 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 1662#endif 1663 return status; 1664} 1665 1666static const btrc_interface_t bt_rc_interface = { 1667 sizeof(bt_rc_interface), 1668 init, 1669 get_play_status_rsp, 1670 NULL, /* list_player_app_attr_rsp */ 1671 NULL, /* list_player_app_value_rsp */ 1672 NULL, /* get_player_app_value_rsp */ 1673 NULL, /* get_player_app_attr_text_rsp */ 1674 NULL, /* get_player_app_value_text_rsp */ 1675 get_element_attr_rsp, 1676 NULL, /* set_player_app_value_rsp */ 1677 register_notification_rsp, 1678 set_volume, 1679 cleanup, 1680}; 1681 1682static const btrc_ctrl_interface_t bt_rc_ctrl_interface = { 1683 sizeof(bt_rc_ctrl_interface), 1684 init_ctrl, 1685 send_passthrough_cmd, 1686 cleanup_ctrl, 1687}; 1688 1689/******************************************************************************* 1690** 1691** Function btif_rc_get_interface 1692** 1693** Description Get the AVRCP Target callback interface 1694** 1695** Returns btav_interface_t 1696** 1697*******************************************************************************/ 1698const btrc_interface_t *btif_rc_get_interface(void) 1699{ 1700 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1701 return &bt_rc_interface; 1702} 1703 1704/******************************************************************************* 1705** 1706** Function btif_rc_ctrl_get_interface 1707** 1708** Description Get the AVRCP Controller callback interface 1709** 1710** Returns btav_interface_t 1711** 1712*******************************************************************************/ 1713const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void) 1714{ 1715 BTIF_TRACE_EVENT("%s", __FUNCTION__); 1716 return &bt_rc_ctrl_interface; 1717} 1718 1719/******************************************************************************* 1720** Function initialize_transaction 1721** 1722** Description Initializes fields of the transaction structure 1723** 1724** Returns void 1725*******************************************************************************/ 1726static void initialize_transaction(int lbl) 1727{ 1728 pthread_mutex_lock(&device.lbllock); 1729 if(lbl < MAX_TRANSACTIONS_PER_SESSION) 1730 { 1731 device.transaction[lbl].lbl = lbl; 1732 device.transaction[lbl].in_use=FALSE; 1733 device.transaction[lbl].handle=0; 1734 } 1735 pthread_mutex_unlock(&device.lbllock); 1736} 1737 1738/******************************************************************************* 1739** Function lbl_init 1740** 1741** Description Initializes label structures and mutexes. 1742** 1743** Returns void 1744*******************************************************************************/ 1745void lbl_init() 1746{ 1747 memset(&device,0,sizeof(rc_device_t)); 1748 pthread_mutexattr_t attr; 1749 pthread_mutexattr_init(&attr); 1750 pthread_mutex_init(&(device.lbllock), &attr); 1751 pthread_mutexattr_destroy(&attr); 1752 init_all_transactions(); 1753} 1754 1755/******************************************************************************* 1756** 1757** Function init_all_transactions 1758** 1759** Description Initializes all transactions 1760** 1761** Returns void 1762*******************************************************************************/ 1763void init_all_transactions() 1764{ 1765 UINT8 txn_indx=0; 1766 for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++) 1767 { 1768 initialize_transaction(txn_indx); 1769 } 1770} 1771 1772/******************************************************************************* 1773** 1774** Function get_transaction_by_lbl 1775** 1776** Description Will return a transaction based on the label. If not inuse 1777** will return an error. 1778** 1779** Returns bt_status_t 1780*******************************************************************************/ 1781rc_transaction_t *get_transaction_by_lbl(UINT8 lbl) 1782{ 1783 rc_transaction_t *transaction = NULL; 1784 pthread_mutex_lock(&device.lbllock); 1785 1786 /* Determine if this is a valid label */ 1787 if (lbl < MAX_TRANSACTIONS_PER_SESSION) 1788 { 1789 if (FALSE==device.transaction[lbl].in_use) 1790 { 1791 transaction = NULL; 1792 } 1793 else 1794 { 1795 transaction = &(device.transaction[lbl]); 1796 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl); 1797 } 1798 } 1799 1800 pthread_mutex_unlock(&device.lbllock); 1801 return transaction; 1802} 1803 1804/******************************************************************************* 1805** 1806** Function get_transaction 1807** 1808** Description Obtains the transaction details. 1809** 1810** Returns bt_status_t 1811*******************************************************************************/ 1812 1813bt_status_t get_transaction(rc_transaction_t **ptransaction) 1814{ 1815 bt_status_t result = BT_STATUS_NOMEM; 1816 UINT8 i=0; 1817 pthread_mutex_lock(&device.lbllock); 1818 1819 // Check for unused transactions 1820 for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++) 1821 { 1822 if (FALSE==device.transaction[i].in_use) 1823 { 1824 BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl); 1825 device.transaction[i].in_use = TRUE; 1826 *ptransaction = &(device.transaction[i]); 1827 result = BT_STATUS_SUCCESS; 1828 break; 1829 } 1830 } 1831 1832 pthread_mutex_unlock(&device.lbllock); 1833 return result; 1834} 1835 1836 1837/******************************************************************************* 1838** 1839** Function release_transaction 1840** 1841** Description Will release a transaction for reuse 1842** 1843** Returns bt_status_t 1844*******************************************************************************/ 1845void release_transaction(UINT8 lbl) 1846{ 1847 rc_transaction_t *transaction = get_transaction_by_lbl(lbl); 1848 1849 /* If the transaction is in use... */ 1850 if (transaction != NULL) 1851 { 1852 BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl); 1853 initialize_transaction(lbl); 1854 } 1855} 1856 1857/******************************************************************************* 1858** 1859** Function lbl_destroy 1860** 1861** Description Cleanup of the mutex 1862** 1863** Returns void 1864*******************************************************************************/ 1865void lbl_destroy() 1866{ 1867 pthread_mutex_destroy(&(device.lbllock)); 1868} 1869