1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /***************************************************************************** 18 * 19 * Filename: btif_rc.c 20 * 21 * Description: Bluetooth AVRC implementation 22 * 23 *****************************************************************************/ 24 25 #define LOG_TAG "bt_btif_avrc" 26 27 #include <errno.h> 28 #include <fcntl.h> 29 #include <pthread.h> 30 #include <string.h> 31 #include <time.h> 32 #include <unistd.h> 33 34 #include <hardware/bluetooth.h> 35 #include <hardware/bt_rc.h> 36 37 #include "avrc_defs.h" 38 #include "bta_api.h" 39 #include "bta_av_api.h" 40 #include "btif_av.h" 41 #include "btif_common.h" 42 #include "btif_util.h" 43 #include "bt_common.h" 44 #include "device/include/interop.h" 45 #include "uinput.h" 46 #include "bdaddr.h" 47 #include "osi/include/list.h" 48 #include "osi/include/properties.h" 49 #include "btu.h" 50 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL) 51 52 /***************************************************************************** 53 ** Constants & Macros 54 ******************************************************************************/ 55 56 /* cod value for Headsets */ 57 #define COD_AV_HEADSETS 0x0404 58 /* for AVRC 1.4 need to change this */ 59 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE 60 61 #define IDX_GET_PLAY_STATUS_RSP 0 62 #define IDX_LIST_APP_ATTR_RSP 1 63 #define IDX_LIST_APP_VALUE_RSP 2 64 #define IDX_GET_CURR_APP_VAL_RSP 3 65 #define IDX_SET_APP_VAL_RSP 4 66 #define IDX_GET_APP_ATTR_TXT_RSP 5 67 #define IDX_GET_APP_VAL_TXT_RSP 6 68 #define IDX_GET_ELEMENT_ATTR_RSP 7 69 #define MAX_VOLUME 128 70 #define MAX_LABEL 16 71 #define MAX_TRANSACTIONS_PER_SESSION 16 72 #define MAX_CMD_QUEUE_LEN 8 73 #define PLAY_STATUS_PLAYING 1 74 75 #define CHECK_RC_CONNECTED \ 76 BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__); \ 77 if (btif_rc_cb.rc_connected == FALSE) \ 78 { \ 79 BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \ 80 return BT_STATUS_NOT_READY; \ 81 } 82 83 #define FILL_PDU_QUEUE(index, ctype, label, pending) \ 84 { \ 85 btif_rc_cb.rc_pdu_info[index].ctype = ctype; \ 86 btif_rc_cb.rc_pdu_info[index].label = label; \ 87 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \ 88 } 89 90 #define SEND_METAMSG_RSP(index, avrc_rsp) \ 91 { \ 92 if (btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \ 93 { \ 94 BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \ 95 return BT_STATUS_UNHANDLED; \ 96 } \ 97 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \ 98 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \ 99 btif_rc_cb.rc_pdu_info[index].ctype = 0; \ 100 btif_rc_cb.rc_pdu_info[index].label = 0; \ 101 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \ 102 } 103 104 /***************************************************************************** 105 ** Local type definitions 106 ******************************************************************************/ 107 typedef struct { 108 UINT8 bNotify; 109 UINT8 label; 110 } btif_rc_reg_notifications_t; 111 112 typedef struct 113 { 114 UINT8 label; 115 UINT8 ctype; 116 BOOLEAN is_rsp_pending; 117 } btif_rc_cmd_ctxt_t; 118 119 /* 2 second timeout to get interim response */ 120 #define BTIF_TIMEOUT_RC_INTERIM_RSP_MS (2 * 1000) 121 #define BTIF_TIMEOUT_RC_STATUS_CMD_MS (2 * 1000) 122 #define BTIF_TIMEOUT_RC_CONTROL_CMD_MS (2 * 1000) 123 124 125 typedef enum 126 { 127 eNOT_REGISTERED, 128 eREGISTERED, 129 eINTERIM 130 } btif_rc_nfn_reg_status_t; 131 132 typedef struct { 133 UINT8 event_id; 134 UINT8 label; 135 btif_rc_nfn_reg_status_t status; 136 } btif_rc_supported_event_t; 137 138 #define BTIF_RC_STS_TIMEOUT 0xFE 139 typedef struct { 140 UINT8 label; 141 UINT8 pdu_id; 142 } btif_rc_status_cmd_timer_t; 143 144 typedef struct { 145 UINT8 label; 146 UINT8 pdu_id; 147 } btif_rc_control_cmd_timer_t; 148 149 typedef struct { 150 union { 151 btif_rc_status_cmd_timer_t rc_status_cmd; 152 btif_rc_control_cmd_timer_t rc_control_cmd; 153 }; 154 } btif_rc_timer_context_t; 155 156 typedef struct { 157 BOOLEAN query_started; 158 UINT8 num_attrs; 159 UINT8 num_ext_attrs; 160 161 UINT8 attr_index; 162 UINT8 ext_attr_index; 163 UINT8 ext_val_index; 164 btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE]; 165 btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE]; 166 } btif_rc_player_app_settings_t; 167 168 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */ 169 typedef struct { 170 BOOLEAN rc_connected; 171 UINT8 rc_handle; 172 tBTA_AV_FEAT rc_features; 173 BD_ADDR rc_addr; 174 UINT16 rc_pending_play; 175 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN]; 176 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS]; 177 unsigned int rc_volume; 178 uint8_t rc_vol_label; 179 list_t *rc_supported_event_list; 180 btif_rc_player_app_settings_t rc_app_settings; 181 alarm_t *rc_play_status_timer; 182 BOOLEAN rc_features_processed; 183 UINT64 rc_playing_uid; 184 BOOLEAN rc_procedure_complete; 185 } btif_rc_cb_t; 186 187 typedef struct { 188 BOOLEAN in_use; 189 UINT8 lbl; 190 UINT8 handle; 191 btif_rc_timer_context_t txn_timer_context; 192 alarm_t *txn_timer; 193 } rc_transaction_t; 194 195 typedef struct 196 { 197 pthread_mutex_t lbllock; 198 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION]; 199 } rc_device_t; 200 201 rc_device_t device; 202 203 #define MAX_UINPUT_PATHS 3 204 static const char* uinput_dev_path[] = 205 {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" }; 206 static int uinput_fd = -1; 207 208 static int send_event (int fd, uint16_t type, uint16_t code, int32_t value); 209 static void send_key (int fd, uint16_t key, int pressed); 210 static int uinput_driver_check(); 211 static int uinput_create(char *name); 212 static int init_uinput (void); 213 static void close_uinput (void); 214 static void sleep_ms(period_ms_t timeout_ms); 215 216 static const struct { 217 const char *name; 218 uint8_t avrcp; 219 uint16_t mapped_id; 220 uint8_t release_quirk; 221 } key_map[] = { 222 { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 }, 223 { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 }, 224 { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 }, 225 { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 }, 226 { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 }, 227 { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 }, 228 { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 }, 229 { NULL, 0, 0, 0 } 230 }; 231 232 static void send_reject_response (UINT8 rc_handle, UINT8 label, 233 UINT8 pdu, UINT8 status); 234 static UINT8 opcode_from_pdu(UINT8 pdu); 235 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, 236 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp); 237 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 238 static void register_volumechange(UINT8 label); 239 #endif 240 static void lbl_init(); 241 static void lbl_destroy(); 242 static void init_all_transactions(); 243 static bt_status_t get_transaction(rc_transaction_t **ptransaction); 244 static void release_transaction(UINT8 label); 245 static rc_transaction_t* get_transaction_by_lbl(UINT8 label); 246 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 247 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg); 248 #endif 249 #if (AVRC_CTLR_INCLUDED == TRUE) 250 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg); 251 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg); 252 static void btif_rc_ctrl_upstreams_rsp_cmd( 253 UINT8 event, tAVRC_COMMAND *pavrc_cmd, UINT8 label); 254 static void rc_ctrl_procedure_complete(); 255 static void rc_stop_play_status_timer(); 256 static void register_for_event_notification (btif_rc_supported_event_t *p_event); 257 static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp); 258 static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp); 259 static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp); 260 static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp); 261 static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp); 262 static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp); 263 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp); 264 static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_ELEM_ATTRS_RSP *p_rsp); 265 static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp); 266 static bt_status_t get_play_status_cmd(void); 267 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs); 268 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals); 269 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value); 270 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids); 271 static bt_status_t getcapabilities_cmd (uint8_t cap_id); 272 static bt_status_t list_player_app_setting_attrib_cmd(void); 273 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id); 274 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids); 275 #endif 276 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label); 277 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 278 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label); 279 #endif 280 static void rc_start_play_status_timer(void); 281 static bool absolute_volume_disabled(void); 282 283 /***************************************************************************** 284 ** Static variables 285 ******************************************************************************/ 286 static btif_rc_cb_t btif_rc_cb; 287 static btrc_callbacks_t *bt_rc_callbacks = NULL; 288 static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL; 289 290 /***************************************************************************** 291 ** Static functions 292 ******************************************************************************/ 293 294 /***************************************************************************** 295 ** Externs 296 ******************************************************************************/ 297 extern BOOLEAN btif_hf_call_terminated_recently(); 298 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod); 299 300 extern fixed_queue_t *btu_general_alarm_queue; 301 302 /***************************************************************************** 303 ** Functions 304 ******************************************************************************/ 305 306 /***************************************************************************** 307 ** Local uinput helper functions 308 ******************************************************************************/ 309 int send_event (int fd, uint16_t type, uint16_t code, int32_t value) 310 { 311 struct uinput_event event; 312 BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__, 313 type, code, value); 314 memset(&event, 0, sizeof(event)); 315 event.type = type; 316 event.code = code; 317 event.value = value; 318 319 ssize_t ret; 320 OSI_NO_INTR(ret = write(fd, &event, sizeof(event))); 321 return (int)ret; 322 } 323 324 void send_key (int fd, uint16_t key, int pressed) 325 { 326 BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__, 327 fd, key, pressed); 328 329 if (fd < 0) 330 { 331 return; 332 } 333 334 BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd); 335 send_event(fd, EV_KEY, key, pressed); 336 send_event(fd, EV_SYN, SYN_REPORT, 0); 337 } 338 339 /************** uinput related functions **************/ 340 int uinput_driver_check() 341 { 342 uint32_t i; 343 for (i=0; i < MAX_UINPUT_PATHS; i++) 344 { 345 if (access(uinput_dev_path[i], O_RDWR) == 0) { 346 return 0; 347 } 348 } 349 BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__); 350 return -1; 351 } 352 353 int uinput_create(char *name) 354 { 355 struct uinput_dev dev; 356 int fd, x = 0; 357 358 for(x=0; x < MAX_UINPUT_PATHS; x++) 359 { 360 fd = open(uinput_dev_path[x], O_RDWR); 361 if (fd < 0) 362 continue; 363 break; 364 } 365 if (x == MAX_UINPUT_PATHS) { 366 BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__); 367 return -1; 368 } 369 memset(&dev, 0, sizeof(dev)); 370 if (name) 371 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1); 372 373 dev.id.bustype = BUS_BLUETOOTH; 374 dev.id.vendor = 0x0000; 375 dev.id.product = 0x0000; 376 dev.id.version = 0x0000; 377 378 ssize_t ret; 379 OSI_NO_INTR(ret = write(fd, &dev, sizeof(dev))); 380 if (ret < 0) { 381 BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__); 382 close(fd); 383 return -1; 384 } 385 386 ioctl(fd, UI_SET_EVBIT, EV_KEY); 387 ioctl(fd, UI_SET_EVBIT, EV_REL); 388 ioctl(fd, UI_SET_EVBIT, EV_SYN); 389 390 for (x = 0; key_map[x].name != NULL; x++) 391 ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id); 392 393 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) { 394 BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__); 395 close(fd); 396 return -1; 397 } 398 return fd; 399 } 400 401 int init_uinput (void) 402 { 403 char *name = "AVRCP"; 404 405 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 406 uinput_fd = uinput_create(name); 407 if (uinput_fd < 0) { 408 BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)", 409 __FUNCTION__, name, uinput_fd); 410 } else { 411 BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)", 412 __FUNCTION__, name, uinput_fd); 413 } 414 return uinput_fd; 415 } 416 417 void close_uinput (void) 418 { 419 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 420 if (uinput_fd > 0) { 421 ioctl(uinput_fd, UI_DEV_DESTROY); 422 423 close(uinput_fd); 424 uinput_fd = -1; 425 } 426 } 427 428 #if (AVRC_CTLR_INCLUDED == TRUE) 429 void rc_cleanup_sent_cmd (void *p_data) 430 { 431 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 432 433 } 434 435 void handle_rc_ctrl_features(BD_ADDR bd_addr) 436 { 437 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)|| 438 ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&& 439 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))) 440 { 441 bt_bdaddr_t rc_addr; 442 int rc_features = 0; 443 bdcpy(rc_addr.address,bd_addr); 444 445 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)&& 446 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)) 447 { 448 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME; 449 } 450 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)&& 451 (btif_rc_cb.rc_features & BTA_AV_FEAT_VENDOR)&& 452 (btif_rc_cb.rc_features_processed != TRUE)) 453 { 454 rc_features |= BTRC_FEAT_METADATA; 455 /* Mark rc features processed to avoid repeating 456 * the AVRCP procedure every time on receiving this 457 * update. 458 */ 459 btif_rc_cb.rc_features_processed = TRUE; 460 461 if (btif_av_is_sink_enabled()) 462 getcapabilities_cmd (AVRC_CAP_COMPANY_ID); 463 } 464 BTIF_TRACE_DEBUG("%s Update rc features to CTRL %d", __FUNCTION__, rc_features); 465 HAL_CBACK(bt_rc_ctrl_callbacks, getrcfeatures_cb, &rc_addr, rc_features); 466 } 467 } 468 #endif 469 470 void handle_rc_features(BD_ADDR bd_addr) 471 { 472 if (bt_rc_callbacks != NULL) 473 { 474 btrc_remote_features_t rc_features = BTRC_FEAT_NONE; 475 bt_bdaddr_t rc_addr; 476 477 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 478 bt_bdaddr_t avdtp_addr = btif_av_get_addr(); 479 480 bdstr_t addr1, addr2; 481 BTIF_TRACE_DEBUG("%s: AVDTP Address: %s AVCTP address: %s", __func__, 482 bdaddr_to_string(&avdtp_addr, addr1, sizeof(addr1)), 483 bdaddr_to_string(&rc_addr, addr2, sizeof(addr2))); 484 485 if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr) 486 || absolute_volume_disabled() 487 || bdcmp(avdtp_addr.address, rc_addr.address)) 488 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL; 489 490 if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE) 491 { 492 rc_features |= BTRC_FEAT_BROWSE; 493 } 494 495 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 496 if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) && 497 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)) 498 { 499 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME; 500 } 501 #endif 502 503 if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA) 504 { 505 rc_features |= BTRC_FEAT_METADATA; 506 } 507 508 BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features); 509 HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features) 510 511 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 512 BTIF_TRACE_DEBUG("%s Checking for feature flags in btif_rc_handler with label %d", 513 __FUNCTION__, btif_rc_cb.rc_vol_label); 514 // Register for volume change on connect 515 if (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL && 516 btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 517 { 518 rc_transaction_t *p_transaction=NULL; 519 bt_status_t status = BT_STATUS_NOT_READY; 520 if (MAX_LABEL==btif_rc_cb.rc_vol_label) 521 { 522 status=get_transaction(&p_transaction); 523 } 524 else 525 { 526 p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label); 527 if (NULL!=p_transaction) 528 { 529 BTIF_TRACE_DEBUG("%s register_volumechange already in progress for label %d", 530 __FUNCTION__, btif_rc_cb.rc_vol_label); 531 return; 532 } 533 else 534 status=get_transaction(&p_transaction); 535 } 536 537 if (BT_STATUS_SUCCESS == status && NULL!=p_transaction) 538 { 539 btif_rc_cb.rc_vol_label=p_transaction->lbl; 540 register_volumechange(btif_rc_cb.rc_vol_label); 541 } 542 } 543 #endif 544 } 545 } 546 547 /*************************************************************************** 548 * Function handle_rc_connect 549 * 550 * - Argument: tBTA_AV_RC_OPEN RC open data structure 551 * 552 * - Description: RC connection event handler 553 * 554 ***************************************************************************/ 555 void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) 556 { 557 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle); 558 bt_status_t result = BT_STATUS_SUCCESS; 559 #if (AVRC_CTLR_INCLUDED == TRUE) 560 bt_bdaddr_t rc_addr; 561 #endif 562 563 if (p_rc_open->status == BTA_AV_SUCCESS) 564 { 565 //check if already some RC is connected 566 if (btif_rc_cb.rc_connected) 567 { 568 BTIF_TRACE_ERROR("%s Got RC OPEN in connected state, Connected RC: %d \ 569 and Current RC: %d", __FUNCTION__, btif_rc_cb.rc_handle,p_rc_open->rc_handle ); 570 if ((btif_rc_cb.rc_handle != p_rc_open->rc_handle) 571 && (bdcmp(btif_rc_cb.rc_addr, p_rc_open->peer_addr))) 572 { 573 BTIF_TRACE_DEBUG("%s Got RC connected for some other handle", __FUNCTION__); 574 BTA_AvCloseRc(p_rc_open->rc_handle); 575 return; 576 } 577 } 578 memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR)); 579 btif_rc_cb.rc_features = p_rc_open->peer_features; 580 btif_rc_cb.rc_vol_label=MAX_LABEL; 581 btif_rc_cb.rc_volume=MAX_VOLUME; 582 583 btif_rc_cb.rc_connected = TRUE; 584 btif_rc_cb.rc_handle = p_rc_open->rc_handle; 585 586 /* on locally initiated connection we will get remote features as part of connect */ 587 if (btif_rc_cb.rc_features != 0) 588 handle_rc_features(btif_rc_cb.rc_addr); 589 if (bt_rc_callbacks) 590 { 591 result = uinput_driver_check(); 592 if (result == BT_STATUS_SUCCESS) 593 { 594 init_uinput(); 595 } 596 } 597 else 598 { 599 BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not initializing UInput", 600 __FUNCTION__); 601 } 602 BTIF_TRACE_DEBUG("%s handle_rc_connect features %d ",__FUNCTION__, btif_rc_cb.rc_features); 603 #if (AVRC_CTLR_INCLUDED == TRUE) 604 btif_rc_cb.rc_playing_uid = RC_INVALID_TRACK_ID; 605 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 606 if (bt_rc_ctrl_callbacks != NULL) 607 { 608 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr); 609 } 610 /* report connection state if remote device is AVRCP target */ 611 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)|| 612 ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&& 613 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))) 614 { 615 handle_rc_ctrl_features(btif_rc_cb.rc_addr); 616 } 617 #endif 618 } 619 else 620 { 621 BTIF_TRACE_ERROR("%s Connect failed with error code: %d", 622 __FUNCTION__, p_rc_open->status); 623 btif_rc_cb.rc_connected = FALSE; 624 } 625 } 626 627 /*************************************************************************** 628 * Function handle_rc_disconnect 629 * 630 * - Argument: tBTA_AV_RC_CLOSE RC close data structure 631 * 632 * - Description: RC disconnection event handler 633 * 634 ***************************************************************************/ 635 void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close) 636 { 637 #if (AVRC_CTLR_INCLUDED == TRUE) 638 bt_bdaddr_t rc_addr; 639 tBTA_AV_FEAT features; 640 #endif 641 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle); 642 if ((p_rc_close->rc_handle != btif_rc_cb.rc_handle) 643 && (bdcmp(btif_rc_cb.rc_addr, p_rc_close->peer_addr))) 644 { 645 BTIF_TRACE_ERROR("Got disconnect of unknown device"); 646 return; 647 } 648 #if (AVRC_CTLR_INCLUDED == TRUE) 649 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 650 features = btif_rc_cb.rc_features; 651 /* Clean up AVRCP procedure flags */ 652 memset(&btif_rc_cb.rc_app_settings, 0, 653 sizeof(btif_rc_player_app_settings_t)); 654 btif_rc_cb.rc_features_processed = FALSE; 655 btif_rc_cb.rc_procedure_complete = FALSE; 656 rc_stop_play_status_timer(); 657 /* Check and clear the notification event list */ 658 if (btif_rc_cb.rc_supported_event_list != NULL) 659 { 660 list_clear(btif_rc_cb.rc_supported_event_list); 661 btif_rc_cb.rc_supported_event_list = NULL; 662 } 663 #endif 664 btif_rc_cb.rc_handle = 0; 665 btif_rc_cb.rc_connected = FALSE; 666 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR)); 667 memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif)); 668 669 btif_rc_cb.rc_features = 0; 670 btif_rc_cb.rc_vol_label=MAX_LABEL; 671 btif_rc_cb.rc_volume=MAX_VOLUME; 672 init_all_transactions(); 673 if (bt_rc_callbacks != NULL) 674 { 675 close_uinput(); 676 } 677 else 678 { 679 BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not closing UInput", __FUNCTION__); 680 } 681 682 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR)); 683 #if (AVRC_CTLR_INCLUDED == TRUE) 684 /* report connection state if device is AVRCP target */ 685 if (bt_rc_ctrl_callbacks != NULL) 686 { 687 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr); 688 } 689 #endif 690 } 691 692 /*************************************************************************** 693 * Function handle_rc_passthrough_cmd 694 * 695 * - Argument: tBTA_AV_RC rc_id remote control command ID 696 * tBTA_AV_STATE key_state status of key press 697 * 698 * - Description: Remote control command handler 699 * 700 ***************************************************************************/ 701 void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd) 702 { 703 const char *status; 704 int pressed, i; 705 706 BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id); 707 708 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */ 709 if (p_remote_cmd) 710 { 711 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */ 712 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected())) 713 { 714 if (p_remote_cmd->key_state == AVRC_STATE_PRESS) 715 { 716 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__); 717 btif_rc_cb.rc_pending_play = TRUE; 718 } 719 return; 720 } 721 722 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play)) 723 { 724 APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__); 725 btif_rc_cb.rc_pending_play = FALSE; 726 return; 727 } 728 if ((p_remote_cmd->rc_id == BTA_AV_RC_VOL_UP)||(p_remote_cmd->rc_id == BTA_AV_RC_VOL_DOWN)) 729 return; // this command is not to be sent to UINPUT, only needed for PTS 730 } 731 732 if ((p_remote_cmd->rc_id == BTA_AV_RC_STOP) && (!btif_av_stream_started_ready())) 733 { 734 APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd",__FUNCTION__); 735 return; 736 } 737 738 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) { 739 status = "released"; 740 pressed = 0; 741 } else { 742 status = "pressed"; 743 pressed = 1; 744 } 745 746 if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) { 747 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed); 748 return; 749 } 750 751 for (i = 0; key_map[i].name != NULL; i++) { 752 if (p_remote_cmd->rc_id == key_map[i].avrcp) { 753 BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status); 754 755 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button 756 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE 757 * comes 1 second after the press, the MediaPlayer UI goes into a bad state. 758 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc. 759 * The fix is to generate a release right after the press and drown the 'actual' 760 * release. 761 */ 762 if ((key_map[i].release_quirk == 1) && (pressed == 0)) 763 { 764 BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now", 765 __FUNCTION__, key_map[i].name); 766 return; 767 } 768 send_key(uinput_fd, key_map[i].mapped_id, pressed); 769 if ((key_map[i].release_quirk == 1) && (pressed == 1)) 770 { 771 sleep_ms(30); 772 BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now", 773 __FUNCTION__, key_map[i].name); 774 send_key(uinput_fd, key_map[i].mapped_id, 0); 775 } 776 break; 777 } 778 } 779 780 if (key_map[i].name == NULL) 781 BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__, 782 p_remote_cmd->rc_id, status); 783 } 784 785 /*************************************************************************** 786 * Function handle_rc_passthrough_rsp 787 * 788 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response 789 * 790 * - Description: Remote control passthrough response handler 791 * 792 ***************************************************************************/ 793 void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp) 794 { 795 #if (AVRC_CTLR_INCLUDED == TRUE) 796 const char *status; 797 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 798 { 799 int key_state; 800 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) 801 { 802 status = "released"; 803 key_state = 1; 804 } 805 else 806 { 807 status = "pressed"; 808 key_state = 0; 809 } 810 811 BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status); 812 813 release_transaction(p_remote_rsp->label); 814 if (bt_rc_ctrl_callbacks != NULL) { 815 HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state); 816 } 817 } 818 else 819 { 820 BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__); 821 } 822 #else 823 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__); 824 #endif 825 } 826 827 /*************************************************************************** 828 * Function handle_rc_vendorunique_rsp 829 * 830 * - Argument: tBTA_AV_REMOTE_RSP command response 831 * 832 * - Description: Remote control vendor unique response handler 833 * 834 ***************************************************************************/ 835 void handle_rc_vendorunique_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp) 836 { 837 #if (AVRC_CTLR_INCLUDED == TRUE) 838 const char *status; 839 UINT8 vendor_id = 0; 840 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 841 { 842 int key_state; 843 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) 844 { 845 status = "released"; 846 key_state = 1; 847 } 848 else 849 { 850 status = "pressed"; 851 key_state = 0; 852 } 853 854 if (p_remote_rsp->len > 0) 855 { 856 if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN) 857 vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN -1]; 858 osi_free_and_reset((void **)&p_remote_rsp->p_data); 859 } 860 BTIF_TRACE_DEBUG("%s: vendor_id=%d status=%s", __FUNCTION__, vendor_id, status); 861 862 release_transaction(p_remote_rsp->label); 863 HAL_CBACK(bt_rc_ctrl_callbacks, groupnavigation_rsp_cb, vendor_id, key_state); 864 } 865 else 866 { 867 BTIF_TRACE_ERROR("%s Remote does not support AVRCP TG role", __FUNCTION__); 868 } 869 #else 870 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__); 871 #endif 872 } 873 874 void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command) 875 { 876 tAVRC_RESPONSE avrc_rsp = {0}; 877 avrc_rsp.rsp.pdu = pavrc_command->pdu; 878 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR; 879 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode; 880 881 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id; 882 avrc_rsp.reg_notif.param.uid_counter = 0; 883 884 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp); 885 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp); 886 887 } 888 889 /*************************************************************************** 890 * Function handle_rc_metamsg_cmd 891 * 892 * - Argument: tBTA_AV_VENDOR Structure containing the received 893 * metamsg command 894 * 895 * - Description: Remote control metamsg command handler (AVRCP 1.3) 896 * 897 ***************************************************************************/ 898 void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg) 899 { 900 /* Parse the metamsg command and pass it on to BTL-IFS */ 901 UINT8 scratch_buf[512] = {0}; 902 tAVRC_COMMAND avrc_command = {0}; 903 tAVRC_STS status; 904 905 BTIF_TRACE_EVENT("+ %s", __FUNCTION__); 906 907 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR) 908 { 909 BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode); 910 return; 911 } 912 if (pmeta_msg->len < 3) 913 { 914 BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode, 915 pmeta_msg->len); 916 return; 917 } 918 919 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) 920 { 921 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 922 { 923 rc_transaction_t *transaction=NULL; 924 transaction=get_transaction_by_lbl(pmeta_msg->label); 925 if (NULL!=transaction) 926 { 927 handle_rc_metamsg_rsp(pmeta_msg); 928 } 929 else 930 { 931 BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.", 932 __FUNCTION__, pmeta_msg->code, pmeta_msg->label); 933 } 934 return; 935 } 936 #else 937 { 938 BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.", 939 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 940 return; 941 } 942 #endif 943 } 944 945 status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf)); 946 BTIF_TRACE_DEBUG("%s Received vendor command.code,PDU and label: %d, %d,%d", 947 __FUNCTION__, pmeta_msg->code, avrc_command.cmd.pdu, pmeta_msg->label); 948 949 if (status != AVRC_STS_NO_ERROR) 950 { 951 /* return error */ 952 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x", 953 __FUNCTION__, status); 954 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status); 955 } 956 else 957 { 958 /* if RegisterNotification, add it to our registered queue */ 959 960 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) 961 { 962 UINT8 event_id = avrc_command.reg_notif.event_id; 963 BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x", 964 __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code); 965 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE; 966 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label; 967 968 if (event_id == AVRC_EVT_UIDS_CHANGE) 969 { 970 handle_uid_changed_notification(pmeta_msg, &avrc_command); 971 return; 972 } 973 974 } 975 976 BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s", 977 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu)); 978 979 /* Since handle_rc_metamsg_cmd() itself is called from 980 *btif context, no context switching is required. Invoke 981 * btif_rc_upstreams_evt directly from here. */ 982 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code, 983 pmeta_msg->label); 984 } 985 } 986 987 /*************************************************************************** 988 ** 989 ** Function btif_rc_handler 990 ** 991 ** Description RC event handler 992 ** 993 ***************************************************************************/ 994 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data) 995 { 996 BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event)); 997 switch (event) 998 { 999 case BTA_AV_RC_OPEN_EVT: 1000 { 1001 BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_open.peer_features); 1002 handle_rc_connect( &(p_data->rc_open) ); 1003 }break; 1004 1005 case BTA_AV_RC_CLOSE_EVT: 1006 { 1007 handle_rc_disconnect( &(p_data->rc_close) ); 1008 }break; 1009 1010 case BTA_AV_REMOTE_CMD_EVT: 1011 { 1012 if (bt_rc_callbacks != NULL) 1013 { 1014 BTIF_TRACE_DEBUG("%s rc_id:0x%x key_state:%d", 1015 __FUNCTION__, p_data->remote_cmd.rc_id, 1016 p_data->remote_cmd.key_state); 1017 /** In race conditions just after 2nd AVRCP is connected 1018 * remote might send pass through commands, so check for 1019 * Rc handle before processing pass through commands 1020 **/ 1021 if (btif_rc_cb.rc_handle == p_data->remote_cmd.rc_handle) 1022 { 1023 handle_rc_passthrough_cmd( (&p_data->remote_cmd) ); 1024 } 1025 else 1026 { 1027 BTIF_TRACE_DEBUG("%s Pass-through command for Invalid rc handle", __FUNCTION__); 1028 } 1029 } 1030 else 1031 { 1032 BTIF_TRACE_ERROR("AVRCP TG role not up, drop passthrough commands"); 1033 } 1034 } 1035 break; 1036 1037 #if (AVRC_CTLR_INCLUDED == TRUE) 1038 case BTA_AV_REMOTE_RSP_EVT: 1039 { 1040 BTIF_TRACE_DEBUG("%s RSP: rc_id:0x%x key_state:%d", 1041 __FUNCTION__, p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state); 1042 if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR) 1043 { 1044 handle_rc_vendorunique_rsp(&p_data->remote_rsp); 1045 } 1046 else 1047 { 1048 handle_rc_passthrough_rsp(&p_data->remote_rsp); 1049 } 1050 } 1051 break; 1052 1053 #endif 1054 case BTA_AV_RC_FEAT_EVT: 1055 { 1056 BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_feat.peer_features); 1057 btif_rc_cb.rc_features = p_data->rc_feat.peer_features; 1058 handle_rc_features(p_data->rc_feat.peer_addr); 1059 #if (AVRC_CTLR_INCLUDED == TRUE) 1060 if ((btif_rc_cb.rc_connected) && (bt_rc_ctrl_callbacks != NULL)) 1061 { 1062 handle_rc_ctrl_features(btif_rc_cb.rc_addr); 1063 } 1064 #endif 1065 } 1066 break; 1067 1068 case BTA_AV_META_MSG_EVT: 1069 { 1070 if (bt_rc_callbacks != NULL) 1071 { 1072 BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT code:%d label:%d", 1073 __FUNCTION__, 1074 p_data->meta_msg.code, 1075 p_data->meta_msg.label); 1076 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d", 1077 __FUNCTION__, 1078 p_data->meta_msg.company_id, 1079 p_data->meta_msg.len, 1080 p_data->meta_msg.rc_handle); 1081 /* handle the metamsg command */ 1082 handle_rc_metamsg_cmd(&(p_data->meta_msg)); 1083 /* Free the Memory allocated for tAVRC_MSG */ 1084 } 1085 #if (AVRC_CTLR_INCLUDED == TRUE) 1086 else if ((bt_rc_callbacks == NULL)&&(bt_rc_ctrl_callbacks != NULL)) 1087 { 1088 /* This is case of Sink + CT + TG(for abs vol)) */ 1089 BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT code:%d label:%d", 1090 __FUNCTION__, 1091 p_data->meta_msg.code, 1092 p_data->meta_msg.label); 1093 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d", 1094 __FUNCTION__, 1095 p_data->meta_msg.company_id, 1096 p_data->meta_msg.len, 1097 p_data->meta_msg.rc_handle); 1098 if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL)&& 1099 (p_data->meta_msg.code <= AVRC_RSP_INTERIM)) 1100 { 1101 /* Its a response */ 1102 handle_avk_rc_metamsg_rsp(&(p_data->meta_msg)); 1103 } 1104 else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ) 1105 { 1106 /* Its a command */ 1107 handle_avk_rc_metamsg_cmd(&(p_data->meta_msg)); 1108 } 1109 1110 } 1111 #endif 1112 else 1113 { 1114 BTIF_TRACE_ERROR("Neither CTRL, nor TG is up, drop meta commands"); 1115 } 1116 } 1117 break; 1118 1119 default: 1120 BTIF_TRACE_DEBUG("%s Unhandled RC event : 0x%x", __FUNCTION__, event); 1121 } 1122 } 1123 1124 /*************************************************************************** 1125 ** 1126 ** Function btif_rc_get_connected_peer 1127 ** 1128 ** Description Fetches the connected headset's BD_ADDR if any 1129 ** 1130 ***************************************************************************/ 1131 BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr) 1132 { 1133 if (btif_rc_cb.rc_connected == TRUE) { 1134 bdcpy(peer_addr, btif_rc_cb.rc_addr); 1135 return TRUE; 1136 } 1137 return FALSE; 1138 } 1139 1140 /*************************************************************************** 1141 ** 1142 ** Function btif_rc_get_connected_peer_handle 1143 ** 1144 ** Description Fetches the connected headset's handle if any 1145 ** 1146 ***************************************************************************/ 1147 UINT8 btif_rc_get_connected_peer_handle(void) 1148 { 1149 return btif_rc_cb.rc_handle; 1150 } 1151 1152 /*************************************************************************** 1153 ** 1154 ** Function btif_rc_check_handle_pending_play 1155 ** 1156 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app 1157 ** 1158 ***************************************************************************/ 1159 1160 /* clear the queued PLAY command. if bSend is TRUE, forward to app */ 1161 void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp) 1162 { 1163 UNUSED(peer_addr); 1164 1165 BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp); 1166 if (btif_rc_cb.rc_pending_play) 1167 { 1168 if (bSendToApp) 1169 { 1170 tBTA_AV_REMOTE_CMD remote_cmd; 1171 APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__); 1172 1173 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); 1174 remote_cmd.rc_handle = btif_rc_cb.rc_handle; 1175 remote_cmd.rc_id = AVRC_ID_PLAY; 1176 remote_cmd.hdr.ctype = AVRC_CMD_CTRL; 1177 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU; 1178 1179 /* delay sending to app, else there is a timing issue in the framework, 1180 ** which causes the audio to be on th device's speaker. Delay between 1181 ** OPEN & RC_PLAYs 1182 */ 1183 sleep_ms(200); 1184 /* send to app - both PRESSED & RELEASED */ 1185 remote_cmd.key_state = AVRC_STATE_PRESS; 1186 handle_rc_passthrough_cmd( &remote_cmd ); 1187 1188 sleep_ms(100); 1189 1190 remote_cmd.key_state = AVRC_STATE_RELEASE; 1191 handle_rc_passthrough_cmd( &remote_cmd ); 1192 } 1193 btif_rc_cb.rc_pending_play = FALSE; 1194 } 1195 } 1196 1197 /* Generic reject response */ 1198 static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status) 1199 { 1200 UINT8 ctype = AVRC_RSP_REJ; 1201 tAVRC_RESPONSE avrc_rsp; 1202 BT_HDR *p_msg = NULL; 1203 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 1204 1205 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu); 1206 avrc_rsp.rsp.pdu = pdu; 1207 avrc_rsp.rsp.status = status; 1208 1209 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) ) 1210 { 1211 BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x", 1212 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status); 1213 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 1214 } 1215 } 1216 1217 /*************************************************************************** 1218 * Function send_metamsg_rsp 1219 * 1220 * - Argument: 1221 * rc_handle RC handle corresponding to the connected RC 1222 * label Label of the RC response 1223 * code Response type 1224 * pmetamsg_resp Vendor response 1225 * 1226 * - Description: Remote control metamsg response handler (AVRCP 1.3) 1227 * 1228 ***************************************************************************/ 1229 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code, 1230 tAVRC_RESPONSE *pmetamsg_resp) 1231 { 1232 UINT8 ctype; 1233 1234 if (!pmetamsg_resp) 1235 { 1236 BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__); 1237 return; 1238 } 1239 1240 BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__, 1241 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu)); 1242 1243 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR) 1244 { 1245 ctype = AVRC_RSP_REJ; 1246 } 1247 else 1248 { 1249 if ( code < AVRC_RSP_NOT_IMPL) 1250 { 1251 if (code == AVRC_CMD_NOTIF) 1252 { 1253 ctype = AVRC_RSP_INTERIM; 1254 } 1255 else if (code == AVRC_CMD_STATUS) 1256 { 1257 ctype = AVRC_RSP_IMPL_STBL; 1258 } 1259 else 1260 { 1261 ctype = AVRC_RSP_ACCEPT; 1262 } 1263 } 1264 else 1265 { 1266 ctype = code; 1267 } 1268 } 1269 /* if response is for register_notification, make sure the rc has 1270 actually registered for this */ 1271 if ((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED)) 1272 { 1273 BOOLEAN bSent = FALSE; 1274 UINT8 event_id = pmetamsg_resp->reg_notif.event_id; 1275 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify); 1276 1277 /* de-register this notification for a CHANGED response */ 1278 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE; 1279 BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__, 1280 btif_rc_cb.rc_handle, event_id, bNotify); 1281 if (bNotify) 1282 { 1283 BT_HDR *p_msg = NULL; 1284 tAVRC_STS status; 1285 1286 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle, 1287 pmetamsg_resp, &p_msg)) ) 1288 { 1289 BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d", 1290 __FUNCTION__, btif_rc_cb.rc_handle, event_id); 1291 bSent = TRUE; 1292 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 1293 ctype, p_msg); 1294 } 1295 else 1296 { 1297 BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x", 1298 __FUNCTION__, status); 1299 } 1300 1301 } 1302 1303 if (!bSent) 1304 { 1305 BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \ 1306 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 1307 } 1308 } 1309 else 1310 { 1311 /* All other commands go here */ 1312 1313 BT_HDR *p_msg = NULL; 1314 tAVRC_STS status; 1315 1316 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg); 1317 1318 if (status == AVRC_STS_NO_ERROR) 1319 { 1320 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 1321 } 1322 else 1323 { 1324 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x", 1325 __FUNCTION__, status); 1326 } 1327 } 1328 } 1329 1330 static UINT8 opcode_from_pdu(UINT8 pdu) 1331 { 1332 UINT8 opcode = 0; 1333 1334 switch (pdu) 1335 { 1336 case AVRC_PDU_NEXT_GROUP: 1337 case AVRC_PDU_PREV_GROUP: /* pass thru */ 1338 opcode = AVRC_OP_PASS_THRU; 1339 break; 1340 1341 default: /* vendor */ 1342 opcode = AVRC_OP_VENDOR; 1343 break; 1344 } 1345 1346 return opcode; 1347 } 1348 1349 /******************************************************************************* 1350 ** 1351 ** Function btif_rc_upstreams_evt 1352 ** 1353 ** Description Executes AVRC UPSTREAMS events in btif context. 1354 ** 1355 ** Returns void 1356 ** 1357 *******************************************************************************/ 1358 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label) 1359 { 1360 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__, 1361 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label); 1362 1363 switch (event) 1364 { 1365 case AVRC_PDU_GET_PLAY_STATUS: 1366 { 1367 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE) 1368 HAL_CBACK(bt_rc_callbacks, get_play_status_cb); 1369 } 1370 break; 1371 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 1372 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 1373 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 1374 case AVRC_PDU_SET_PLAYER_APP_VALUE: 1375 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 1376 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 1377 { 1378 /* TODO: Add support for Application Settings */ 1379 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD); 1380 } 1381 break; 1382 case AVRC_PDU_GET_ELEMENT_ATTR: 1383 { 1384 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1385 UINT8 num_attr; 1386 memset(&element_attrs, 0, sizeof(element_attrs)); 1387 if (pavrc_cmd->get_elem_attrs.num_attr == 0) 1388 { 1389 /* CT requests for all attributes */ 1390 int attr_cnt; 1391 num_attr = BTRC_MAX_ELEM_ATTR_SIZE; 1392 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++) 1393 { 1394 element_attrs[attr_cnt] = attr_cnt + 1; 1395 } 1396 } 1397 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF) 1398 { 1399 /* 0xff indicates, no attributes requested - reject */ 1400 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 1401 AVRC_STS_BAD_PARAM); 1402 return; 1403 } 1404 else 1405 { 1406 int attr_cnt, filled_attr_count; 1407 1408 num_attr = 0; 1409 /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid, 1410 * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID. 1411 * Fill only valid entries. 1412 */ 1413 for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) && 1414 (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++) 1415 { 1416 if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) && 1417 (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID)) 1418 { 1419 /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases 1420 */ 1421 for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++) 1422 { 1423 if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt]) 1424 break; 1425 } 1426 if (filled_attr_count == num_attr) 1427 { 1428 element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt]; 1429 num_attr++; 1430 } 1431 } 1432 } 1433 } 1434 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE); 1435 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs); 1436 } 1437 break; 1438 case AVRC_PDU_REGISTER_NOTIFICATION: 1439 { 1440 if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED && 1441 pavrc_cmd->reg_notif.param == 0) 1442 { 1443 BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.", 1444 __FUNCTION__); 1445 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM); 1446 /* de-register this notification for a rejected response */ 1447 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE; 1448 return; 1449 } 1450 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id, 1451 pavrc_cmd->reg_notif.param); 1452 } 1453 break; 1454 case AVRC_PDU_INFORM_DISPLAY_CHARSET: 1455 { 1456 tAVRC_RESPONSE avrc_rsp; 1457 BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__); 1458 if (btif_rc_cb.rc_connected == TRUE) 1459 { 1460 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP)); 1461 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET); 1462 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET; 1463 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR; 1464 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp); 1465 } 1466 } 1467 break; 1468 default: 1469 { 1470 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, 1471 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD); 1472 return; 1473 } 1474 break; 1475 } 1476 } 1477 1478 #if (AVRC_CTLR_INCLUDED == TRUE) 1479 /******************************************************************************* 1480 ** 1481 ** Function btif_rc_ctrl_upstreams_rsp_cmd 1482 ** 1483 ** Description Executes AVRC UPSTREAMS response events in btif context. 1484 ** 1485 ** Returns void 1486 ** 1487 *******************************************************************************/ 1488 static void btif_rc_ctrl_upstreams_rsp_cmd(UINT8 event, tAVRC_COMMAND *pavrc_cmd, 1489 UINT8 label) 1490 { 1491 BTIF_TRACE_DEBUG("%s pdu: %s handle: 0x%x", __FUNCTION__, 1492 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle); 1493 bt_bdaddr_t rc_addr; 1494 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 1495 #if (AVRC_CTLR_INCLUDED == TRUE) 1496 switch (event) 1497 { 1498 case AVRC_PDU_SET_ABSOLUTE_VOLUME: 1499 HAL_CBACK(bt_rc_ctrl_callbacks,setabsvol_cmd_cb, &rc_addr, 1500 pavrc_cmd->volume.volume, label); 1501 break; 1502 case AVRC_PDU_REGISTER_NOTIFICATION: 1503 if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE) 1504 { 1505 HAL_CBACK(bt_rc_ctrl_callbacks, registernotification_absvol_cb, 1506 &rc_addr, label); 1507 } 1508 break; 1509 } 1510 #endif 1511 } 1512 #endif 1513 1514 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 1515 /******************************************************************************* 1516 ** 1517 ** Function btif_rc_upstreams_rsp_evt 1518 ** 1519 ** Description Executes AVRC UPSTREAMS response events in btif context. 1520 ** 1521 ** Returns void 1522 ** 1523 *******************************************************************************/ 1524 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label) 1525 { 1526 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__, 1527 dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label); 1528 1529 switch (event) 1530 { 1531 case AVRC_PDU_REGISTER_NOTIFICATION: 1532 { 1533 if (AVRC_RSP_CHANGED==ctype) 1534 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume; 1535 HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype) 1536 } 1537 break; 1538 1539 case AVRC_PDU_SET_ABSOLUTE_VOLUME: 1540 { 1541 BTIF_TRACE_DEBUG("%s Set absolute volume change event received: volume %d,ctype %d", 1542 __FUNCTION__, pavrc_resp->volume.volume,ctype); 1543 if (AVRC_RSP_ACCEPT==ctype) 1544 btif_rc_cb.rc_volume=pavrc_resp->volume.volume; 1545 HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype) 1546 } 1547 break; 1548 1549 default: 1550 return; 1551 } 1552 } 1553 #endif 1554 1555 /************************************************************************************ 1556 ** AVRCP API Functions 1557 ************************************************************************************/ 1558 1559 /******************************************************************************* 1560 ** 1561 ** Function init 1562 ** 1563 ** Description Initializes the AVRC interface 1564 ** 1565 ** Returns bt_status_t 1566 ** 1567 *******************************************************************************/ 1568 static bt_status_t init(btrc_callbacks_t* callbacks ) 1569 { 1570 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 1571 bt_status_t result = BT_STATUS_SUCCESS; 1572 1573 if (bt_rc_callbacks) 1574 return BT_STATUS_DONE; 1575 1576 bt_rc_callbacks = callbacks; 1577 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb)); 1578 btif_rc_cb.rc_vol_label=MAX_LABEL; 1579 btif_rc_cb.rc_volume=MAX_VOLUME; 1580 lbl_init(); 1581 1582 return result; 1583 } 1584 1585 /******************************************************************************* 1586 ** 1587 ** Function init_ctrl 1588 ** 1589 ** Description Initializes the AVRC interface 1590 ** 1591 ** Returns bt_status_t 1592 ** 1593 *******************************************************************************/ 1594 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks ) 1595 { 1596 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 1597 bt_status_t result = BT_STATUS_SUCCESS; 1598 1599 if (bt_rc_ctrl_callbacks) 1600 return BT_STATUS_DONE; 1601 1602 bt_rc_ctrl_callbacks = callbacks; 1603 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb)); 1604 btif_rc_cb.rc_vol_label=MAX_LABEL; 1605 btif_rc_cb.rc_volume=MAX_VOLUME; 1606 lbl_init(); 1607 1608 return result; 1609 } 1610 1611 static void rc_ctrl_procedure_complete () 1612 { 1613 if (btif_rc_cb.rc_procedure_complete == TRUE) 1614 { 1615 return; 1616 } 1617 btif_rc_cb.rc_procedure_complete = TRUE; 1618 UINT32 attr_list[] = { 1619 AVRC_MEDIA_ATTR_ID_TITLE, 1620 AVRC_MEDIA_ATTR_ID_ARTIST, 1621 AVRC_MEDIA_ATTR_ID_ALBUM, 1622 AVRC_MEDIA_ATTR_ID_TRACK_NUM, 1623 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, 1624 AVRC_MEDIA_ATTR_ID_GENRE, 1625 AVRC_MEDIA_ATTR_ID_PLAYING_TIME 1626 }; 1627 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list); 1628 } 1629 1630 /*************************************************************************** 1631 ** 1632 ** Function get_play_status_rsp 1633 ** 1634 ** Description Returns the current play status. 1635 ** This method is called in response to 1636 ** GetPlayStatus request. 1637 ** 1638 ** Returns bt_status_t 1639 ** 1640 ***************************************************************************/ 1641 static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len, 1642 uint32_t song_pos) 1643 { 1644 tAVRC_RESPONSE avrc_rsp; 1645 CHECK_RC_CONNECTED 1646 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP)); 1647 avrc_rsp.get_play_status.song_len = song_len; 1648 avrc_rsp.get_play_status.song_pos = song_pos; 1649 avrc_rsp.get_play_status.play_status = play_status; 1650 1651 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 1652 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS); 1653 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1654 /* Send the response */ 1655 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp); 1656 return BT_STATUS_SUCCESS; 1657 } 1658 1659 /*************************************************************************** 1660 ** 1661 ** Function get_element_attr_rsp 1662 ** 1663 ** Description Returns the current songs' element attributes 1664 ** in text. 1665 ** 1666 ** Returns bt_status_t 1667 ** 1668 ***************************************************************************/ 1669 static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs) 1670 { 1671 tAVRC_RESPONSE avrc_rsp; 1672 UINT32 i; 1673 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1674 CHECK_RC_CONNECTED 1675 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); 1676 1677 if (num_attr == 0) 1678 { 1679 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM; 1680 } 1681 else 1682 { 1683 for (i=0; i<num_attr; i++) { 1684 element_attrs[i].attr_id = p_attrs[i].attr_id; 1685 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8; 1686 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text); 1687 element_attrs[i].name.p_str = p_attrs[i].text; 1688 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s", 1689 __FUNCTION__, (unsigned int)element_attrs[i].attr_id, 1690 element_attrs[i].name.charset_id, element_attrs[i].name.str_len, 1691 element_attrs[i].name.p_str); 1692 } 1693 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1694 } 1695 avrc_rsp.get_elem_attrs.num_attr = num_attr; 1696 avrc_rsp.get_elem_attrs.p_attrs = element_attrs; 1697 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 1698 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR); 1699 /* Send the response */ 1700 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp); 1701 return BT_STATUS_SUCCESS; 1702 } 1703 1704 /*************************************************************************** 1705 ** 1706 ** Function register_notification_rsp 1707 ** 1708 ** Description Response to the register notification request. 1709 ** in text. 1710 ** 1711 ** Returns bt_status_t 1712 ** 1713 ***************************************************************************/ 1714 static bt_status_t register_notification_rsp(btrc_event_id_t event_id, 1715 btrc_notification_type_t type, btrc_register_notification_t *p_param) 1716 { 1717 tAVRC_RESPONSE avrc_rsp; 1718 CHECK_RC_CONNECTED 1719 BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id)); 1720 if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE) 1721 { 1722 BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id); 1723 return BT_STATUS_NOT_READY; 1724 } 1725 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP)); 1726 avrc_rsp.reg_notif.event_id = event_id; 1727 1728 switch(event_id) 1729 { 1730 case BTRC_EVT_PLAY_STATUS_CHANGED: 1731 avrc_rsp.reg_notif.param.play_status = p_param->play_status; 1732 if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING) 1733 btif_av_clear_remote_suspend_flag(); 1734 break; 1735 case BTRC_EVT_TRACK_CHANGE: 1736 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t)); 1737 break; 1738 case BTRC_EVT_PLAY_POS_CHANGED: 1739 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos; 1740 break; 1741 default: 1742 BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id); 1743 return BT_STATUS_UNHANDLED; 1744 } 1745 1746 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1747 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION); 1748 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1749 1750 /* Send the response. */ 1751 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label, 1752 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp); 1753 return BT_STATUS_SUCCESS; 1754 } 1755 1756 /*************************************************************************** 1757 ** 1758 ** Function set_volume 1759 ** 1760 ** Description Send current volume setting to remote side. 1761 ** Support limited to SetAbsoluteVolume 1762 ** This can be enhanced to support Relative Volume (AVRCP 1.0). 1763 ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN 1764 ** as opposed to absolute volume level 1765 ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set 1766 ** 1767 ** Returns bt_status_t 1768 ** 1769 ***************************************************************************/ 1770 static bt_status_t set_volume(uint8_t volume) 1771 { 1772 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 1773 CHECK_RC_CONNECTED 1774 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 1775 rc_transaction_t *p_transaction=NULL; 1776 1777 if (btif_rc_cb.rc_volume==volume) 1778 { 1779 status=BT_STATUS_DONE; 1780 BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume); 1781 return status; 1782 } 1783 1784 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) && 1785 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)) 1786 { 1787 tAVRC_COMMAND avrc_cmd = {0}; 1788 BT_HDR *p_msg = NULL; 1789 1790 BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume); 1791 avrc_cmd.volume.opcode = AVRC_OP_VENDOR; 1792 avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME; 1793 avrc_cmd.volume.status = AVRC_STS_NO_ERROR; 1794 avrc_cmd.volume.volume = volume; 1795 1796 if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR) 1797 { 1798 bt_status_t tran_status=get_transaction(&p_transaction); 1799 if (BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction) 1800 { 1801 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 1802 __FUNCTION__,p_transaction->lbl); 1803 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg); 1804 status = BT_STATUS_SUCCESS; 1805 } 1806 else 1807 { 1808 osi_free(p_msg); 1809 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x", 1810 __FUNCTION__, tran_status); 1811 status = BT_STATUS_FAIL; 1812 } 1813 } 1814 else 1815 { 1816 BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x", 1817 __FUNCTION__, status); 1818 status = BT_STATUS_FAIL; 1819 } 1820 } 1821 else 1822 status=BT_STATUS_NOT_READY; 1823 return status; 1824 } 1825 1826 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 1827 /*************************************************************************** 1828 ** 1829 ** Function register_volumechange 1830 ** 1831 ** Description Register for volume change notification from remote side. 1832 ** 1833 ** Returns void 1834 ** 1835 ***************************************************************************/ 1836 1837 static void register_volumechange (UINT8 lbl) 1838 { 1839 tAVRC_COMMAND avrc_cmd = {0}; 1840 BT_HDR *p_msg = NULL; 1841 tAVRC_STS BldResp=AVRC_STS_BAD_CMD; 1842 rc_transaction_t *p_transaction=NULL; 1843 1844 BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl); 1845 1846 avrc_cmd.cmd.opcode=0x00; 1847 avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1848 avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE; 1849 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR; 1850 avrc_cmd.reg_notif.param = 0; 1851 1852 BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg); 1853 if (AVRC_STS_NO_ERROR == BldResp && p_msg) { 1854 p_transaction = get_transaction_by_lbl(lbl); 1855 if (p_transaction != NULL) { 1856 BTA_AvMetaCmd(btif_rc_cb.rc_handle, p_transaction->lbl, 1857 AVRC_CMD_NOTIF, p_msg); 1858 BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called", __func__); 1859 } else { 1860 osi_free(p_msg); 1861 BTIF_TRACE_ERROR("%s transaction not obtained with label: %d", 1862 __func__, lbl); 1863 } 1864 } else { 1865 BTIF_TRACE_ERROR("%s failed to build command:%d", __func__, BldResp); 1866 } 1867 } 1868 1869 /*************************************************************************** 1870 ** 1871 ** Function handle_rc_metamsg_rsp 1872 ** 1873 ** Description Handle RC metamessage response 1874 ** 1875 ** Returns void 1876 ** 1877 ***************************************************************************/ 1878 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg) 1879 { 1880 tAVRC_RESPONSE avrc_response = {0}; 1881 UINT8 scratch_buf[512] = {0}; 1882 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 1883 1884 if (AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code 1885 || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code 1886 || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code)) 1887 { 1888 status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf)); 1889 BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d", 1890 __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu, 1891 status, pmeta_msg->label); 1892 1893 if (status != AVRC_STS_NO_ERROR) 1894 { 1895 if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu 1896 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id 1897 && btif_rc_cb.rc_vol_label==pmeta_msg->label) 1898 { 1899 btif_rc_cb.rc_vol_label=MAX_LABEL; 1900 release_transaction(btif_rc_cb.rc_vol_label); 1901 } 1902 else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu) 1903 { 1904 release_transaction(pmeta_msg->label); 1905 } 1906 return; 1907 } 1908 else if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu 1909 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id 1910 && btif_rc_cb.rc_vol_label!=pmeta_msg->label) 1911 { 1912 // Just discard the message, if the device sends back with an incorrect label 1913 BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d", 1914 __FUNCTION__, pmeta_msg->code, pmeta_msg->label); 1915 return; 1916 } 1917 } 1918 else 1919 { 1920 BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.", 1921 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 1922 return; 1923 } 1924 1925 if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu 1926 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id 1927 && AVRC_RSP_CHANGED==pmeta_msg->code) 1928 { 1929 /* re-register for volume change notification */ 1930 // Do not re-register for rejected case, as it might get into endless loop 1931 register_volumechange(btif_rc_cb.rc_vol_label); 1932 } 1933 else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu) 1934 { 1935 /* free up the label here */ 1936 release_transaction(pmeta_msg->label); 1937 } 1938 1939 BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s", 1940 __FUNCTION__, dump_rc_pdu(avrc_response.pdu)); 1941 btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code, 1942 pmeta_msg->label); 1943 } 1944 #endif 1945 1946 #if (AVRC_CTLR_INCLUDED == TRUE) 1947 /*************************************************************************** 1948 ** 1949 ** Function iterate_supported_event_list_for_interim_rsp 1950 ** 1951 ** Description iterator callback function to match the event and handle 1952 ** timer cleanup 1953 ** Returns true to continue iterating, false to stop 1954 ** 1955 ***************************************************************************/ 1956 bool iterate_supported_event_list_for_interim_rsp(void *data, void *cb_data) 1957 { 1958 UINT8 *p_event_id; 1959 btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data; 1960 1961 p_event_id = (UINT8*)cb_data; 1962 1963 if (p_event->event_id == *p_event_id) 1964 { 1965 p_event->status = eINTERIM; 1966 return false; 1967 } 1968 return true; 1969 } 1970 1971 /*************************************************************************** 1972 ** 1973 ** Function iterate_supported_event_list_for_timeout 1974 ** 1975 ** Description Iterator callback function for timeout handling. 1976 ** As part of the failure handling, it releases the 1977 ** transaction label and removes the event from list, 1978 ** this event will not be requested again during 1979 ** the lifetime of the connection. 1980 ** Returns false to stop iterating, true to continue 1981 ** 1982 ***************************************************************************/ 1983 bool iterate_supported_event_list_for_timeout(void *data, void *cb_data) 1984 { 1985 UINT8 label; 1986 btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data; 1987 1988 label = (*(UINT8*)cb_data) & 0xFF; 1989 1990 if (p_event->label == label) 1991 { 1992 list_remove(btif_rc_cb.rc_supported_event_list, p_event); 1993 return false; 1994 } 1995 return true; 1996 } 1997 1998 /*************************************************************************** 1999 ** 2000 ** Function rc_notification_interim_timout 2001 ** 2002 ** Description Interim response timeout handler. 2003 ** Runs the iterator to check and clear the timed out event. 2004 ** Proceeds to register for the unregistered events. 2005 ** Returns None 2006 ** 2007 ***************************************************************************/ 2008 static void rc_notification_interim_timout (UINT8 label) 2009 { 2010 list_node_t *node; 2011 2012 list_foreach(btif_rc_cb.rc_supported_event_list, 2013 iterate_supported_event_list_for_timeout, &label); 2014 /* Timeout happened for interim response for the registered event, 2015 * check if there are any pending for registration 2016 */ 2017 node = list_begin(btif_rc_cb.rc_supported_event_list); 2018 while (node != NULL) 2019 { 2020 btif_rc_supported_event_t *p_event; 2021 2022 p_event = (btif_rc_supported_event_t *)list_node(node); 2023 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) 2024 { 2025 register_for_event_notification(p_event); 2026 break; 2027 } 2028 node = list_next (node); 2029 } 2030 /* Todo. Need to initiate application settings query if this 2031 * is the last event registration. 2032 */ 2033 } 2034 2035 /*************************************************************************** 2036 ** 2037 ** Function btif_rc_status_cmd_timeout_handler 2038 ** 2039 ** Description RC status command timeout handler (Runs in BTIF context). 2040 ** Returns None 2041 ** 2042 ***************************************************************************/ 2043 static void btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event, 2044 char *data) 2045 { 2046 btif_rc_timer_context_t *p_context; 2047 tAVRC_RESPONSE avrc_response = {0}; 2048 tBTA_AV_META_MSG meta_msg; 2049 2050 p_context = (btif_rc_timer_context_t *)data; 2051 memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG)); 2052 meta_msg.rc_handle = btif_rc_cb.rc_handle; 2053 2054 switch (p_context->rc_status_cmd.pdu_id) { 2055 case AVRC_PDU_REGISTER_NOTIFICATION: 2056 rc_notification_interim_timout(p_context->rc_status_cmd.label); 2057 break; 2058 2059 case AVRC_PDU_GET_CAPABILITIES: 2060 avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT; 2061 handle_get_capability_response(&meta_msg, &avrc_response.get_caps); 2062 break; 2063 2064 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 2065 avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT; 2066 handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr); 2067 break; 2068 2069 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 2070 avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT; 2071 handle_app_val_response(&meta_msg, &avrc_response.list_app_values); 2072 break; 2073 2074 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 2075 avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT; 2076 handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val); 2077 break; 2078 2079 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 2080 avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT; 2081 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt); 2082 break; 2083 2084 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 2085 avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT; 2086 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt); 2087 break; 2088 2089 case AVRC_PDU_GET_ELEMENT_ATTR: 2090 avrc_response.get_elem_attrs.status = BTIF_RC_STS_TIMEOUT; 2091 handle_get_elem_attr_response(&meta_msg, &avrc_response.get_elem_attrs); 2092 break; 2093 2094 case AVRC_PDU_GET_PLAY_STATUS: 2095 avrc_response.get_play_status.status = BTIF_RC_STS_TIMEOUT; 2096 handle_get_playstatus_response(&meta_msg, &avrc_response.get_play_status); 2097 break; 2098 } 2099 release_transaction(p_context->rc_status_cmd.label); 2100 } 2101 2102 /*************************************************************************** 2103 ** 2104 ** Function btif_rc_status_cmd_timer_timeout 2105 ** 2106 ** Description RC status command timeout callback. 2107 ** This is called from BTU context and switches to BTIF 2108 ** context to handle the timeout events 2109 ** Returns None 2110 ** 2111 ***************************************************************************/ 2112 static void btif_rc_status_cmd_timer_timeout(void *data) 2113 { 2114 btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data; 2115 2116 btif_transfer_context(btif_rc_status_cmd_timeout_handler, 0, 2117 (char *)p_data, sizeof(btif_rc_timer_context_t), 2118 NULL); 2119 } 2120 2121 /*************************************************************************** 2122 ** 2123 ** Function btif_rc_control_cmd_timeout_handler 2124 ** 2125 ** Description RC control command timeout handler (Runs in BTIF context). 2126 ** Returns None 2127 ** 2128 ***************************************************************************/ 2129 static void btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event, 2130 char *data) 2131 { 2132 btif_rc_timer_context_t *p_context = (btif_rc_timer_context_t *)data; 2133 tAVRC_RESPONSE avrc_response = {0}; 2134 tBTA_AV_META_MSG meta_msg; 2135 2136 memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG)); 2137 meta_msg.rc_handle = btif_rc_cb.rc_handle; 2138 2139 switch (p_context->rc_control_cmd.pdu_id) { 2140 case AVRC_PDU_SET_PLAYER_APP_VALUE: 2141 avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT; 2142 handle_set_app_attr_val_response(&meta_msg, 2143 &avrc_response.set_app_val); 2144 break; 2145 } 2146 release_transaction(p_context->rc_control_cmd.label); 2147 } 2148 2149 /*************************************************************************** 2150 ** 2151 ** Function btif_rc_control_cmd_timer_timeout 2152 ** 2153 ** Description RC control command timeout callback. 2154 ** This is called from BTU context and switches to BTIF 2155 ** context to handle the timeout events 2156 ** Returns None 2157 ** 2158 ***************************************************************************/ 2159 static void btif_rc_control_cmd_timer_timeout(void *data) 2160 { 2161 btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data; 2162 2163 btif_transfer_context(btif_rc_control_cmd_timeout_handler, 0, 2164 (char *)p_data, sizeof(btif_rc_timer_context_t), 2165 NULL); 2166 } 2167 2168 /*************************************************************************** 2169 ** 2170 ** Function btif_rc_play_status_timeout_handler 2171 ** 2172 ** Description RC play status timeout handler (Runs in BTIF context). 2173 ** Returns None 2174 ** 2175 ***************************************************************************/ 2176 static void btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event, 2177 UNUSED_ATTR char *p_data) 2178 { 2179 get_play_status_cmd(); 2180 rc_start_play_status_timer(); 2181 } 2182 2183 /*************************************************************************** 2184 ** 2185 ** Function btif_rc_play_status_timer_timeout 2186 ** 2187 ** Description RC play status timeout callback. 2188 ** This is called from BTU context and switches to BTIF 2189 ** context to handle the timeout events 2190 ** Returns None 2191 ** 2192 ***************************************************************************/ 2193 static void btif_rc_play_status_timer_timeout(UNUSED_ATTR void *data) 2194 { 2195 btif_transfer_context(btif_rc_play_status_timeout_handler, 0, 0, 0, NULL); 2196 } 2197 2198 /*************************************************************************** 2199 ** 2200 ** Function rc_start_play_status_timer 2201 ** 2202 ** Description Helper function to start the timer to fetch play status. 2203 ** Returns None 2204 ** 2205 ***************************************************************************/ 2206 static void rc_start_play_status_timer(void) 2207 { 2208 /* Start the Play status timer only if it is not started */ 2209 if (!alarm_is_scheduled(btif_rc_cb.rc_play_status_timer)) { 2210 if (btif_rc_cb.rc_play_status_timer == NULL) { 2211 btif_rc_cb.rc_play_status_timer = 2212 alarm_new("btif_rc.rc_play_status_timer"); 2213 } 2214 alarm_set_on_queue(btif_rc_cb.rc_play_status_timer, 2215 BTIF_TIMEOUT_RC_INTERIM_RSP_MS, 2216 btif_rc_play_status_timer_timeout, NULL, 2217 btu_general_alarm_queue); 2218 } 2219 } 2220 2221 /*************************************************************************** 2222 ** 2223 ** Function rc_stop_play_status_timer 2224 ** 2225 ** Description Helper function to stop the play status timer. 2226 ** Returns None 2227 ** 2228 ***************************************************************************/ 2229 void rc_stop_play_status_timer() 2230 { 2231 if (btif_rc_cb.rc_play_status_timer != NULL) 2232 alarm_cancel(btif_rc_cb.rc_play_status_timer); 2233 } 2234 2235 /*************************************************************************** 2236 ** 2237 ** Function register_for_event_notification 2238 ** 2239 ** Description Helper function registering notification events 2240 ** sets an interim response timeout to handle if the remote 2241 ** does not respond. 2242 ** Returns None 2243 ** 2244 ***************************************************************************/ 2245 static void register_for_event_notification(btif_rc_supported_event_t *p_event) 2246 { 2247 bt_status_t status; 2248 rc_transaction_t *p_transaction; 2249 2250 status = get_transaction(&p_transaction); 2251 if (status == BT_STATUS_SUCCESS) 2252 { 2253 btif_rc_timer_context_t *p_context = &p_transaction->txn_timer_context; 2254 2255 status = register_notification_cmd (p_transaction->lbl, p_event->event_id, 0); 2256 if (status != BT_STATUS_SUCCESS) 2257 { 2258 BTIF_TRACE_ERROR("%s Error in Notification registration %d", 2259 __FUNCTION__, status); 2260 release_transaction (p_transaction->lbl); 2261 return; 2262 } 2263 p_event->label = p_transaction->lbl; 2264 p_event->status = eREGISTERED; 2265 p_context->rc_status_cmd.label = p_transaction->lbl; 2266 p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION; 2267 2268 alarm_free(p_transaction->txn_timer); 2269 p_transaction->txn_timer = 2270 alarm_new("btif_rc.status_command_txn_timer"); 2271 alarm_set_on_queue(p_transaction->txn_timer, 2272 BTIF_TIMEOUT_RC_INTERIM_RSP_MS, 2273 btif_rc_status_cmd_timer_timeout, p_context, 2274 btu_general_alarm_queue); 2275 } 2276 else 2277 { 2278 BTIF_TRACE_ERROR("%s Error No more Transaction label %d", 2279 __FUNCTION__, status); 2280 } 2281 } 2282 2283 static void start_status_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn) 2284 { 2285 btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context; 2286 p_context->rc_status_cmd.label = p_txn->lbl; 2287 p_context->rc_status_cmd.pdu_id = pdu_id; 2288 2289 alarm_free(p_txn->txn_timer); 2290 p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer"); 2291 alarm_set_on_queue(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS, 2292 btif_rc_status_cmd_timer_timeout, p_context, 2293 btu_general_alarm_queue); 2294 } 2295 2296 static void start_control_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn) 2297 { 2298 btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context; 2299 p_context->rc_control_cmd.label = p_txn->lbl; 2300 p_context->rc_control_cmd.pdu_id = pdu_id; 2301 2302 alarm_free(p_txn->txn_timer); 2303 p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer"); 2304 alarm_set_on_queue(p_txn->txn_timer, 2305 BTIF_TIMEOUT_RC_CONTROL_CMD_MS, 2306 btif_rc_control_cmd_timer_timeout, p_context, 2307 btu_general_alarm_queue); 2308 } 2309 2310 /*************************************************************************** 2311 ** 2312 ** Function handle_get_capability_response 2313 ** 2314 ** Description Handles the get_cap_response to populate company id info 2315 ** and query the supported events. 2316 ** Initiates Notification registration for events supported 2317 ** Returns None 2318 ** 2319 ***************************************************************************/ 2320 static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp) 2321 { 2322 int xx = 0; 2323 2324 /* Todo: Do we need to retry on command timeout */ 2325 if (p_rsp->status != AVRC_STS_NO_ERROR) 2326 { 2327 BTIF_TRACE_ERROR("%s Error capability response 0x%02X", 2328 __FUNCTION__, p_rsp->status); 2329 return; 2330 } 2331 2332 if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED) 2333 { 2334 btif_rc_supported_event_t *p_event; 2335 2336 /* Todo: Check if list can be active when we hit here */ 2337 btif_rc_cb.rc_supported_event_list = list_new(osi_free); 2338 for (xx = 0; xx < p_rsp->count; xx++) 2339 { 2340 /* Skip registering for Play position change notification */ 2341 if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE)|| 2342 (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE)|| 2343 (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE)) 2344 { 2345 p_event = (btif_rc_supported_event_t *)osi_malloc(sizeof(btif_rc_supported_event_t)); 2346 p_event->event_id = p_rsp->param.event_id[xx]; 2347 p_event->status = eNOT_REGISTERED; 2348 list_append(btif_rc_cb.rc_supported_event_list, p_event); 2349 } 2350 } 2351 p_event = list_front(btif_rc_cb.rc_supported_event_list); 2352 if (p_event != NULL) 2353 { 2354 register_for_event_notification(p_event); 2355 } 2356 } 2357 else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) 2358 { 2359 getcapabilities_cmd (AVRC_CAP_EVENTS_SUPPORTED); 2360 BTIF_TRACE_EVENT("%s AVRC_CAP_COMPANY_ID: ", __FUNCTION__); 2361 for (xx = 0; xx < p_rsp->count; xx++) 2362 { 2363 BTIF_TRACE_EVENT("%s : %d", __FUNCTION__, p_rsp->param.company_id[xx]); 2364 } 2365 } 2366 } 2367 2368 bool rc_is_track_id_valid (tAVRC_UID uid) 2369 { 2370 tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 2371 2372 if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0) 2373 { 2374 return false; 2375 } 2376 else 2377 { 2378 return true; 2379 } 2380 } 2381 2382 /*************************************************************************** 2383 ** 2384 ** Function handle_notification_response 2385 ** 2386 ** Description Main handler for notification responses to registered events 2387 ** 1. Register for unregistered event(in interim response path) 2388 ** 2. After registering for all supported events, start 2389 ** retrieving application settings and values 2390 ** 3. Reregister for events on getting changed response 2391 ** 4. Run play status timer for getting position when the 2392 ** status changes to playing 2393 ** 5. Get the Media details when the track change happens 2394 ** or track change interim response is received with 2395 ** valid track id 2396 ** 6. HAL callback for play status change and application 2397 ** setting change 2398 ** Returns None 2399 ** 2400 ***************************************************************************/ 2401 static void handle_notification_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_REG_NOTIF_RSP *p_rsp) 2402 { 2403 bt_bdaddr_t rc_addr; 2404 UINT32 attr_list[] = { 2405 AVRC_MEDIA_ATTR_ID_TITLE, 2406 AVRC_MEDIA_ATTR_ID_ARTIST, 2407 AVRC_MEDIA_ATTR_ID_ALBUM, 2408 AVRC_MEDIA_ATTR_ID_TRACK_NUM, 2409 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, 2410 AVRC_MEDIA_ATTR_ID_GENRE, 2411 AVRC_MEDIA_ATTR_ID_PLAYING_TIME 2412 }; 2413 2414 2415 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 2416 2417 if (pmeta_msg->code == AVRC_RSP_INTERIM) 2418 { 2419 btif_rc_supported_event_t *p_event; 2420 list_node_t *node; 2421 2422 BTIF_TRACE_DEBUG("%s Interim response : 0x%2X ", __FUNCTION__, p_rsp->event_id); 2423 switch (p_rsp->event_id) 2424 { 2425 case AVRC_EVT_PLAY_STATUS_CHANGE: 2426 /* Start timer to get play status periodically 2427 * if the play state is playing. 2428 */ 2429 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING) 2430 { 2431 rc_start_play_status_timer(); 2432 } 2433 HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb, 2434 &rc_addr, p_rsp->param.play_status); 2435 break; 2436 2437 case AVRC_EVT_TRACK_CHANGE: 2438 if (rc_is_track_id_valid (p_rsp->param.track) != true) 2439 { 2440 break; 2441 } 2442 else 2443 { 2444 UINT8 *p_data = p_rsp->param.track; 2445 /* Update the UID for current track 2446 * Attributes will be fetched after the AVRCP procedure 2447 */ 2448 BE_STREAM_TO_UINT64(btif_rc_cb.rc_playing_uid, p_data); 2449 } 2450 break; 2451 2452 case AVRC_EVT_APP_SETTING_CHANGE: 2453 break; 2454 2455 case AVRC_EVT_NOW_PLAYING_CHANGE: 2456 break; 2457 2458 case AVRC_EVT_AVAL_PLAYERS_CHANGE: 2459 break; 2460 2461 case AVRC_EVT_ADDR_PLAYER_CHANGE: 2462 break; 2463 2464 case AVRC_EVT_UIDS_CHANGE: 2465 break; 2466 2467 case AVRC_EVT_TRACK_REACHED_END: 2468 case AVRC_EVT_TRACK_REACHED_START: 2469 case AVRC_EVT_PLAY_POS_CHANGED: 2470 case AVRC_EVT_BATTERY_STATUS_CHANGE: 2471 case AVRC_EVT_SYSTEM_STATUS_CHANGE: 2472 default: 2473 BTIF_TRACE_ERROR("%s Unhandled interim response 0x%2X", __FUNCTION__, 2474 p_rsp->event_id); 2475 return; 2476 } 2477 list_foreach(btif_rc_cb.rc_supported_event_list, 2478 iterate_supported_event_list_for_interim_rsp, 2479 &p_rsp->event_id); 2480 2481 node = list_begin(btif_rc_cb.rc_supported_event_list); 2482 while (node != NULL) 2483 { 2484 p_event = (btif_rc_supported_event_t *)list_node(node); 2485 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) 2486 { 2487 register_for_event_notification(p_event); 2488 break; 2489 } 2490 node = list_next (node); 2491 p_event = NULL; 2492 } 2493 /* Registered for all events, we can request application settings */ 2494 if ((p_event == NULL) && (btif_rc_cb.rc_app_settings.query_started == false)) 2495 { 2496 /* we need to do this only if remote TG supports 2497 * player application settings 2498 */ 2499 btif_rc_cb.rc_app_settings.query_started = TRUE; 2500 if (btif_rc_cb.rc_features & BTA_AV_FEAT_APP_SETTING) 2501 { 2502 list_player_app_setting_attrib_cmd(); 2503 } 2504 else 2505 { 2506 BTIF_TRACE_DEBUG("%s App setting not supported, complete procedure", __FUNCTION__); 2507 rc_ctrl_procedure_complete(); 2508 } 2509 } 2510 } 2511 else if (pmeta_msg->code == AVRC_RSP_CHANGED) 2512 { 2513 btif_rc_supported_event_t *p_event; 2514 list_node_t *node; 2515 2516 BTIF_TRACE_DEBUG("%s Notification completed : 0x%2X ", __FUNCTION__, 2517 p_rsp->event_id); 2518 2519 node = list_begin(btif_rc_cb.rc_supported_event_list); 2520 while (node != NULL) 2521 { 2522 p_event = (btif_rc_supported_event_t *)list_node(node); 2523 if ((p_event != NULL) && (p_event->event_id == p_rsp->event_id)) 2524 { 2525 p_event->status = eNOT_REGISTERED; 2526 register_for_event_notification(p_event); 2527 break; 2528 } 2529 node = list_next (node); 2530 } 2531 2532 switch (p_rsp->event_id) 2533 { 2534 case AVRC_EVT_PLAY_STATUS_CHANGE: 2535 /* Start timer to get play status periodically 2536 * if the play state is playing. 2537 */ 2538 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING) 2539 { 2540 rc_start_play_status_timer(); 2541 } 2542 else 2543 { 2544 rc_stop_play_status_timer(); 2545 } 2546 HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb, 2547 &rc_addr, p_rsp->param.play_status); 2548 break; 2549 2550 case AVRC_EVT_TRACK_CHANGE: 2551 if (rc_is_track_id_valid (p_rsp->param.track) != true) 2552 { 2553 break; 2554 } 2555 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list); 2556 break; 2557 2558 case AVRC_EVT_APP_SETTING_CHANGE: 2559 { 2560 btrc_player_settings_t app_settings; 2561 UINT16 xx; 2562 2563 app_settings.num_attr = p_rsp->param.player_setting.num_attr; 2564 for (xx = 0; xx < app_settings.num_attr; xx++) 2565 { 2566 app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx]; 2567 app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx]; 2568 } 2569 HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb, 2570 &rc_addr, &app_settings); 2571 } 2572 break; 2573 2574 case AVRC_EVT_NOW_PLAYING_CHANGE: 2575 break; 2576 2577 case AVRC_EVT_AVAL_PLAYERS_CHANGE: 2578 break; 2579 2580 case AVRC_EVT_ADDR_PLAYER_CHANGE: 2581 break; 2582 2583 case AVRC_EVT_UIDS_CHANGE: 2584 break; 2585 2586 case AVRC_EVT_TRACK_REACHED_END: 2587 case AVRC_EVT_TRACK_REACHED_START: 2588 case AVRC_EVT_PLAY_POS_CHANGED: 2589 case AVRC_EVT_BATTERY_STATUS_CHANGE: 2590 case AVRC_EVT_SYSTEM_STATUS_CHANGE: 2591 default: 2592 BTIF_TRACE_ERROR("%s Unhandled completion response 0x%2X", 2593 __FUNCTION__, p_rsp->event_id); 2594 return; 2595 } 2596 } 2597 } 2598 2599 /*************************************************************************** 2600 ** 2601 ** Function handle_app_attr_response 2602 ** 2603 ** Description handles the the application attributes response and 2604 ** initiates procedure to fetch the attribute values 2605 ** Returns None 2606 ** 2607 ***************************************************************************/ 2608 static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp) 2609 { 2610 UINT8 xx; 2611 2612 if (p_rsp->status != AVRC_STS_NO_ERROR) 2613 { 2614 BTIF_TRACE_ERROR("%s Error getting Player application settings: 0x%2X", 2615 __FUNCTION__, p_rsp->status); 2616 rc_ctrl_procedure_complete(); 2617 return; 2618 } 2619 2620 for (xx = 0; xx < p_rsp->num_attr; xx++) 2621 { 2622 UINT8 st_index; 2623 2624 if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT) 2625 { 2626 st_index = btif_rc_cb.rc_app_settings.num_ext_attrs; 2627 btif_rc_cb.rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx]; 2628 btif_rc_cb.rc_app_settings.num_ext_attrs++; 2629 } 2630 else 2631 { 2632 st_index = btif_rc_cb.rc_app_settings.num_attrs; 2633 btif_rc_cb.rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx]; 2634 btif_rc_cb.rc_app_settings.num_attrs++; 2635 } 2636 } 2637 btif_rc_cb.rc_app_settings.attr_index = 0; 2638 btif_rc_cb.rc_app_settings.ext_attr_index = 0; 2639 btif_rc_cb.rc_app_settings.ext_val_index = 0; 2640 if (p_rsp->num_attr) 2641 { 2642 list_player_app_setting_value_cmd (btif_rc_cb.rc_app_settings.attrs[0].attr_id); 2643 } 2644 else 2645 { 2646 BTIF_TRACE_ERROR("%s No Player application settings found", 2647 __FUNCTION__); 2648 } 2649 } 2650 2651 /*************************************************************************** 2652 ** 2653 ** Function handle_app_val_response 2654 ** 2655 ** Description handles the the attributes value response and if extended 2656 ** menu is available, it initiates query for the attribute 2657 ** text. If not, it initiates procedure to get the current 2658 ** attribute values and calls the HAL callback for provding 2659 ** application settings information. 2660 ** Returns None 2661 ** 2662 ***************************************************************************/ 2663 static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp) 2664 { 2665 UINT8 xx, attr_index; 2666 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; 2667 btif_rc_player_app_settings_t *p_app_settings; 2668 bt_bdaddr_t rc_addr; 2669 2670 /* Todo: Do we need to retry on command timeout */ 2671 if (p_rsp->status != AVRC_STS_NO_ERROR) 2672 { 2673 BTIF_TRACE_ERROR("%s Error fetching attribute values 0x%02X", 2674 __FUNCTION__, p_rsp->status); 2675 return; 2676 } 2677 2678 p_app_settings = &btif_rc_cb.rc_app_settings; 2679 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 2680 2681 if (p_app_settings->attr_index < p_app_settings->num_attrs) 2682 { 2683 attr_index = p_app_settings->attr_index; 2684 p_app_settings->attrs[attr_index].num_val = p_rsp->num_val; 2685 for (xx = 0; xx < p_rsp->num_val; xx++) 2686 { 2687 p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx]; 2688 } 2689 attr_index++; 2690 p_app_settings->attr_index++; 2691 if (attr_index < p_app_settings->num_attrs) 2692 { 2693 list_player_app_setting_value_cmd (p_app_settings->attrs[p_app_settings->attr_index].attr_id); 2694 } 2695 else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) 2696 { 2697 attr_index = 0; 2698 p_app_settings->ext_attr_index = 0; 2699 list_player_app_setting_value_cmd (p_app_settings->ext_attrs[attr_index].attr_id); 2700 } 2701 else 2702 { 2703 for (xx = 0; xx < p_app_settings->num_attrs; xx++) 2704 { 2705 attrs[xx] = p_app_settings->attrs[xx].attr_id; 2706 } 2707 get_player_app_setting_cmd (p_app_settings->num_attrs, attrs); 2708 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr, 2709 p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL); 2710 } 2711 } 2712 else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) 2713 { 2714 attr_index = p_app_settings->ext_attr_index; 2715 p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val; 2716 for (xx = 0; xx < p_rsp->num_val; xx++) 2717 { 2718 p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx]; 2719 } 2720 attr_index++; 2721 p_app_settings->ext_attr_index++; 2722 if (attr_index < p_app_settings->num_ext_attrs) 2723 { 2724 list_player_app_setting_value_cmd (p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id); 2725 } 2726 else 2727 { 2728 UINT8 attr[AVRC_MAX_APP_ATTR_SIZE]; 2729 UINT8 xx; 2730 2731 for (xx = 0; xx < p_app_settings->num_ext_attrs; xx++) 2732 { 2733 attr[xx] = p_app_settings->ext_attrs[xx].attr_id; 2734 } 2735 get_player_app_setting_attr_text_cmd(attr, xx); 2736 } 2737 } 2738 } 2739 2740 /*************************************************************************** 2741 ** 2742 ** Function handle_app_cur_val_response 2743 ** 2744 ** Description handles the the get attributes value response. 2745 ** 2746 ** Returns None 2747 ** 2748 ***************************************************************************/ 2749 static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp) 2750 { 2751 btrc_player_settings_t app_settings; 2752 bt_bdaddr_t rc_addr; 2753 UINT16 xx; 2754 2755 /* Todo: Do we need to retry on command timeout */ 2756 if (p_rsp->status != AVRC_STS_NO_ERROR) 2757 { 2758 BTIF_TRACE_ERROR("%s Error fetching current settings: 0x%02X", 2759 __FUNCTION__, p_rsp->status); 2760 return; 2761 } 2762 2763 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 2764 2765 app_settings.num_attr = p_rsp->num_val; 2766 for (xx = 0; xx < app_settings.num_attr; xx++) 2767 { 2768 app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id; 2769 app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val; 2770 } 2771 HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb, 2772 &rc_addr, &app_settings); 2773 /* Application settings are fetched only once for initial values 2774 * initiate anything that follows after RC procedure. 2775 * Defer it if browsing is supported till players query 2776 */ 2777 rc_ctrl_procedure_complete (); 2778 osi_free_and_reset((void **)&p_rsp->p_vals); 2779 } 2780 2781 /*************************************************************************** 2782 ** 2783 ** Function handle_app_attr_txt_response 2784 ** 2785 ** Description handles the the get attributes text response, if fails 2786 ** calls HAL callback with just normal settings and initiates 2787 ** query for current settings else initiates query for value text 2788 ** Returns None 2789 ** 2790 ***************************************************************************/ 2791 static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp) 2792 { 2793 UINT8 xx; 2794 UINT8 vals[AVRC_MAX_APP_ATTR_SIZE]; 2795 btif_rc_player_app_settings_t *p_app_settings; 2796 bt_bdaddr_t rc_addr; 2797 2798 p_app_settings = &btif_rc_cb.rc_app_settings; 2799 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 2800 2801 /* Todo: Do we need to retry on command timeout */ 2802 if (p_rsp->status != AVRC_STS_NO_ERROR) 2803 { 2804 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; 2805 2806 BTIF_TRACE_ERROR("%s Error fetching attribute text: 0x%02X", 2807 __FUNCTION__, p_rsp->status); 2808 /* Not able to fetch Text for extended Menu, skip the process 2809 * and cleanup used memory. Proceed to get the current settings 2810 * for standard attributes. 2811 */ 2812 p_app_settings->num_ext_attrs = 0; 2813 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) 2814 osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str); 2815 p_app_settings->ext_attr_index = 0; 2816 2817 for (xx = 0; xx < p_app_settings->num_attrs; xx++) 2818 { 2819 attrs[xx] = p_app_settings->attrs[xx].attr_id; 2820 } 2821 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr, 2822 p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL); 2823 2824 get_player_app_setting_cmd (xx, attrs); 2825 return; 2826 } 2827 2828 for (xx = 0; xx < p_rsp->num_attr; xx++) 2829 { 2830 UINT8 x; 2831 for (x = 0; x < p_app_settings->num_ext_attrs; x++) 2832 { 2833 if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) 2834 { 2835 p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id; 2836 p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len; 2837 p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str; 2838 break; 2839 } 2840 } 2841 } 2842 2843 for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++) 2844 { 2845 vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val; 2846 } 2847 get_player_app_setting_value_text_cmd(vals, xx); 2848 } 2849 2850 2851 /*************************************************************************** 2852 ** 2853 ** Function handle_app_attr_val_txt_response 2854 ** 2855 ** Description handles the the get attributes value text response, if fails 2856 ** calls HAL callback with just normal settings and initiates 2857 ** query for current settings 2858 ** Returns None 2859 ** 2860 ***************************************************************************/ 2861 static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp) 2862 { 2863 UINT8 xx, attr_index; 2864 UINT8 vals[AVRC_MAX_APP_ATTR_SIZE]; 2865 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; 2866 btif_rc_player_app_settings_t *p_app_settings; 2867 bt_bdaddr_t rc_addr; 2868 2869 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 2870 p_app_settings = &btif_rc_cb.rc_app_settings; 2871 2872 /* Todo: Do we need to retry on command timeout */ 2873 if (p_rsp->status != AVRC_STS_NO_ERROR) 2874 { 2875 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE]; 2876 2877 BTIF_TRACE_ERROR("%s Error fetching attribute value text: 0x%02X", 2878 __FUNCTION__, p_rsp->status); 2879 2880 /* Not able to fetch Text for extended Menu, skip the process 2881 * and cleanup used memory. Proceed to get the current settings 2882 * for standard attributes. 2883 */ 2884 p_app_settings->num_ext_attrs = 0; 2885 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) 2886 { 2887 int x; 2888 btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx]; 2889 2890 for (x = 0; x < p_ext_attr->num_val; x++) 2891 osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str); 2892 p_ext_attr->num_val = 0; 2893 osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str); 2894 } 2895 p_app_settings->ext_attr_index = 0; 2896 2897 for (xx = 0; xx < p_app_settings->num_attrs; xx++) 2898 { 2899 attrs[xx] = p_app_settings->attrs[xx].attr_id; 2900 } 2901 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr, 2902 p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL); 2903 2904 get_player_app_setting_cmd (xx, attrs); 2905 return; 2906 } 2907 2908 for (xx = 0; xx < p_rsp->num_attr; xx++) 2909 { 2910 UINT8 x; 2911 btrc_player_app_ext_attr_t *p_ext_attr; 2912 p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index]; 2913 for (x = 0; x < p_rsp->num_attr; x++) 2914 { 2915 if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) 2916 { 2917 p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id; 2918 p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len; 2919 p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str; 2920 break; 2921 } 2922 } 2923 } 2924 p_app_settings->ext_val_index++; 2925 2926 if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs) 2927 { 2928 attr_index = p_app_settings->ext_val_index; 2929 for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++) 2930 { 2931 vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val; 2932 } 2933 get_player_app_setting_value_text_cmd(vals, xx); 2934 } 2935 else 2936 { 2937 UINT8 x; 2938 2939 for (xx = 0; xx < p_app_settings->num_attrs; xx++) 2940 { 2941 attrs[xx] = p_app_settings->attrs[xx].attr_id; 2942 } 2943 for (x = 0; x < p_app_settings->num_ext_attrs; x++) 2944 { 2945 attrs[xx+x] = p_app_settings->ext_attrs[x].attr_id; 2946 } 2947 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr, 2948 p_app_settings->num_attrs, p_app_settings->attrs, 2949 p_app_settings->num_ext_attrs, p_app_settings->ext_attrs); 2950 get_player_app_setting_cmd (xx + x, attrs); 2951 2952 /* Free the application settings information after sending to 2953 * application. 2954 */ 2955 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) 2956 { 2957 int x; 2958 btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx]; 2959 2960 for (x = 0; x < p_ext_attr->num_val; x++) 2961 osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str); 2962 p_ext_attr->num_val = 0; 2963 osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str); 2964 } 2965 p_app_settings->num_attrs = 0; 2966 } 2967 } 2968 2969 /*************************************************************************** 2970 ** 2971 ** Function handle_set_app_attr_val_response 2972 ** 2973 ** Description handles the the set attributes value response, if fails 2974 ** calls HAL callback to indicate the failure 2975 ** Returns None 2976 ** 2977 ***************************************************************************/ 2978 static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp) 2979 { 2980 uint8_t accepted = 0; 2981 bt_bdaddr_t rc_addr; 2982 2983 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 2984 2985 /* For timeout pmeta_msg will be NULL, else we need to 2986 * check if this is accepted by TG 2987 */ 2988 if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT)) 2989 { 2990 accepted = 1; 2991 } 2992 HAL_CBACK(bt_rc_ctrl_callbacks, setplayerappsetting_rsp_cb, &rc_addr, accepted); 2993 } 2994 2995 /*************************************************************************** 2996 ** 2997 ** Function handle_get_elem_attr_response 2998 ** 2999 ** Description handles the the element attributes response, calls 3000 ** HAL callback to update track change information. 3001 ** Returns None 3002 ** 3003 ***************************************************************************/ 3004 static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, 3005 tAVRC_GET_ELEM_ATTRS_RSP *p_rsp) 3006 { 3007 if (p_rsp->status == AVRC_STS_NO_ERROR) { 3008 bt_bdaddr_t rc_addr; 3009 size_t buf_size = p_rsp->num_attr * sizeof(btrc_element_attr_val_t); 3010 btrc_element_attr_val_t *p_attr = 3011 (btrc_element_attr_val_t *)osi_calloc(buf_size); 3012 3013 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 3014 3015 for (int i = 0; i < p_rsp->num_attr; i++) { 3016 p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id; 3017 /* Todo. Legth limit check to include null */ 3018 if (p_rsp->p_attrs[i].name.str_len && 3019 p_rsp->p_attrs[i].name.p_str) { 3020 memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str, 3021 p_rsp->p_attrs[i].name.str_len); 3022 osi_free_and_reset((void **)&p_rsp->p_attrs[i].name.p_str); 3023 } 3024 } 3025 HAL_CBACK(bt_rc_ctrl_callbacks, track_changed_cb, 3026 &rc_addr, p_rsp->num_attr, p_attr); 3027 osi_free(p_attr); 3028 } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) { 3029 /* Retry for timeout case, this covers error handling 3030 * for continuation failure also. 3031 */ 3032 UINT32 attr_list[] = { 3033 AVRC_MEDIA_ATTR_ID_TITLE, 3034 AVRC_MEDIA_ATTR_ID_ARTIST, 3035 AVRC_MEDIA_ATTR_ID_ALBUM, 3036 AVRC_MEDIA_ATTR_ID_TRACK_NUM, 3037 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, 3038 AVRC_MEDIA_ATTR_ID_GENRE, 3039 AVRC_MEDIA_ATTR_ID_PLAYING_TIME 3040 }; 3041 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list); 3042 } else { 3043 BTIF_TRACE_ERROR("%s: Error in get element attr procedure %d", 3044 __func__, p_rsp->status); 3045 } 3046 } 3047 3048 /*************************************************************************** 3049 ** 3050 ** Function handle_get_playstatus_response 3051 ** 3052 ** Description handles the the play status response, calls 3053 ** HAL callback to update play position. 3054 ** Returns None 3055 ** 3056 ***************************************************************************/ 3057 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp) 3058 { 3059 bt_bdaddr_t rc_addr; 3060 3061 bdcpy(rc_addr.address, btif_rc_cb.rc_addr); 3062 3063 if (p_rsp->status == AVRC_STS_NO_ERROR) 3064 { 3065 HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb, 3066 &rc_addr, p_rsp->song_len, p_rsp->song_pos); 3067 } 3068 else 3069 { 3070 BTIF_TRACE_ERROR("%s: Error in get play status procedure %d", 3071 __FUNCTION__, p_rsp->status); 3072 } 3073 } 3074 3075 /*************************************************************************** 3076 ** 3077 ** Function clear_cmd_timeout 3078 ** 3079 ** Description helper function to stop the command timeout timer 3080 ** Returns None 3081 ** 3082 ***************************************************************************/ 3083 static void clear_cmd_timeout (UINT8 label) 3084 { 3085 rc_transaction_t *p_txn; 3086 3087 p_txn = get_transaction_by_lbl (label); 3088 if (p_txn == NULL) 3089 { 3090 BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __FUNCTION__); 3091 return; 3092 } 3093 3094 if (p_txn->txn_timer != NULL) 3095 alarm_cancel(p_txn->txn_timer); 3096 } 3097 3098 /*************************************************************************** 3099 ** 3100 ** Function handle_avk_rc_metamsg_rsp 3101 ** 3102 ** Description Handle RC metamessage response 3103 ** 3104 ** Returns void 3105 ** 3106 ***************************************************************************/ 3107 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg) 3108 { 3109 tAVRC_RESPONSE avrc_response = {0}; 3110 UINT8 scratch_buf[512] = {0};// this variable is unused 3111 UINT16 buf_len; 3112 tAVRC_STS status; 3113 3114 BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d ", __FUNCTION__, 3115 pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); 3116 3117 if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode)&& 3118 (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)&& 3119 (pmeta_msg->code <= AVRC_RSP_INTERIM)) 3120 { 3121 status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len); 3122 BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d", 3123 __FUNCTION__, status, avrc_response.pdu, 3124 pmeta_msg->p_msg->vendor.hdr.ctype); 3125 3126 switch (avrc_response.pdu) 3127 { 3128 case AVRC_PDU_REGISTER_NOTIFICATION: 3129 handle_notification_response(pmeta_msg, &avrc_response.reg_notif); 3130 if (pmeta_msg->code == AVRC_RSP_INTERIM) 3131 { 3132 /* Don't free the transaction Id */ 3133 clear_cmd_timeout (pmeta_msg->label); 3134 return; 3135 } 3136 break; 3137 3138 case AVRC_PDU_GET_CAPABILITIES: 3139 handle_get_capability_response(pmeta_msg, &avrc_response.get_caps); 3140 break; 3141 3142 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 3143 handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr); 3144 break; 3145 3146 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 3147 handle_app_val_response(pmeta_msg, &avrc_response.list_app_values); 3148 break; 3149 3150 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 3151 handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val); 3152 break; 3153 3154 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 3155 handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt); 3156 break; 3157 3158 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 3159 handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt); 3160 break; 3161 3162 case AVRC_PDU_SET_PLAYER_APP_VALUE: 3163 handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val); 3164 break; 3165 3166 case AVRC_PDU_GET_ELEMENT_ATTR: 3167 handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_elem_attrs); 3168 break; 3169 3170 case AVRC_PDU_GET_PLAY_STATUS: 3171 handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status); 3172 break; 3173 } 3174 release_transaction(pmeta_msg->label); 3175 } 3176 else 3177 { 3178 BTIF_TRACE_DEBUG("%s:Invalid Vendor Command code: %d len: %d. Not processing it.", 3179 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 3180 return; 3181 } 3182 } 3183 3184 /*************************************************************************** 3185 ** 3186 ** Function handle_avk_rc_metamsg_cmd 3187 ** 3188 ** Description Handle RC metamessage response 3189 ** 3190 ** Returns void 3191 ** 3192 ***************************************************************************/ 3193 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg) 3194 { 3195 tAVRC_COMMAND avrc_cmd = {0}; 3196 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3197 BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d ",__FUNCTION__, 3198 pmeta_msg->p_msg->hdr.opcode,pmeta_msg->code); 3199 if ((AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode)&& 3200 (pmeta_msg->code <= AVRC_CMD_GEN_INQ)) 3201 { 3202 status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd); 3203 BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d", 3204 __FUNCTION__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label); 3205 3206 if (status != AVRC_STS_NO_ERROR) 3207 { 3208 /* return error */ 3209 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x", 3210 __FUNCTION__, status); 3211 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status); 3212 } 3213 else 3214 { 3215 if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) 3216 { 3217 UINT8 event_id = avrc_cmd.reg_notif.event_id; 3218 BTIF_TRACE_EVENT("%s:Register notification event_id: %s", 3219 __FUNCTION__, dump_rc_notification_event_id(event_id)); 3220 } 3221 else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) 3222 { 3223 BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __FUNCTION__); 3224 } 3225 btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label); 3226 } 3227 } 3228 else 3229 { 3230 BTIF_TRACE_DEBUG("%s:Invalid Vendor Command code: %d len: %d. Not processing it.", 3231 __FUNCTION__, pmeta_msg->code, pmeta_msg->len); 3232 return; 3233 } 3234 } 3235 #endif 3236 3237 /*************************************************************************** 3238 ** 3239 ** Function cleanup 3240 ** 3241 ** Description Closes the AVRC interface 3242 ** 3243 ** Returns void 3244 ** 3245 ***************************************************************************/ 3246 static void cleanup() 3247 { 3248 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 3249 close_uinput(); 3250 if (bt_rc_callbacks) 3251 { 3252 bt_rc_callbacks = NULL; 3253 } 3254 alarm_free(btif_rc_cb.rc_play_status_timer); 3255 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t)); 3256 lbl_destroy(); 3257 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__); 3258 } 3259 3260 /*************************************************************************** 3261 ** 3262 ** Function cleanup_ctrl 3263 ** 3264 ** Description Closes the AVRC Controller interface 3265 ** 3266 ** Returns void 3267 ** 3268 ***************************************************************************/ 3269 static void cleanup_ctrl() 3270 { 3271 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__); 3272 3273 if (bt_rc_ctrl_callbacks) 3274 { 3275 bt_rc_ctrl_callbacks = NULL; 3276 } 3277 alarm_free(btif_rc_cb.rc_play_status_timer); 3278 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t)); 3279 lbl_destroy(); 3280 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__); 3281 } 3282 3283 /*************************************************************************** 3284 ** 3285 ** Function getcapabilities_cmd 3286 ** 3287 ** Description GetCapabilties from Remote(Company_ID, Events_Supported) 3288 ** 3289 ** Returns void 3290 ** 3291 ***************************************************************************/ 3292 static bt_status_t getcapabilities_cmd (uint8_t cap_id) 3293 { 3294 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3295 rc_transaction_t *p_transaction = NULL; 3296 #if (AVRC_CTLR_INCLUDED == TRUE) 3297 BTIF_TRACE_DEBUG("%s: cap_id %d", __FUNCTION__, cap_id); 3298 CHECK_RC_CONNECTED 3299 bt_status_t tran_status=get_transaction(&p_transaction); 3300 if (BT_STATUS_SUCCESS != tran_status) 3301 return BT_STATUS_FAIL; 3302 3303 tAVRC_COMMAND avrc_cmd = {0}; 3304 BT_HDR *p_msg = NULL; 3305 avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR; 3306 avrc_cmd.get_caps.capability_id = cap_id; 3307 avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES; 3308 avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR; 3309 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3310 if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL)) 3311 { 3312 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3313 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3314 __FUNCTION__,p_transaction->lbl); 3315 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS, 3316 data_start, p_msg->len); 3317 status = BT_STATUS_SUCCESS; 3318 start_status_command_timer (AVRC_PDU_GET_CAPABILITIES, p_transaction); 3319 } 3320 else 3321 { 3322 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3323 __FUNCTION__, status); 3324 } 3325 osi_free(p_msg); 3326 #else 3327 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3328 #endif 3329 return status; 3330 } 3331 3332 /*************************************************************************** 3333 ** 3334 ** Function list_player_app_setting_attrib_cmd 3335 ** 3336 ** Description Get supported List Player Attributes 3337 ** 3338 ** Returns void 3339 ** 3340 ***************************************************************************/ 3341 static bt_status_t list_player_app_setting_attrib_cmd(void) 3342 { 3343 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3344 rc_transaction_t *p_transaction = NULL; 3345 #if (AVRC_CTLR_INCLUDED == TRUE) 3346 BTIF_TRACE_DEBUG("%s: ", __FUNCTION__); 3347 CHECK_RC_CONNECTED 3348 bt_status_t tran_status=get_transaction(&p_transaction); 3349 if (BT_STATUS_SUCCESS != tran_status) 3350 return BT_STATUS_FAIL; 3351 3352 tAVRC_COMMAND avrc_cmd = {0}; 3353 BT_HDR *p_msg = NULL; 3354 avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR; 3355 avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR; 3356 avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR; 3357 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3358 if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL)) 3359 { 3360 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3361 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3362 __FUNCTION__,p_transaction->lbl); 3363 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS, 3364 data_start, p_msg->len); 3365 status = BT_STATUS_SUCCESS; 3366 start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_ATTR, p_transaction); 3367 } 3368 else 3369 { 3370 3371 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3372 __FUNCTION__, status); 3373 } 3374 osi_free(p_msg); 3375 #else 3376 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3377 #endif 3378 return status; 3379 } 3380 3381 /*************************************************************************** 3382 ** 3383 ** Function list_player_app_setting_value_cmd 3384 ** 3385 ** Description Get values of supported Player Attributes 3386 ** 3387 ** Returns void 3388 ** 3389 ***************************************************************************/ 3390 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id) 3391 { 3392 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3393 rc_transaction_t *p_transaction=NULL; 3394 #if (AVRC_CTLR_INCLUDED == TRUE) 3395 BTIF_TRACE_DEBUG("%s: attrib_id %d", __FUNCTION__, attrib_id); 3396 CHECK_RC_CONNECTED 3397 bt_status_t tran_status=get_transaction(&p_transaction); 3398 if (BT_STATUS_SUCCESS != tran_status) 3399 return BT_STATUS_FAIL; 3400 3401 tAVRC_COMMAND avrc_cmd = {0}; 3402 BT_HDR *p_msg = NULL; 3403 avrc_cmd.list_app_values.attr_id = attrib_id; 3404 avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR; 3405 avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES; 3406 avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR; 3407 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3408 if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL)) 3409 { 3410 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3411 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3412 __FUNCTION__,p_transaction->lbl); 3413 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS, 3414 data_start, p_msg->len); 3415 status = BT_STATUS_SUCCESS; 3416 start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_VALUES, p_transaction); 3417 } 3418 else 3419 { 3420 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status); 3421 } 3422 osi_free(p_msg); 3423 #else 3424 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3425 #endif 3426 return status; 3427 } 3428 3429 /*************************************************************************** 3430 ** 3431 ** Function get_player_app_setting_cmd 3432 ** 3433 ** Description Get current values of Player Attributes 3434 ** 3435 ** Returns void 3436 ** 3437 ***************************************************************************/ 3438 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids) 3439 { 3440 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3441 rc_transaction_t *p_transaction = NULL; 3442 int count = 0; 3443 #if (AVRC_CTLR_INCLUDED == TRUE) 3444 BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib); 3445 CHECK_RC_CONNECTED 3446 bt_status_t tran_status=get_transaction(&p_transaction); 3447 if (BT_STATUS_SUCCESS != tran_status) 3448 return BT_STATUS_FAIL; 3449 3450 tAVRC_COMMAND avrc_cmd = {0}; 3451 BT_HDR *p_msg = NULL; 3452 avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR; 3453 avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR; 3454 avrc_cmd.get_cur_app_val.num_attr = num_attrib; 3455 avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE; 3456 3457 for (count = 0; count < num_attrib; count++) 3458 { 3459 avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count]; 3460 } 3461 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3462 if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL)) 3463 { 3464 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3465 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3466 __FUNCTION__,p_transaction->lbl); 3467 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS, 3468 data_start, p_msg->len); 3469 status = BT_STATUS_SUCCESS; 3470 start_status_command_timer (AVRC_PDU_GET_CUR_PLAYER_APP_VALUE, p_transaction); 3471 } 3472 else 3473 { 3474 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3475 __FUNCTION__, status); 3476 } 3477 osi_free(p_msg); 3478 #else 3479 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3480 #endif 3481 return status; 3482 } 3483 3484 /*************************************************************************** 3485 ** 3486 ** Function change_player_app_setting 3487 ** 3488 ** Description Set current values of Player Attributes 3489 ** 3490 ** Returns void 3491 ** 3492 ***************************************************************************/ 3493 static bt_status_t change_player_app_setting(bt_bdaddr_t *bd_addr, uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals) 3494 { 3495 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3496 rc_transaction_t *p_transaction = NULL; 3497 int count = 0; 3498 #if (AVRC_CTLR_INCLUDED == TRUE) 3499 BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib); 3500 CHECK_RC_CONNECTED 3501 bt_status_t tran_status=get_transaction(&p_transaction); 3502 if (BT_STATUS_SUCCESS != tran_status) 3503 return BT_STATUS_FAIL; 3504 3505 tAVRC_COMMAND avrc_cmd = {0}; 3506 BT_HDR *p_msg = NULL; 3507 avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR; 3508 avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR; 3509 avrc_cmd.set_app_val.num_val = num_attrib; 3510 avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE; 3511 avrc_cmd.set_app_val.p_vals = 3512 (tAVRC_APP_SETTING *)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib); 3513 for (count = 0; count < num_attrib; count++) 3514 { 3515 avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count]; 3516 avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count]; 3517 } 3518 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3519 if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL)) 3520 { 3521 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3522 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3523 __FUNCTION__,p_transaction->lbl); 3524 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_CTRL, 3525 data_start, p_msg->len); 3526 status = BT_STATUS_SUCCESS; 3527 start_control_command_timer (AVRC_PDU_SET_PLAYER_APP_VALUE, p_transaction); 3528 } 3529 else 3530 { 3531 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3532 __FUNCTION__, status); 3533 } 3534 osi_free(p_msg); 3535 osi_free_and_reset((void **)&avrc_cmd.set_app_val.p_vals); 3536 #else 3537 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3538 #endif 3539 return status; 3540 } 3541 3542 /*************************************************************************** 3543 ** 3544 ** Function get_player_app_setting_attr_text_cmd 3545 ** 3546 ** Description Get text description for app attribute 3547 ** 3548 ** Returns void 3549 ** 3550 ***************************************************************************/ 3551 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs) 3552 { 3553 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3554 rc_transaction_t *p_transaction = NULL; 3555 int count = 0; 3556 #if (AVRC_CTLR_INCLUDED == TRUE) 3557 tAVRC_COMMAND avrc_cmd = {0}; 3558 BT_HDR *p_msg = NULL; 3559 bt_status_t tran_status; 3560 CHECK_RC_CONNECTED 3561 3562 BTIF_TRACE_DEBUG("%s: num attrs %d", __FUNCTION__, num_attrs); 3563 3564 tran_status = get_transaction(&p_transaction); 3565 if (BT_STATUS_SUCCESS != tran_status) 3566 return BT_STATUS_FAIL; 3567 3568 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT; 3569 avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR; 3570 avrc_cmd.get_app_attr_txt.num_attr = num_attrs; 3571 3572 for (count = 0; count < num_attrs; count++) 3573 { 3574 avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count]; 3575 } 3576 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3577 if (status == AVRC_STS_NO_ERROR) 3578 { 3579 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3580 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3581 __FUNCTION__, p_transaction->lbl); 3582 BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl, 3583 AVRC_CMD_STATUS, data_start, p_msg->len); 3584 osi_free(p_msg); 3585 status = BT_STATUS_SUCCESS; 3586 start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT, p_transaction); 3587 } 3588 else 3589 { 3590 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status); 3591 } 3592 osi_free(p_msg); 3593 #else 3594 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3595 #endif 3596 return status; 3597 } 3598 3599 /*************************************************************************** 3600 ** 3601 ** Function get_player_app_setting_val_text_cmd 3602 ** 3603 ** Description Get text description for app attribute values 3604 ** 3605 ** Returns void 3606 ** 3607 ***************************************************************************/ 3608 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals) 3609 { 3610 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3611 rc_transaction_t *p_transaction = NULL; 3612 int count = 0; 3613 #if (AVRC_CTLR_INCLUDED == TRUE) 3614 tAVRC_COMMAND avrc_cmd = {0}; 3615 BT_HDR *p_msg = NULL; 3616 bt_status_t tran_status; 3617 CHECK_RC_CONNECTED 3618 3619 BTIF_TRACE_DEBUG("%s: num_vals %d", __FUNCTION__, num_vals); 3620 3621 tran_status = get_transaction(&p_transaction); 3622 if (BT_STATUS_SUCCESS != tran_status) 3623 return BT_STATUS_FAIL; 3624 3625 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT; 3626 avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR; 3627 avrc_cmd.get_app_val_txt.num_val = num_vals; 3628 3629 for (count = 0; count < num_vals; count++) 3630 { 3631 avrc_cmd.get_app_val_txt.vals[count] = vals[count]; 3632 } 3633 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3634 if (status == AVRC_STS_NO_ERROR) 3635 { 3636 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3637 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3638 __FUNCTION__, p_transaction->lbl); 3639 if (p_msg != NULL) 3640 { 3641 BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl, 3642 AVRC_CMD_STATUS, data_start, p_msg->len); 3643 status = BT_STATUS_SUCCESS; 3644 start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT, p_transaction); 3645 } 3646 } 3647 else 3648 { 3649 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3650 __FUNCTION__, status); 3651 } 3652 osi_free(p_msg); 3653 #else 3654 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3655 #endif 3656 return status; 3657 } 3658 3659 /*************************************************************************** 3660 ** 3661 ** Function register_notification_cmd 3662 ** 3663 ** Description Send Command to register for a Notification ID 3664 ** 3665 ** Returns void 3666 ** 3667 ***************************************************************************/ 3668 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value) 3669 { 3670 3671 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3672 #if (AVRC_CTLR_INCLUDED == TRUE) 3673 tAVRC_COMMAND avrc_cmd = {0}; 3674 BT_HDR *p_msg = NULL; 3675 CHECK_RC_CONNECTED 3676 3677 3678 BTIF_TRACE_DEBUG("%s: event_id %d event_value", __FUNCTION__, event_id, event_value); 3679 3680 avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR; 3681 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR; 3682 avrc_cmd.reg_notif.event_id = event_id; 3683 avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 3684 avrc_cmd.reg_notif.param = event_value; 3685 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3686 if (status == AVRC_STS_NO_ERROR) 3687 { 3688 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3689 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3690 __FUNCTION__, label); 3691 if (p_msg != NULL) 3692 { 3693 BTA_AvVendorCmd(btif_rc_cb.rc_handle, label, AVRC_CMD_NOTIF, 3694 data_start, p_msg->len); 3695 status = BT_STATUS_SUCCESS; 3696 } 3697 } 3698 else 3699 { 3700 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3701 __FUNCTION__, status); 3702 } 3703 osi_free(p_msg); 3704 #else 3705 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3706 #endif 3707 return status; 3708 } 3709 3710 /*************************************************************************** 3711 ** 3712 ** Function get_element_attribute_cmd 3713 ** 3714 ** Description Get Element Attribute for attributeIds 3715 ** 3716 ** Returns void 3717 ** 3718 ***************************************************************************/ 3719 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids) 3720 { 3721 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3722 rc_transaction_t *p_transaction=NULL; 3723 int count = 0; 3724 #if (AVRC_CTLR_INCLUDED == TRUE) 3725 tAVRC_COMMAND avrc_cmd = {0}; 3726 BT_HDR *p_msg = NULL; 3727 bt_status_t tran_status; 3728 CHECK_RC_CONNECTED 3729 3730 BTIF_TRACE_DEBUG("%s: num_attribute %d attribute_id %d", 3731 __FUNCTION__, num_attribute, p_attr_ids[0]); 3732 3733 tran_status = get_transaction(&p_transaction); 3734 if (BT_STATUS_SUCCESS != tran_status) 3735 return BT_STATUS_FAIL; 3736 3737 avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR; 3738 avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR; 3739 avrc_cmd.get_elem_attrs.num_attr = num_attribute; 3740 avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 3741 for (count = 0; count < num_attribute; count++) 3742 { 3743 avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count]; 3744 } 3745 3746 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3747 if (status == AVRC_STS_NO_ERROR) 3748 { 3749 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3750 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3751 __FUNCTION__, p_transaction->lbl); 3752 if (p_msg != NULL) 3753 { 3754 BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl, 3755 AVRC_CMD_STATUS, data_start, p_msg->len); 3756 status = BT_STATUS_SUCCESS; 3757 start_status_command_timer (AVRC_PDU_GET_ELEMENT_ATTR, 3758 p_transaction); 3759 } 3760 } 3761 else 3762 { 3763 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3764 __FUNCTION__, status); 3765 } 3766 osi_free(p_msg); 3767 #else 3768 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3769 #endif 3770 return status; 3771 } 3772 3773 /*************************************************************************** 3774 ** 3775 ** Function get_play_status_cmd 3776 ** 3777 ** Description Get Element Attribute for attributeIds 3778 ** 3779 ** Returns void 3780 ** 3781 ***************************************************************************/ 3782 static bt_status_t get_play_status_cmd(void) 3783 { 3784 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3785 rc_transaction_t *p_transaction = NULL; 3786 #if (AVRC_CTLR_INCLUDED == TRUE) 3787 tAVRC_COMMAND avrc_cmd = {0}; 3788 BT_HDR *p_msg = NULL; 3789 bt_status_t tran_status; 3790 CHECK_RC_CONNECTED 3791 3792 BTIF_TRACE_DEBUG("%s: ", __FUNCTION__); 3793 tran_status = get_transaction(&p_transaction); 3794 if (BT_STATUS_SUCCESS != tran_status) 3795 return BT_STATUS_FAIL; 3796 3797 avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR; 3798 avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 3799 avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR; 3800 status = AVRC_BldCommand(&avrc_cmd, &p_msg); 3801 if (status == AVRC_STS_NO_ERROR) 3802 { 3803 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3804 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3805 __FUNCTION__, p_transaction->lbl); 3806 if (p_msg != NULL) 3807 { 3808 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl, 3809 AVRC_CMD_STATUS, data_start, p_msg->len); 3810 status = BT_STATUS_SUCCESS; 3811 start_status_command_timer (AVRC_PDU_GET_PLAY_STATUS, p_transaction); 3812 } 3813 } 3814 else 3815 { 3816 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3817 __FUNCTION__, status); 3818 } 3819 osi_free(p_msg); 3820 #else 3821 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3822 #endif 3823 return status; 3824 3825 } 3826 3827 /*************************************************************************** 3828 ** 3829 ** Function set_volume_rsp 3830 ** 3831 ** Description Rsp for SetAbsoluteVolume Command 3832 ** 3833 ** Returns void 3834 ** 3835 ***************************************************************************/ 3836 static bt_status_t set_volume_rsp(bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label) 3837 { 3838 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3839 #if (AVRC_CTLR_INCLUDED == TRUE) 3840 tAVRC_RESPONSE avrc_rsp; 3841 BT_HDR *p_msg = NULL; 3842 CHECK_RC_CONNECTED 3843 3844 BTIF_TRACE_DEBUG("%s: abs_vol %d", __FUNCTION__, abs_vol); 3845 3846 avrc_rsp.volume.opcode = AVRC_OP_VENDOR; 3847 avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME; 3848 avrc_rsp.volume.status = AVRC_STS_NO_ERROR; 3849 avrc_rsp.volume.volume = abs_vol; 3850 status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg); 3851 if (status == AVRC_STS_NO_ERROR) 3852 { 3853 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3854 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3855 __FUNCTION__, btif_rc_cb.rc_vol_label); 3856 if (p_msg != NULL) 3857 { 3858 BTA_AvVendorRsp(btif_rc_cb.rc_handle, label, 3859 BTA_AV_RSP_ACCEPT, data_start, p_msg->len, 0); 3860 status = BT_STATUS_SUCCESS; 3861 } 3862 } 3863 else 3864 { 3865 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3866 __FUNCTION__, status); 3867 } 3868 osi_free(p_msg); 3869 #else 3870 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3871 #endif 3872 return status; 3873 } 3874 3875 /*************************************************************************** 3876 ** 3877 ** Function send_register_abs_vol_rsp 3878 ** 3879 ** Description Rsp for Notification of Absolute Volume 3880 ** 3881 ** Returns void 3882 ** 3883 ***************************************************************************/ 3884 static bt_status_t volume_change_notification_rsp(bt_bdaddr_t *bd_addr, btrc_notification_type_t rsp_type, 3885 uint8_t abs_vol, uint8_t label) 3886 { 3887 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3888 tAVRC_RESPONSE avrc_rsp; 3889 BT_HDR *p_msg = NULL; 3890 #if (AVRC_CTLR_INCLUDED == TRUE) 3891 BTIF_TRACE_DEBUG("%s: rsp_type %d abs_vol %d", __func__, rsp_type, abs_vol); 3892 CHECK_RC_CONNECTED 3893 3894 avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR; 3895 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 3896 avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR; 3897 avrc_rsp.reg_notif.param.volume = abs_vol; 3898 avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE; 3899 3900 status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg); 3901 if (status == AVRC_STS_NO_ERROR) { 3902 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", 3903 __func__, label); 3904 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset; 3905 BTA_AvVendorRsp(btif_rc_cb.rc_handle, label, 3906 (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ? 3907 AVRC_RSP_INTERIM : AVRC_RSP_CHANGED, 3908 data_start, p_msg->len, 0); 3909 status = BT_STATUS_SUCCESS; 3910 } else { 3911 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", 3912 __func__, status); 3913 } 3914 osi_free(p_msg); 3915 3916 #else 3917 BTIF_TRACE_DEBUG("%s: feature not enabled", __func__); 3918 #endif 3919 return status; 3920 } 3921 3922 /*************************************************************************** 3923 ** 3924 ** Function send_groupnavigation_cmd 3925 ** 3926 ** Description Send Pass-Through command 3927 ** 3928 ** Returns void 3929 ** 3930 ***************************************************************************/ 3931 static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, 3932 uint8_t key_state) 3933 { 3934 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3935 #if (AVRC_CTLR_INCLUDED == TRUE) 3936 rc_transaction_t *p_transaction=NULL; 3937 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__, 3938 key_code, key_state); 3939 CHECK_RC_CONNECTED 3940 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 3941 { 3942 bt_status_t tran_status = get_transaction(&p_transaction); 3943 if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) { 3944 UINT8 buffer[AVRC_PASS_THRU_GROUP_LEN] = {0}; 3945 UINT8* start = buffer; 3946 UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA); 3947 *(start)++ = 0; 3948 UINT8_TO_BE_STREAM(start, key_code); 3949 BTA_AvRemoteVendorUniqueCmd(btif_rc_cb.rc_handle, 3950 p_transaction->lbl, 3951 (tBTA_AV_STATE)key_state, buffer, 3952 AVRC_PASS_THRU_GROUP_LEN); 3953 status = BT_STATUS_SUCCESS; 3954 BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA", 3955 __FUNCTION__); 3956 } 3957 else 3958 { 3959 status = BT_STATUS_FAIL; 3960 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__); 3961 } 3962 } 3963 else 3964 { 3965 status = BT_STATUS_FAIL; 3966 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__); 3967 } 3968 #else 3969 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 3970 #endif 3971 return status; 3972 } 3973 3974 /*************************************************************************** 3975 ** 3976 ** Function send_passthrough_cmd 3977 ** 3978 ** Description Send Pass-Through command 3979 ** 3980 ** Returns void 3981 ** 3982 ***************************************************************************/ 3983 static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state) 3984 { 3985 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 3986 #if (AVRC_CTLR_INCLUDED == TRUE) 3987 CHECK_RC_CONNECTED 3988 rc_transaction_t *p_transaction=NULL; 3989 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__, 3990 key_code, key_state); 3991 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) 3992 { 3993 bt_status_t tran_status = get_transaction(&p_transaction); 3994 if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction) 3995 { 3996 BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl, 3997 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state); 3998 status = BT_STATUS_SUCCESS; 3999 BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__); 4000 } 4001 else 4002 { 4003 status = BT_STATUS_FAIL; 4004 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__); 4005 } 4006 } 4007 else 4008 { 4009 status = BT_STATUS_FAIL; 4010 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__); 4011 } 4012 #else 4013 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__); 4014 #endif 4015 return status; 4016 } 4017 4018 static const btrc_interface_t bt_rc_interface = { 4019 sizeof(bt_rc_interface), 4020 init, 4021 get_play_status_rsp, 4022 NULL, /* list_player_app_attr_rsp */ 4023 NULL, /* list_player_app_value_rsp */ 4024 NULL, /* get_player_app_value_rsp */ 4025 NULL, /* get_player_app_attr_text_rsp */ 4026 NULL, /* get_player_app_value_text_rsp */ 4027 get_element_attr_rsp, 4028 NULL, /* set_player_app_value_rsp */ 4029 register_notification_rsp, 4030 set_volume, 4031 cleanup, 4032 }; 4033 4034 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = { 4035 sizeof(bt_rc_ctrl_interface), 4036 init_ctrl, 4037 send_passthrough_cmd, 4038 send_groupnavigation_cmd, 4039 change_player_app_setting, 4040 set_volume_rsp, 4041 volume_change_notification_rsp, 4042 cleanup_ctrl, 4043 }; 4044 4045 /******************************************************************************* 4046 ** 4047 ** Function btif_rc_get_interface 4048 ** 4049 ** Description Get the AVRCP Target callback interface 4050 ** 4051 ** Returns btav_interface_t 4052 ** 4053 *******************************************************************************/ 4054 const btrc_interface_t *btif_rc_get_interface(void) 4055 { 4056 BTIF_TRACE_EVENT("%s", __FUNCTION__); 4057 return &bt_rc_interface; 4058 } 4059 4060 /******************************************************************************* 4061 ** 4062 ** Function btif_rc_ctrl_get_interface 4063 ** 4064 ** Description Get the AVRCP Controller callback interface 4065 ** 4066 ** Returns btav_interface_t 4067 ** 4068 *******************************************************************************/ 4069 const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void) 4070 { 4071 BTIF_TRACE_EVENT("%s", __FUNCTION__); 4072 return &bt_rc_ctrl_interface; 4073 } 4074 4075 /******************************************************************************* 4076 ** Function initialize_transaction 4077 ** 4078 ** Description Initializes fields of the transaction structure 4079 ** 4080 ** Returns void 4081 *******************************************************************************/ 4082 static void initialize_transaction(int lbl) 4083 { 4084 pthread_mutex_lock(&device.lbllock); 4085 if (lbl < MAX_TRANSACTIONS_PER_SESSION) { 4086 if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) { 4087 clear_cmd_timeout(lbl); 4088 } 4089 device.transaction[lbl].lbl = lbl; 4090 device.transaction[lbl].in_use=FALSE; 4091 device.transaction[lbl].handle=0; 4092 } 4093 pthread_mutex_unlock(&device.lbllock); 4094 } 4095 4096 /******************************************************************************* 4097 ** Function lbl_init 4098 ** 4099 ** Description Initializes label structures and mutexes. 4100 ** 4101 ** Returns void 4102 *******************************************************************************/ 4103 void lbl_init() 4104 { 4105 memset(&device,0,sizeof(rc_device_t)); 4106 pthread_mutexattr_t attr; 4107 pthread_mutexattr_init(&attr); 4108 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 4109 pthread_mutex_init(&(device.lbllock), &attr); 4110 pthread_mutexattr_destroy(&attr); 4111 init_all_transactions(); 4112 } 4113 4114 /******************************************************************************* 4115 ** 4116 ** Function init_all_transactions 4117 ** 4118 ** Description Initializes all transactions 4119 ** 4120 ** Returns void 4121 *******************************************************************************/ 4122 void init_all_transactions() 4123 { 4124 UINT8 txn_indx=0; 4125 for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++) 4126 { 4127 initialize_transaction(txn_indx); 4128 } 4129 } 4130 4131 /******************************************************************************* 4132 ** 4133 ** Function get_transaction_by_lbl 4134 ** 4135 ** Description Will return a transaction based on the label. If not inuse 4136 ** will return an error. 4137 ** 4138 ** Returns bt_status_t 4139 *******************************************************************************/ 4140 rc_transaction_t *get_transaction_by_lbl(UINT8 lbl) 4141 { 4142 rc_transaction_t *transaction = NULL; 4143 pthread_mutex_lock(&device.lbllock); 4144 4145 /* Determine if this is a valid label */ 4146 if (lbl < MAX_TRANSACTIONS_PER_SESSION) 4147 { 4148 if (FALSE==device.transaction[lbl].in_use) 4149 { 4150 transaction = NULL; 4151 } 4152 else 4153 { 4154 transaction = &(device.transaction[lbl]); 4155 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl); 4156 } 4157 } 4158 4159 pthread_mutex_unlock(&device.lbllock); 4160 return transaction; 4161 } 4162 4163 /******************************************************************************* 4164 ** 4165 ** Function get_transaction 4166 ** 4167 ** Description Obtains the transaction details. 4168 ** 4169 ** Returns bt_status_t 4170 *******************************************************************************/ 4171 4172 bt_status_t get_transaction(rc_transaction_t **ptransaction) 4173 { 4174 bt_status_t result = BT_STATUS_NOMEM; 4175 UINT8 i=0; 4176 pthread_mutex_lock(&device.lbllock); 4177 4178 // Check for unused transactions 4179 for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++) 4180 { 4181 if (FALSE==device.transaction[i].in_use) 4182 { 4183 BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl); 4184 device.transaction[i].in_use = TRUE; 4185 *ptransaction = &(device.transaction[i]); 4186 result = BT_STATUS_SUCCESS; 4187 break; 4188 } 4189 } 4190 4191 pthread_mutex_unlock(&device.lbllock); 4192 return result; 4193 } 4194 4195 /******************************************************************************* 4196 ** 4197 ** Function release_transaction 4198 ** 4199 ** Description Will release a transaction for reuse 4200 ** 4201 ** Returns bt_status_t 4202 *******************************************************************************/ 4203 void release_transaction(UINT8 lbl) 4204 { 4205 rc_transaction_t *transaction = get_transaction_by_lbl(lbl); 4206 4207 /* If the transaction is in use... */ 4208 if (transaction != NULL) 4209 { 4210 BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl); 4211 initialize_transaction(lbl); 4212 } 4213 } 4214 4215 /******************************************************************************* 4216 ** 4217 ** Function lbl_destroy 4218 ** 4219 ** Description Cleanup of the mutex 4220 ** 4221 ** Returns void 4222 *******************************************************************************/ 4223 void lbl_destroy() 4224 { 4225 pthread_mutex_destroy(&(device.lbllock)); 4226 } 4227 4228 /******************************************************************************* 4229 ** Function sleep_ms 4230 ** 4231 ** Description Sleep the calling thread unconditionally for 4232 ** |timeout_ms| milliseconds. 4233 ** 4234 ** Returns void 4235 *******************************************************************************/ 4236 static void sleep_ms(period_ms_t timeout_ms) { 4237 struct timespec delay; 4238 delay.tv_sec = timeout_ms / 1000; 4239 delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000); 4240 4241 OSI_NO_INTR(nanosleep(&delay, &delay)); 4242 } 4243 4244 static bool absolute_volume_disabled() { 4245 char volume_disabled[PROPERTY_VALUE_MAX] = {0}; 4246 osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false"); 4247 if (strncmp(volume_disabled, "true", 4) == 0) { 4248 BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__); 4249 return true; 4250 } 4251 return false; 4252 } 4253