btif_rc.c revision b88fc6cb5636c4af17077502fe3313ffb32d93ee
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 "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 60#define MAX_CMD_QUEUE_LEN 8 61 62#define CHECK_RC_CONNECTED \ 63 BTIF_TRACE_DEBUG1("## %s ##", __FUNCTION__); \ 64 if(btif_rc_cb.rc_connected == FALSE) \ 65 { \ 66 BTIF_TRACE_WARNING1("Function %s() called when RC is not connected", __FUNCTION__); \ 67 return BT_STATUS_NOT_READY; \ 68 } 69 70#define FILL_PDU_QUEUE(index, ctype, label, pending) \ 71{ \ 72 btif_rc_cb.rc_pdu_info[index].ctype = ctype; \ 73 btif_rc_cb.rc_pdu_info[index].label = label; \ 74 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \ 75} 76 77#define SEND_METAMSG_RSP(index, avrc_rsp) \ 78{ \ 79 if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \ 80 { \ 81 BTIF_TRACE_WARNING1("%s Not sending response as no PDU was registered", __FUNCTION__); \ 82 return BT_STATUS_UNHANDLED; \ 83 } \ 84 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \ 85 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \ 86 btif_rc_cb.rc_pdu_info[index].ctype = 0; \ 87 btif_rc_cb.rc_pdu_info[index].label = 0; \ 88 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \ 89} 90 91/***************************************************************************** 92** Local type definitions 93******************************************************************************/ 94typedef struct { 95 UINT8 bNotify; 96 UINT8 label; 97} btif_rc_reg_notifications_t; 98 99typedef struct 100{ 101 UINT8 label; 102 UINT8 ctype; 103 BOOLEAN is_rsp_pending; 104} btif_rc_cmd_ctxt_t; 105 106/* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */ 107typedef struct { 108 BOOLEAN rc_connected; 109 UINT8 rc_handle; 110 tBTA_AV_FEAT rc_features; 111 BD_ADDR rc_addr; 112 UINT16 rc_pending_play; 113 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN]; 114 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS]; 115} btif_rc_cb_t; 116 117#define MAX_UINPUT_PATHS 3 118static const char* uinput_dev_path[] = 119 {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" }; 120static int uinput_fd = -1; 121 122static int send_event (int fd, uint16_t type, uint16_t code, int32_t value); 123static void send_key (int fd, uint16_t key, int pressed); 124static int uinput_driver_check(); 125static int uinput_create(char *name); 126static int init_uinput (void); 127static void close_uinput (void); 128 129static const struct { 130 const char *name; 131 uint8_t avrcp; 132 uint16_t mapped_id; 133 uint8_t release_quirk; 134} key_map[] = { 135 { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 }, 136 { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 }, 137 { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 }, 138 { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 }, 139 { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 }, 140 { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 }, 141 { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FORWARD, 0 }, 142 { NULL, 0, 0, 0 } 143}; 144 145static void send_reject_response (UINT8 rc_handle, UINT8 label, 146 UINT8 pdu, UINT8 status); 147static UINT8 opcode_from_pdu(UINT8 pdu); 148static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, 149 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp); 150static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label); 151 152/***************************************************************************** 153** Static variables 154******************************************************************************/ 155static btif_rc_cb_t btif_rc_cb; 156static btrc_callbacks_t *bt_rc_callbacks = NULL; 157 158/***************************************************************************** 159** Static functions 160******************************************************************************/ 161 162/***************************************************************************** 163** Externs 164******************************************************************************/ 165extern BOOLEAN btif_hf_call_terminated_recently(); 166extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod); 167 168 169/***************************************************************************** 170** Functions 171******************************************************************************/ 172 173/***************************************************************************** 174** Local uinput helper functions 175******************************************************************************/ 176int send_event (int fd, uint16_t type, uint16_t code, int32_t value) 177{ 178 struct uinput_event event; 179 BTIF_TRACE_DEBUG4("%s type:%u code:%u value:%d", __FUNCTION__, 180 type, code, value); 181 memset(&event, 0, sizeof(event)); 182 event.type = type; 183 event.code = code; 184 event.value = value; 185 186 return write(fd, &event, sizeof(event)); 187} 188 189void send_key (int fd, uint16_t key, int pressed) 190{ 191 BTIF_TRACE_DEBUG4("%s fd:%d key:%u pressed:%d", __FUNCTION__, 192 fd, key, pressed); 193 194 if (fd < 0) 195 { 196 return; 197 } 198 199 BTIF_TRACE_DEBUG3("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd); 200 send_event(fd, EV_KEY, key, pressed); 201 send_event(fd, EV_SYN, SYN_REPORT, 0); 202} 203 204/************** uinput related functions **************/ 205int uinput_driver_check() 206{ 207 uint32_t i; 208 for (i=0; i < MAX_UINPUT_PATHS; i++) 209 { 210 if (access(uinput_dev_path[i], O_RDWR) == 0) { 211 return 0; 212 } 213 } 214 BTIF_TRACE_ERROR1("%s ERROR: uinput device is not in the system", __FUNCTION__); 215 return -1; 216} 217 218int uinput_create(char *name) 219{ 220 struct uinput_dev dev; 221 int fd, err, x = 0; 222 223 for(x=0; x < MAX_UINPUT_PATHS; x++) 224 { 225 fd = open(uinput_dev_path[x], O_RDWR); 226 if (fd < 0) 227 continue; 228 break; 229 } 230 if (x == MAX_UINPUT_PATHS) { 231 BTIF_TRACE_ERROR1("%s ERROR: uinput device open failed", __FUNCTION__); 232 return -1; 233 } 234 memset(&dev, 0, sizeof(dev)); 235 if (name) 236 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE); 237 238 dev.id.bustype = BUS_BLUETOOTH; 239 dev.id.vendor = 0x0000; 240 dev.id.product = 0x0000; 241 dev.id.version = 0x0000; 242 243 if (write(fd, &dev, sizeof(dev)) < 0) { 244 BTIF_TRACE_ERROR1("%s Unable to write device information", __FUNCTION__); 245 close(fd); 246 return -1; 247 } 248 249 ioctl(fd, UI_SET_EVBIT, EV_KEY); 250 ioctl(fd, UI_SET_EVBIT, EV_REL); 251 ioctl(fd, UI_SET_EVBIT, EV_SYN); 252 253 for (x = 0; key_map[x].name != NULL; x++) 254 ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id); 255 256 for(x = 0; x < KEY_MAX; x++) 257 ioctl(fd, UI_SET_KEYBIT, x); 258 259 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) { 260 BTIF_TRACE_ERROR1("%s Unable to create uinput device", __FUNCTION__); 261 close(fd); 262 return -1; 263 } 264 return fd; 265} 266 267int init_uinput (void) 268{ 269 char *name = "AVRCP"; 270 271 BTIF_TRACE_DEBUG1("%s", __FUNCTION__); 272 uinput_fd = uinput_create(name); 273 if (uinput_fd < 0) { 274 BTIF_TRACE_ERROR3("%s AVRCP: Failed to initialize uinput for %s (%d)", 275 __FUNCTION__, name, uinput_fd); 276 } else { 277 BTIF_TRACE_DEBUG3("%s AVRCP: Initialized uinput for %s (fd=%d)", 278 __FUNCTION__, name, uinput_fd); 279 } 280 return uinput_fd; 281} 282 283void close_uinput (void) 284{ 285 BTIF_TRACE_DEBUG1("%s", __FUNCTION__); 286 if (uinput_fd > 0) { 287 ioctl(uinput_fd, UI_DEV_DESTROY); 288 289 close(uinput_fd); 290 uinput_fd = -1; 291 } 292} 293 294 295 296 297/*************************************************************************** 298 * Function handle_rc_connect 299 * 300 * - Argument: tBTA_AV_RC_OPEN RC open data structure 301 * 302 * - Description: RC connection event handler 303 * 304 ***************************************************************************/ 305void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) 306{ 307 BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle); 308 bt_status_t result = BT_STATUS_SUCCESS; 309 int i; 310 char bd_str[18]; 311 312 if(p_rc_open->status == BTA_AV_SUCCESS) 313 { 314 memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR)); 315 btif_rc_cb.rc_features = p_rc_open->peer_features; 316 317 btif_rc_cb.rc_connected = TRUE; 318 btif_rc_cb.rc_handle = p_rc_open->rc_handle; 319 320 result = uinput_driver_check(); 321 if(result == BT_STATUS_SUCCESS) 322 { 323 init_uinput(); 324 } 325 } 326 else 327 { 328 BTIF_TRACE_ERROR2("%s Connect failed with error code: %d", 329 __FUNCTION__, p_rc_open->status); 330 btif_rc_cb.rc_connected = FALSE; 331 } 332} 333 334/*************************************************************************** 335 * Function handle_rc_disconnect 336 * 337 * - Argument: tBTA_AV_RC_CLOSE RC close data structure 338 * 339 * - Description: RC disconnection event handler 340 * 341 ***************************************************************************/ 342void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close) 343{ 344 BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle); 345 346 btif_rc_cb.rc_handle = 0; 347 btif_rc_cb.rc_connected = FALSE; 348 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR)); 349 btif_rc_cb.rc_features = 0; 350 close_uinput(); 351} 352 353/*************************************************************************** 354 * Function handle_rc_passthrough_cmd 355 * 356 * - Argument: tBTA_AV_RC rc_id remote control command ID 357 * tBTA_AV_STATE key_state status of key press 358 * 359 * - Description: Remote control command handler 360 * 361 ***************************************************************************/ 362void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd) 363{ 364 const char *status; 365 int pressed, i; 366 367 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */ 368 if (p_remote_cmd) 369 { 370 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */ 371 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected())) 372 { 373 if (p_remote_cmd->key_state == AVRC_STATE_PRESS) 374 { 375 APPL_TRACE_WARNING1("%s: AVDT not open, queuing the PLAY command", __FUNCTION__); 376 btif_rc_cb.rc_pending_play = TRUE; 377 } 378 return; 379 } 380 381 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play)) 382 { 383 APPL_TRACE_WARNING1("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__); 384 btif_rc_cb.rc_pending_play = FALSE; 385 return; 386 } 387 } 388 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) { 389 status = "released"; 390 pressed = 0; 391 } else { 392 status = "pressed"; 393 pressed = 1; 394 } 395 396 /* If this is Play/Pause command (press or release) before processing, check the following 397 * a voice call has ended recently 398 * the remote device is not of type headset 399 * If the above conditions meet, drop the Play/Pause command 400 * This fix is to interop with certain carkits which sends an automatic PLAY or PAUSE 401 * commands right after call ends 402 */ 403 if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&& 404 (btif_hf_call_terminated_recently() == TRUE) && 405 (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE)) 406 { 407 BTIF_TRACE_DEBUG2("%s:Dropping the play/Pause command received right after call end cmd:%d", 408 __FUNCTION__,p_remote_cmd->rc_id); 409 return; 410 } 411 412 for (i = 0; key_map[i].name != NULL; i++) { 413 if (p_remote_cmd->rc_id == key_map[i].avrcp) { 414 BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status); 415 416 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button 417 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE 418 * comes 1 second after the press, the MediaPlayer UI goes into a bad state. 419 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc. 420 * The fix is to generate a release right after the press and drown the 'actual' 421 * release. 422 */ 423 if ((key_map[i].release_quirk == 1) && (pressed == 0)) 424 { 425 BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now", 426 __FUNCTION__, key_map[i].name); 427 return; 428 } 429 send_key(uinput_fd, key_map[i].mapped_id, pressed); 430 if ((key_map[i].release_quirk == 1) && (pressed == 1)) 431 { 432 GKI_delay(30); // 30ms 433 BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now", 434 __FUNCTION__, key_map[i].name); 435 send_key(uinput_fd, key_map[i].mapped_id, 0); 436 } 437 break; 438 } 439 } 440 441 if (key_map[i].name == NULL) 442 BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__, 443 p_remote_cmd->rc_id, status); 444} 445 446void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command) 447{ 448 tAVRC_RESPONSE avrc_rsp = {0}; 449 avrc_rsp.rsp.pdu = pavrc_command->pdu; 450 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR; 451 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode; 452 453 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id; 454 avrc_rsp.reg_notif.param.uid_counter = 0; 455 456 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp); 457 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp); 458 459} 460 461 462/*************************************************************************** 463 * Function handle_rc_metamsg_cmd 464 * 465 * - Argument: tBTA_AV_VENDOR Structure containing the received 466 * metamsg command 467 * 468 * - Description: Remote control metamsg command handler (AVRCP 1.3) 469 * 470 ***************************************************************************/ 471void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg) 472{ 473 /* Parse the metamsg command and pass it on to BTL-IFS */ 474 UINT8 scratch_buf[512] = {0}; 475 tAVRC_COMMAND avrc_command = {0}; 476 tAVRC_STS status; 477 int param_len; 478 479 BTIF_TRACE_EVENT1("+ %s", __FUNCTION__); 480 481 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR) 482 { 483 BTIF_TRACE_WARNING1("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode); 484 return; 485 } 486 if (pmeta_msg->len < 3) 487 { 488 BTIF_TRACE_WARNING2("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode, 489 pmeta_msg->len); 490 return; 491 } 492 493 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) 494 { 495 BTIF_TRACE_DEBUG3("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.", 496 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 497 return; 498 } 499 status = AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf)); 500 501 if (status != AVRC_STS_NO_ERROR) 502 { 503 /* return error */ 504 BTIF_TRACE_WARNING2("%s: Error in parsing received metamsg command. status: 0x%02x", 505 __FUNCTION__, status); 506 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status); 507 } 508 else 509 { 510 /* if RegisterNotification, add it to our registered queue */ 511 512 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) 513 { 514 UINT8 event_id = avrc_command.reg_notif.event_id; 515 param_len = sizeof(tAVRC_REG_NOTIF_CMD); 516 BTIF_TRACE_EVENT3("%s: New register notification received. event_id:%s, label:0x%x", 517 __FUNCTION__, dump_rc_notification_event_id(event_id), pmeta_msg->label); 518 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE; 519 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label; 520 521 if(event_id == AVRC_EVT_UIDS_CHANGE) 522 { 523 handle_uid_changed_notification(pmeta_msg, &avrc_command); 524 return; 525 } 526 527 } 528 529 BTIF_TRACE_EVENT2("%s: Passing received metamsg command to app. pdu: %s", 530 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu)); 531 532 /* Since handle_rc_metamsg_cmd() itself is called from 533 *btif context, no context switching is required. Invoke 534 * btif_rc_upstreams_evt directly from here. */ 535 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code, 536 pmeta_msg->label); 537 } 538} 539 540/*************************************************************************** 541 ** 542 ** Function btif_rc_handler 543 ** 544 ** Description RC event handler 545 ** 546 ***************************************************************************/ 547void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data) 548{ 549 BTIF_TRACE_DEBUG2 ("%s event:%s", __FUNCTION__, dump_rc_event(event)); 550 switch (event) 551 { 552 case BTA_AV_RC_OPEN_EVT: 553 { 554 BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_open.peer_features); 555 handle_rc_connect( &(p_data->rc_open) ); 556 }break; 557 558 case BTA_AV_RC_CLOSE_EVT: 559 { 560 handle_rc_disconnect( &(p_data->rc_close) ); 561 }break; 562 563 case BTA_AV_REMOTE_CMD_EVT: 564 { 565 BTIF_TRACE_DEBUG2("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id, 566 p_data->remote_cmd.key_state); 567 handle_rc_passthrough_cmd( (&p_data->remote_cmd) ); 568 } 569 break; 570 case BTA_AV_RC_FEAT_EVT: 571 { 572 BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_feat.peer_features); 573 btif_rc_cb.rc_features = p_data->rc_feat.peer_features; 574 /* TODO Handle RC_FEAT_EVT*/ 575 } 576 break; 577 case BTA_AV_META_MSG_EVT: 578 { 579 BTIF_TRACE_DEBUG2("BTA_AV_META_MSG_EVT code:%d label:%d", p_data->meta_msg.code, 580 p_data->meta_msg.label); 581 BTIF_TRACE_DEBUG3(" company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id, 582 p_data->meta_msg.len, p_data->meta_msg.rc_handle); 583 /* handle the metamsg command */ 584 handle_rc_metamsg_cmd(&(p_data->meta_msg)); 585 } 586 break; 587 default: 588 BTIF_TRACE_DEBUG1("Unhandled RC event : 0x%x", event); 589 } 590} 591 592/*************************************************************************** 593 ** 594 ** Function btif_rc_get_connected_peer 595 ** 596 ** Description Fetches the connected headset's BD_ADDR if any 597 ** 598 ***************************************************************************/ 599BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr) 600{ 601 if (btif_rc_cb.rc_connected == TRUE) { 602 bdcpy(peer_addr, btif_rc_cb.rc_addr); 603 return TRUE; 604 } 605 return FALSE; 606} 607 608/*************************************************************************** 609 ** 610 ** Function btif_rc_check_handle_pending_play 611 ** 612 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app 613 ** 614 ***************************************************************************/ 615 616/* clear the queued PLAY command. if bSend is TRUE, forward to app */ 617void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp) 618{ 619 BTIF_TRACE_DEBUG2("%s: bSendToApp=%d", __FUNCTION__, bSendToApp); 620 if (btif_rc_cb.rc_pending_play) 621 { 622 if (bSendToApp) 623 { 624 tBTA_AV_REMOTE_CMD remote_cmd; 625 APPL_TRACE_DEBUG1("%s: Sending queued PLAYED event to app", __FUNCTION__); 626 627 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); 628 remote_cmd.rc_handle = btif_rc_cb.rc_handle; 629 remote_cmd.rc_id = AVRC_ID_PLAY; 630 remote_cmd.hdr.ctype = AVRC_CMD_CTRL; 631 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU; 632 633 /* delay sending to app, else there is a timing issue in the framework, 634 ** which causes the audio to be on th device's speaker. Delay between 635 ** OPEN & RC_PLAYs 636 */ 637 GKI_delay (200); 638 /* send to app - both PRESSED & RELEASED */ 639 remote_cmd.key_state = AVRC_STATE_PRESS; 640 handle_rc_passthrough_cmd( &remote_cmd ); 641 642 GKI_delay (100); 643 644 remote_cmd.key_state = AVRC_STATE_RELEASE; 645 handle_rc_passthrough_cmd( &remote_cmd ); 646 } 647 btif_rc_cb.rc_pending_play = FALSE; 648 } 649} 650 651/* Generic reject response */ 652static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status) 653{ 654 UINT8 ctype = AVRC_RSP_REJ; 655 tAVRC_RESPONSE avrc_rsp; 656 BT_HDR *p_msg = NULL; 657 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 658 659 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu); 660 avrc_rsp.rsp.pdu = pdu; 661 avrc_rsp.rsp.status = status; 662 663 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) ) 664 { 665 BTIF_TRACE_DEBUG4("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x", 666 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status); 667 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 668 } 669} 670 671/*************************************************************************** 672 * Function send_metamsg_rsp 673 * 674 * - Argument: 675 * rc_handle RC handle corresponding to the connected RC 676 * label Label of the RC response 677 * code Response type 678 * pmetamsg_resp Vendor response 679 * 680 * - Description: Remote control metamsg response handler (AVRCP 1.3) 681 * 682 ***************************************************************************/ 683static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code, 684 tAVRC_RESPONSE *pmetamsg_resp) 685{ 686 UINT8 ctype; 687 tAVRC_STS status; 688 689 if (!pmetamsg_resp) 690 { 691 BTIF_TRACE_WARNING1("%s: Invalid response received from application", __FUNCTION__); 692 return; 693 } 694 695 BTIF_TRACE_EVENT5("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__, 696 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu)); 697 698 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR) 699 { 700 ctype = AVRC_RSP_REJ; 701 } 702 else 703 { 704 if ( code < AVRC_RSP_NOT_IMPL) 705 { 706 if (code == AVRC_CMD_NOTIF) 707 { 708 ctype = AVRC_RSP_INTERIM; 709 } 710 else if (code == AVRC_CMD_STATUS) 711 { 712 ctype = AVRC_RSP_IMPL_STBL; 713 } 714 else 715 { 716 ctype = AVRC_RSP_ACCEPT; 717 } 718 } 719 else 720 { 721 ctype = code; 722 } 723 } 724 /* if response is for register_notification, make sure the rc has 725 actually registered for this */ 726 if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED)) 727 { 728 BOOLEAN bSent = FALSE; 729 UINT8 event_id = pmetamsg_resp->reg_notif.event_id; 730 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify); 731 732 /* de-register this notification for a CHANGED response */ 733 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE; 734 BTIF_TRACE_DEBUG4("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__, 735 btif_rc_cb.rc_handle, event_id, bNotify); 736 if (bNotify) 737 { 738 BT_HDR *p_msg = NULL; 739 tAVRC_STS status; 740 741 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle, 742 pmetamsg_resp, &p_msg)) ) 743 { 744 BTIF_TRACE_DEBUG3("%s Sending notification to rc_handle: %d. event_id: 0x%02d", 745 __FUNCTION__, btif_rc_cb.rc_handle, event_id); 746 bSent = TRUE; 747 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 748 ctype, p_msg); 749 } 750 else 751 { 752 BTIF_TRACE_WARNING2("%s failed to build metamsg response. status: 0x%02x", 753 __FUNCTION__, status); 754 } 755 756 } 757 758 if (!bSent) 759 { 760 BTIF_TRACE_DEBUG2("%s: Notification not sent, as there are no RC connections or the \ 761 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 762 } 763 } 764 else 765 { 766 /* All other commands go here */ 767 768 BT_HDR *p_msg = NULL; 769 tAVRC_STS status; 770 771 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg); 772 773 if (status == AVRC_STS_NO_ERROR) 774 { 775 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 776 } 777 else 778 { 779 BTIF_TRACE_ERROR2("%s: failed to build metamsg response. status: 0x%02x", 780 __FUNCTION__, status); 781 } 782 } 783} 784 785static UINT8 opcode_from_pdu(UINT8 pdu) 786{ 787 UINT8 opcode = 0; 788 789 switch (pdu) 790 { 791 case AVRC_PDU_NEXT_GROUP: 792 case AVRC_PDU_PREV_GROUP: /* pass thru */ 793 opcode = AVRC_OP_PASS_THRU; 794 break; 795 796 default: /* vendor */ 797 opcode = AVRC_OP_VENDOR; 798 break; 799 } 800 801 return opcode; 802} 803 804/******************************************************************************* 805** 806** Function btif_rc_upstreams_evt 807** 808** Description Executes AVRC UPSTREAMS events in btif context. 809** 810** Returns void 811** 812*******************************************************************************/ 813static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label) 814{ 815 BTIF_TRACE_EVENT5("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__, 816 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label); 817 818 switch (event) 819 { 820 case AVRC_PDU_GET_PLAY_STATUS: 821 { 822 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE) 823 HAL_CBACK(bt_rc_callbacks, get_play_status_cb); 824 } 825 break; 826 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 827 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 828 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 829 case AVRC_PDU_SET_PLAYER_APP_VALUE: 830 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 831 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 832 { 833 /* TODO: Add support for Application Settings */ 834 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD); 835 } 836 break; 837 case AVRC_PDU_GET_ELEMENT_ATTR: 838 { 839 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 840 UINT8 num_attr; 841 memset(&element_attrs, 0, sizeof(element_attrs)); 842 if (pavrc_cmd->get_elem_attrs.num_attr == 0) 843 { 844 /* CT requests for all attributes */ 845 int attr_cnt; 846 num_attr = BTRC_MAX_ELEM_ATTR_SIZE; 847 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++) 848 { 849 element_attrs[attr_cnt] = attr_cnt + 1; 850 } 851 } 852 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF) 853 { 854 /* 0xff indicates, no attributes requested - reject */ 855 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 856 AVRC_STS_BAD_PARAM); 857 return; 858 } 859 else 860 { 861 num_attr = pavrc_cmd->get_elem_attrs.num_attr; 862 memcpy(element_attrs, pavrc_cmd->get_elem_attrs.attrs, sizeof(UINT32) 863 *pavrc_cmd->get_elem_attrs.num_attr); 864 } 865 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE); 866 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs); 867 } 868 break; 869 case AVRC_PDU_REGISTER_NOTIFICATION: 870 { 871 if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED && 872 pavrc_cmd->reg_notif.param == 0) 873 { 874 BTIF_TRACE_WARNING1("%s Device registering position changed with illegal param 0.", 875 __FUNCTION__); 876 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM); 877 /* de-register this notification for a rejected response */ 878 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE; 879 return; 880 } 881 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id, 882 pavrc_cmd->reg_notif.param); 883 } 884 break; 885 case AVRC_PDU_INFORM_DISPLAY_CHARSET: 886 { 887 tAVRC_RESPONSE avrc_rsp; 888 BTIF_TRACE_EVENT1("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__); 889 if(btif_rc_cb.rc_connected == TRUE) 890 { 891 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP)); 892 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET); 893 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET; 894 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR; 895 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp); 896 } 897 } 898 break; 899 default: 900 { 901 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 902 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD); 903 return; 904 } 905 break; 906 } 907 908} 909 910/************************************************************************************ 911** AVRCP API Functions 912************************************************************************************/ 913 914/******************************************************************************* 915** 916** Function init 917** 918** Description Initializes the AVRC interface 919** 920** Returns bt_status_t 921** 922*******************************************************************************/ 923static bt_status_t init(btrc_callbacks_t* callbacks ) 924{ 925 BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__); 926 bt_status_t result = BT_STATUS_SUCCESS; 927 928 if (bt_rc_callbacks) 929 return BT_STATUS_DONE; 930 931 bt_rc_callbacks = callbacks; 932 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb)); 933 934 return result; 935} 936 937/*************************************************************************** 938** 939** Function get_play_status_rsp 940** 941** Description Returns the current play status. 942** This method is called in response to 943** GetPlayStatus request. 944** 945** Returns bt_status_t 946** 947***************************************************************************/ 948static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len, 949 uint32_t song_pos) 950{ 951 tAVRC_RESPONSE avrc_rsp; 952 UINT32 i; 953 CHECK_RC_CONNECTED 954 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP)); 955 avrc_rsp.get_play_status.song_len = song_len; 956 avrc_rsp.get_play_status.song_pos = song_pos; 957 avrc_rsp.get_play_status.play_status = play_status; 958 959 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 960 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS); 961 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 962 /* Send the response */ 963 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp); 964 return BT_STATUS_SUCCESS; 965} 966 967/*************************************************************************** 968** 969** Function get_element_attr_rsp 970** 971** Description Returns the current songs' element attributes 972** in text. 973** 974** Returns bt_status_t 975** 976***************************************************************************/ 977static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs) 978{ 979 tAVRC_RESPONSE avrc_rsp; 980 UINT32 i; 981 uint8_t j; 982 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 983 CHECK_RC_CONNECTED 984 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); 985 986 if (num_attr == 0) 987 { 988 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM; 989 } 990 else 991 { 992 for (i=0; i<num_attr; i++) { 993 element_attrs[i].attr_id = p_attrs[i].attr_id; 994 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8; 995 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text); 996 element_attrs[i].name.p_str = p_attrs[i].text; 997 BTIF_TRACE_DEBUG5("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s", 998 __FUNCTION__, (unsigned int)element_attrs[i].attr_id, 999 element_attrs[i].name.charset_id, element_attrs[i].name.str_len, 1000 element_attrs[i].name.p_str); 1001 } 1002 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1003 } 1004 avrc_rsp.get_elem_attrs.num_attr = num_attr; 1005 avrc_rsp.get_elem_attrs.p_attrs = element_attrs; 1006 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 1007 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR); 1008 /* Send the response */ 1009 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp); 1010 return BT_STATUS_SUCCESS; 1011} 1012 1013/*************************************************************************** 1014** 1015** Function register_notification_rsp 1016** 1017** Description Response to the register notification request. 1018** in text. 1019** 1020** Returns bt_status_t 1021** 1022***************************************************************************/ 1023static bt_status_t register_notification_rsp(btrc_event_id_t event_id, 1024 btrc_notification_type_t type, btrc_register_notification_t *p_param) 1025{ 1026 tAVRC_RESPONSE avrc_rsp; 1027 CHECK_RC_CONNECTED 1028 BTIF_TRACE_EVENT2("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 1029 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP)); 1030 avrc_rsp.reg_notif.event_id = event_id; 1031 1032 switch(event_id) 1033 { 1034 case BTRC_EVT_PLAY_STATUS_CHANGED: 1035 avrc_rsp.reg_notif.param.play_status = p_param->play_status; 1036 break; 1037 case BTRC_EVT_TRACK_CHANGE: 1038 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t)); 1039 break; 1040 case BTRC_EVT_PLAY_POS_CHANGED: 1041 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos; 1042 break; 1043 default: 1044 BTIF_TRACE_WARNING2("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id); 1045 return BT_STATUS_UNHANDLED; 1046 } 1047 1048 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1049 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION); 1050 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1051 1052 /* Send the response. */ 1053 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 1054 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp); 1055 return BT_STATUS_SUCCESS; 1056} 1057 1058/*************************************************************************** 1059** 1060** Function cleanup 1061** 1062** Description Closes the AVRC interface 1063** 1064** Returns void 1065** 1066***************************************************************************/ 1067static void cleanup() 1068{ 1069 BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__); 1070 close_uinput(); 1071 if (bt_rc_callbacks) 1072 { 1073 bt_rc_callbacks = NULL; 1074 } 1075 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t)); 1076} 1077 1078 1079static const btrc_interface_t bt_rc_interface = { 1080 sizeof(bt_rc_interface), 1081 init, 1082 get_play_status_rsp, 1083 NULL, /* list_player_app_attr_rsp */ 1084 NULL, /* list_player_app_value_rsp */ 1085 NULL, /* get_player_app_value_rsp */ 1086 NULL, /* get_player_app_attr_text_rsp */ 1087 NULL, /* get_player_app_value_text_rsp */ 1088 get_element_attr_rsp, 1089 NULL, /* set_player_app_value_rsp */ 1090 register_notification_rsp, 1091 cleanup, 1092}; 1093 1094/******************************************************************************* 1095** 1096** Function btif_rc_get_interface 1097** 1098** Description Get the AVRCP callback interface 1099** 1100** Returns btav_interface_t 1101** 1102*******************************************************************************/ 1103const btrc_interface_t *btif_rc_get_interface(void) 1104{ 1105 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1106 return &bt_rc_interface; 1107} 1108