btif_rc.c revision 98497a520010fc996a8ce490665cac6c1439dd2d
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_FAST_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 BTIF_TRACE_DEBUG2("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id); 368 369 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */ 370 if (p_remote_cmd) 371 { 372 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */ 373 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected())) 374 { 375 if (p_remote_cmd->key_state == AVRC_STATE_PRESS) 376 { 377 APPL_TRACE_WARNING1("%s: AVDT not open, queuing the PLAY command", __FUNCTION__); 378 btif_rc_cb.rc_pending_play = TRUE; 379 } 380 return; 381 } 382 383 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play)) 384 { 385 APPL_TRACE_WARNING1("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__); 386 btif_rc_cb.rc_pending_play = FALSE; 387 return; 388 } 389 } 390 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) { 391 status = "released"; 392 pressed = 0; 393 } else { 394 status = "pressed"; 395 pressed = 1; 396 } 397 398 /* If this is Play/Pause command (press or release) before processing, check the following 399 * a voice call has ended recently 400 * the remote device is not of type headset 401 * If the above conditions meet, drop the Play/Pause command 402 * This fix is to interop with certain carkits which sends an automatic PLAY or PAUSE 403 * commands right after call ends 404 */ 405 if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&& 406 (btif_hf_call_terminated_recently() == TRUE) && 407 (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE)) 408 { 409 BTIF_TRACE_DEBUG2("%s:Dropping the play/Pause command received right after call end cmd:%d", 410 __FUNCTION__,p_remote_cmd->rc_id); 411 return; 412 } 413 414 if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) { 415 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed); 416 return; 417 } 418 419 for (i = 0; key_map[i].name != NULL; i++) { 420 if (p_remote_cmd->rc_id == key_map[i].avrcp) { 421 BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status); 422 423 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button 424 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE 425 * comes 1 second after the press, the MediaPlayer UI goes into a bad state. 426 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc. 427 * The fix is to generate a release right after the press and drown the 'actual' 428 * release. 429 */ 430 if ((key_map[i].release_quirk == 1) && (pressed == 0)) 431 { 432 BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now", 433 __FUNCTION__, key_map[i].name); 434 return; 435 } 436 send_key(uinput_fd, key_map[i].mapped_id, pressed); 437 if ((key_map[i].release_quirk == 1) && (pressed == 1)) 438 { 439 GKI_delay(30); // 30ms 440 BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now", 441 __FUNCTION__, key_map[i].name); 442 send_key(uinput_fd, key_map[i].mapped_id, 0); 443 } 444 break; 445 } 446 } 447 448 if (key_map[i].name == NULL) 449 BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__, 450 p_remote_cmd->rc_id, status); 451} 452 453void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command) 454{ 455 tAVRC_RESPONSE avrc_rsp = {0}; 456 avrc_rsp.rsp.pdu = pavrc_command->pdu; 457 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR; 458 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode; 459 460 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id; 461 avrc_rsp.reg_notif.param.uid_counter = 0; 462 463 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp); 464 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp); 465 466} 467 468 469/*************************************************************************** 470 * Function handle_rc_metamsg_cmd 471 * 472 * - Argument: tBTA_AV_VENDOR Structure containing the received 473 * metamsg command 474 * 475 * - Description: Remote control metamsg command handler (AVRCP 1.3) 476 * 477 ***************************************************************************/ 478void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg) 479{ 480 /* Parse the metamsg command and pass it on to BTL-IFS */ 481 UINT8 scratch_buf[512] = {0}; 482 tAVRC_COMMAND avrc_command = {0}; 483 tAVRC_STS status; 484 int param_len; 485 486 BTIF_TRACE_EVENT1("+ %s", __FUNCTION__); 487 488 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR) 489 { 490 BTIF_TRACE_WARNING1("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode); 491 return; 492 } 493 if (pmeta_msg->len < 3) 494 { 495 BTIF_TRACE_WARNING2("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode, 496 pmeta_msg->len); 497 return; 498 } 499 500 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) 501 { 502 BTIF_TRACE_DEBUG3("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.", 503 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 504 return; 505 } 506 status = AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf)); 507 508 if (status != AVRC_STS_NO_ERROR) 509 { 510 /* return error */ 511 BTIF_TRACE_WARNING2("%s: Error in parsing received metamsg command. status: 0x%02x", 512 __FUNCTION__, status); 513 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status); 514 } 515 else 516 { 517 /* if RegisterNotification, add it to our registered queue */ 518 519 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) 520 { 521 UINT8 event_id = avrc_command.reg_notif.event_id; 522 param_len = sizeof(tAVRC_REG_NOTIF_CMD); 523 BTIF_TRACE_EVENT3("%s: New register notification received. event_id:%s, label:0x%x", 524 __FUNCTION__, dump_rc_notification_event_id(event_id), pmeta_msg->label); 525 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE; 526 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label; 527 528 if(event_id == AVRC_EVT_UIDS_CHANGE) 529 { 530 handle_uid_changed_notification(pmeta_msg, &avrc_command); 531 return; 532 } 533 534 } 535 536 BTIF_TRACE_EVENT2("%s: Passing received metamsg command to app. pdu: %s", 537 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu)); 538 539 /* Since handle_rc_metamsg_cmd() itself is called from 540 *btif context, no context switching is required. Invoke 541 * btif_rc_upstreams_evt directly from here. */ 542 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code, 543 pmeta_msg->label); 544 } 545} 546 547/*************************************************************************** 548 ** 549 ** Function btif_rc_handler 550 ** 551 ** Description RC event handler 552 ** 553 ***************************************************************************/ 554void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data) 555{ 556 BTIF_TRACE_DEBUG2 ("%s event:%s", __FUNCTION__, dump_rc_event(event)); 557 switch (event) 558 { 559 case BTA_AV_RC_OPEN_EVT: 560 { 561 BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_open.peer_features); 562 handle_rc_connect( &(p_data->rc_open) ); 563 }break; 564 565 case BTA_AV_RC_CLOSE_EVT: 566 { 567 handle_rc_disconnect( &(p_data->rc_close) ); 568 }break; 569 570 case BTA_AV_REMOTE_CMD_EVT: 571 { 572 BTIF_TRACE_DEBUG2("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id, 573 p_data->remote_cmd.key_state); 574 handle_rc_passthrough_cmd( (&p_data->remote_cmd) ); 575 } 576 break; 577 case BTA_AV_RC_FEAT_EVT: 578 { 579 BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_feat.peer_features); 580 btif_rc_cb.rc_features = p_data->rc_feat.peer_features; 581 /* TODO Handle RC_FEAT_EVT*/ 582 } 583 break; 584 case BTA_AV_META_MSG_EVT: 585 { 586 BTIF_TRACE_DEBUG2("BTA_AV_META_MSG_EVT code:%d label:%d", p_data->meta_msg.code, 587 p_data->meta_msg.label); 588 BTIF_TRACE_DEBUG3(" company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id, 589 p_data->meta_msg.len, p_data->meta_msg.rc_handle); 590 /* handle the metamsg command */ 591 handle_rc_metamsg_cmd(&(p_data->meta_msg)); 592 } 593 break; 594 default: 595 BTIF_TRACE_DEBUG1("Unhandled RC event : 0x%x", event); 596 } 597} 598 599/*************************************************************************** 600 ** 601 ** Function btif_rc_get_connected_peer 602 ** 603 ** Description Fetches the connected headset's BD_ADDR if any 604 ** 605 ***************************************************************************/ 606BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr) 607{ 608 if (btif_rc_cb.rc_connected == TRUE) { 609 bdcpy(peer_addr, btif_rc_cb.rc_addr); 610 return TRUE; 611 } 612 return FALSE; 613} 614 615/*************************************************************************** 616 ** 617 ** Function btif_rc_check_handle_pending_play 618 ** 619 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app 620 ** 621 ***************************************************************************/ 622 623/* clear the queued PLAY command. if bSend is TRUE, forward to app */ 624void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp) 625{ 626 BTIF_TRACE_DEBUG2("%s: bSendToApp=%d", __FUNCTION__, bSendToApp); 627 if (btif_rc_cb.rc_pending_play) 628 { 629 if (bSendToApp) 630 { 631 tBTA_AV_REMOTE_CMD remote_cmd; 632 APPL_TRACE_DEBUG1("%s: Sending queued PLAYED event to app", __FUNCTION__); 633 634 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); 635 remote_cmd.rc_handle = btif_rc_cb.rc_handle; 636 remote_cmd.rc_id = AVRC_ID_PLAY; 637 remote_cmd.hdr.ctype = AVRC_CMD_CTRL; 638 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU; 639 640 /* delay sending to app, else there is a timing issue in the framework, 641 ** which causes the audio to be on th device's speaker. Delay between 642 ** OPEN & RC_PLAYs 643 */ 644 GKI_delay (200); 645 /* send to app - both PRESSED & RELEASED */ 646 remote_cmd.key_state = AVRC_STATE_PRESS; 647 handle_rc_passthrough_cmd( &remote_cmd ); 648 649 GKI_delay (100); 650 651 remote_cmd.key_state = AVRC_STATE_RELEASE; 652 handle_rc_passthrough_cmd( &remote_cmd ); 653 } 654 btif_rc_cb.rc_pending_play = FALSE; 655 } 656} 657 658/* Generic reject response */ 659static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status) 660{ 661 UINT8 ctype = AVRC_RSP_REJ; 662 tAVRC_RESPONSE avrc_rsp; 663 BT_HDR *p_msg = NULL; 664 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 665 666 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu); 667 avrc_rsp.rsp.pdu = pdu; 668 avrc_rsp.rsp.status = status; 669 670 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) ) 671 { 672 BTIF_TRACE_DEBUG4("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x", 673 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status); 674 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 675 } 676} 677 678/*************************************************************************** 679 * Function send_metamsg_rsp 680 * 681 * - Argument: 682 * rc_handle RC handle corresponding to the connected RC 683 * label Label of the RC response 684 * code Response type 685 * pmetamsg_resp Vendor response 686 * 687 * - Description: Remote control metamsg response handler (AVRCP 1.3) 688 * 689 ***************************************************************************/ 690static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code, 691 tAVRC_RESPONSE *pmetamsg_resp) 692{ 693 UINT8 ctype; 694 tAVRC_STS status; 695 696 if (!pmetamsg_resp) 697 { 698 BTIF_TRACE_WARNING1("%s: Invalid response received from application", __FUNCTION__); 699 return; 700 } 701 702 BTIF_TRACE_EVENT5("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__, 703 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu)); 704 705 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR) 706 { 707 ctype = AVRC_RSP_REJ; 708 } 709 else 710 { 711 if ( code < AVRC_RSP_NOT_IMPL) 712 { 713 if (code == AVRC_CMD_NOTIF) 714 { 715 ctype = AVRC_RSP_INTERIM; 716 } 717 else if (code == AVRC_CMD_STATUS) 718 { 719 ctype = AVRC_RSP_IMPL_STBL; 720 } 721 else 722 { 723 ctype = AVRC_RSP_ACCEPT; 724 } 725 } 726 else 727 { 728 ctype = code; 729 } 730 } 731 /* if response is for register_notification, make sure the rc has 732 actually registered for this */ 733 if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED)) 734 { 735 BOOLEAN bSent = FALSE; 736 UINT8 event_id = pmetamsg_resp->reg_notif.event_id; 737 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify); 738 739 /* de-register this notification for a CHANGED response */ 740 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE; 741 BTIF_TRACE_DEBUG4("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__, 742 btif_rc_cb.rc_handle, event_id, bNotify); 743 if (bNotify) 744 { 745 BT_HDR *p_msg = NULL; 746 tAVRC_STS status; 747 748 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle, 749 pmetamsg_resp, &p_msg)) ) 750 { 751 BTIF_TRACE_DEBUG3("%s Sending notification to rc_handle: %d. event_id: 0x%02d", 752 __FUNCTION__, btif_rc_cb.rc_handle, event_id); 753 bSent = TRUE; 754 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 755 ctype, p_msg); 756 } 757 else 758 { 759 BTIF_TRACE_WARNING2("%s failed to build metamsg response. status: 0x%02x", 760 __FUNCTION__, status); 761 } 762 763 } 764 765 if (!bSent) 766 { 767 BTIF_TRACE_DEBUG2("%s: Notification not sent, as there are no RC connections or the \ 768 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 769 } 770 } 771 else 772 { 773 /* All other commands go here */ 774 775 BT_HDR *p_msg = NULL; 776 tAVRC_STS status; 777 778 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg); 779 780 if (status == AVRC_STS_NO_ERROR) 781 { 782 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 783 } 784 else 785 { 786 BTIF_TRACE_ERROR2("%s: failed to build metamsg response. status: 0x%02x", 787 __FUNCTION__, status); 788 } 789 } 790} 791 792static UINT8 opcode_from_pdu(UINT8 pdu) 793{ 794 UINT8 opcode = 0; 795 796 switch (pdu) 797 { 798 case AVRC_PDU_NEXT_GROUP: 799 case AVRC_PDU_PREV_GROUP: /* pass thru */ 800 opcode = AVRC_OP_PASS_THRU; 801 break; 802 803 default: /* vendor */ 804 opcode = AVRC_OP_VENDOR; 805 break; 806 } 807 808 return opcode; 809} 810 811/******************************************************************************* 812** 813** Function btif_rc_upstreams_evt 814** 815** Description Executes AVRC UPSTREAMS events in btif context. 816** 817** Returns void 818** 819*******************************************************************************/ 820static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label) 821{ 822 BTIF_TRACE_EVENT5("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__, 823 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label); 824 825 switch (event) 826 { 827 case AVRC_PDU_GET_PLAY_STATUS: 828 { 829 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE) 830 HAL_CBACK(bt_rc_callbacks, get_play_status_cb); 831 } 832 break; 833 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 834 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 835 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 836 case AVRC_PDU_SET_PLAYER_APP_VALUE: 837 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 838 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 839 { 840 /* TODO: Add support for Application Settings */ 841 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD); 842 } 843 break; 844 case AVRC_PDU_GET_ELEMENT_ATTR: 845 { 846 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 847 UINT8 num_attr; 848 memset(&element_attrs, 0, sizeof(element_attrs)); 849 if (pavrc_cmd->get_elem_attrs.num_attr == 0) 850 { 851 /* CT requests for all attributes */ 852 int attr_cnt; 853 num_attr = BTRC_MAX_ELEM_ATTR_SIZE; 854 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++) 855 { 856 element_attrs[attr_cnt] = attr_cnt + 1; 857 } 858 } 859 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF) 860 { 861 /* 0xff indicates, no attributes requested - reject */ 862 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 863 AVRC_STS_BAD_PARAM); 864 return; 865 } 866 else 867 { 868 num_attr = pavrc_cmd->get_elem_attrs.num_attr; 869 memcpy(element_attrs, pavrc_cmd->get_elem_attrs.attrs, sizeof(UINT32) 870 *pavrc_cmd->get_elem_attrs.num_attr); 871 } 872 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE); 873 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs); 874 } 875 break; 876 case AVRC_PDU_REGISTER_NOTIFICATION: 877 { 878 if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED && 879 pavrc_cmd->reg_notif.param == 0) 880 { 881 BTIF_TRACE_WARNING1("%s Device registering position changed with illegal param 0.", 882 __FUNCTION__); 883 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM); 884 /* de-register this notification for a rejected response */ 885 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE; 886 return; 887 } 888 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id, 889 pavrc_cmd->reg_notif.param); 890 } 891 break; 892 case AVRC_PDU_INFORM_DISPLAY_CHARSET: 893 { 894 tAVRC_RESPONSE avrc_rsp; 895 BTIF_TRACE_EVENT1("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__); 896 if(btif_rc_cb.rc_connected == TRUE) 897 { 898 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP)); 899 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET); 900 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET; 901 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR; 902 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp); 903 } 904 } 905 break; 906 default: 907 { 908 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 909 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD); 910 return; 911 } 912 break; 913 } 914 915} 916 917/************************************************************************************ 918** AVRCP API Functions 919************************************************************************************/ 920 921/******************************************************************************* 922** 923** Function init 924** 925** Description Initializes the AVRC interface 926** 927** Returns bt_status_t 928** 929*******************************************************************************/ 930static bt_status_t init(btrc_callbacks_t* callbacks ) 931{ 932 BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__); 933 bt_status_t result = BT_STATUS_SUCCESS; 934 935 if (bt_rc_callbacks) 936 return BT_STATUS_DONE; 937 938 bt_rc_callbacks = callbacks; 939 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb)); 940 941 return result; 942} 943 944/*************************************************************************** 945** 946** Function get_play_status_rsp 947** 948** Description Returns the current play status. 949** This method is called in response to 950** GetPlayStatus request. 951** 952** Returns bt_status_t 953** 954***************************************************************************/ 955static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len, 956 uint32_t song_pos) 957{ 958 tAVRC_RESPONSE avrc_rsp; 959 UINT32 i; 960 CHECK_RC_CONNECTED 961 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP)); 962 avrc_rsp.get_play_status.song_len = song_len; 963 avrc_rsp.get_play_status.song_pos = song_pos; 964 avrc_rsp.get_play_status.play_status = play_status; 965 966 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 967 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS); 968 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 969 /* Send the response */ 970 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp); 971 return BT_STATUS_SUCCESS; 972} 973 974/*************************************************************************** 975** 976** Function get_element_attr_rsp 977** 978** Description Returns the current songs' element attributes 979** in text. 980** 981** Returns bt_status_t 982** 983***************************************************************************/ 984static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs) 985{ 986 tAVRC_RESPONSE avrc_rsp; 987 UINT32 i; 988 uint8_t j; 989 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 990 CHECK_RC_CONNECTED 991 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); 992 993 if (num_attr == 0) 994 { 995 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM; 996 } 997 else 998 { 999 for (i=0; i<num_attr; i++) { 1000 element_attrs[i].attr_id = p_attrs[i].attr_id; 1001 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8; 1002 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text); 1003 element_attrs[i].name.p_str = p_attrs[i].text; 1004 BTIF_TRACE_DEBUG5("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s", 1005 __FUNCTION__, (unsigned int)element_attrs[i].attr_id, 1006 element_attrs[i].name.charset_id, element_attrs[i].name.str_len, 1007 element_attrs[i].name.p_str); 1008 } 1009 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1010 } 1011 avrc_rsp.get_elem_attrs.num_attr = num_attr; 1012 avrc_rsp.get_elem_attrs.p_attrs = element_attrs; 1013 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 1014 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR); 1015 /* Send the response */ 1016 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp); 1017 return BT_STATUS_SUCCESS; 1018} 1019 1020/*************************************************************************** 1021** 1022** Function register_notification_rsp 1023** 1024** Description Response to the register notification request. 1025** in text. 1026** 1027** Returns bt_status_t 1028** 1029***************************************************************************/ 1030static bt_status_t register_notification_rsp(btrc_event_id_t event_id, 1031 btrc_notification_type_t type, btrc_register_notification_t *p_param) 1032{ 1033 tAVRC_RESPONSE avrc_rsp; 1034 CHECK_RC_CONNECTED 1035 BTIF_TRACE_EVENT2("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 1036 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP)); 1037 avrc_rsp.reg_notif.event_id = event_id; 1038 1039 switch(event_id) 1040 { 1041 case BTRC_EVT_PLAY_STATUS_CHANGED: 1042 avrc_rsp.reg_notif.param.play_status = p_param->play_status; 1043 break; 1044 case BTRC_EVT_TRACK_CHANGE: 1045 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t)); 1046 break; 1047 case BTRC_EVT_PLAY_POS_CHANGED: 1048 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos; 1049 break; 1050 default: 1051 BTIF_TRACE_WARNING2("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id); 1052 return BT_STATUS_UNHANDLED; 1053 } 1054 1055 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1056 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION); 1057 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1058 1059 /* Send the response. */ 1060 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 1061 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp); 1062 return BT_STATUS_SUCCESS; 1063} 1064 1065/*************************************************************************** 1066** 1067** Function cleanup 1068** 1069** Description Closes the AVRC interface 1070** 1071** Returns void 1072** 1073***************************************************************************/ 1074static void cleanup() 1075{ 1076 BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__); 1077 close_uinput(); 1078 if (bt_rc_callbacks) 1079 { 1080 bt_rc_callbacks = NULL; 1081 } 1082 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t)); 1083} 1084 1085 1086static const btrc_interface_t bt_rc_interface = { 1087 sizeof(bt_rc_interface), 1088 init, 1089 get_play_status_rsp, 1090 NULL, /* list_player_app_attr_rsp */ 1091 NULL, /* list_player_app_value_rsp */ 1092 NULL, /* get_player_app_value_rsp */ 1093 NULL, /* get_player_app_attr_text_rsp */ 1094 NULL, /* get_player_app_value_text_rsp */ 1095 get_element_attr_rsp, 1096 NULL, /* set_player_app_value_rsp */ 1097 register_notification_rsp, 1098 cleanup, 1099}; 1100 1101/******************************************************************************* 1102** 1103** Function btif_rc_get_interface 1104** 1105** Description Get the AVRCP callback interface 1106** 1107** Returns btav_interface_t 1108** 1109*******************************************************************************/ 1110const btrc_interface_t *btif_rc_get_interface(void) 1111{ 1112 BTIF_TRACE_EVENT1("%s", __FUNCTION__); 1113 return &bt_rc_interface; 1114}