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