1 /* 2 * Copyright 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.cc 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 <mutex> 35 36 #include <hardware/bluetooth.h> 37 #include <hardware/bt_rc.h> 38 39 #include "avrc_defs.h" 40 #include "bt_common.h" 41 #include "bta_api.h" 42 #include "bta_av_api.h" 43 #include "btif_av.h" 44 #include "btif_common.h" 45 #include "btif_rc.h" 46 #include "btif_util.h" 47 #include "btu.h" 48 #include "device/include/interop.h" 49 #include "log/log.h" 50 #include "osi/include/list.h" 51 #include "osi/include/osi.h" 52 #include "osi/include/properties.h" 53 54 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL) 55 56 /***************************************************************************** 57 * Constants & Macros 58 *****************************************************************************/ 59 60 /* cod value for Headsets */ 61 #define COD_AV_HEADSETS 0x0404 62 /* for AVRC 1.4 need to change this */ 63 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE 64 65 #define IDX_GET_PLAY_STATUS_RSP 0 66 #define IDX_LIST_APP_ATTR_RSP 1 67 #define IDX_LIST_APP_VALUE_RSP 2 68 #define IDX_GET_CURR_APP_VAL_RSP 3 69 #define IDX_SET_APP_VAL_RSP 4 70 #define IDX_GET_APP_ATTR_TXT_RSP 5 71 #define IDX_GET_APP_VAL_TXT_RSP 6 72 #define IDX_GET_ELEMENT_ATTR_RSP 7 73 #define IDX_SET_ADDR_PLAYER_RSP 8 74 #define IDX_SET_BROWSED_PLAYER_RSP 9 75 #define IDX_GET_FOLDER_ITEMS_RSP 10 76 #define IDX_CHG_PATH_RSP 11 77 #define IDX_GET_ITEM_ATTR_RSP 12 78 #define IDX_PLAY_ITEM_RSP 13 79 #define IDX_GET_TOTAL_NUM_OF_ITEMS_RSP 14 80 #define IDX_SEARCH_RSP 15 81 #define IDX_ADD_TO_NOW_PLAYING_RSP 16 82 83 /* Update MAX value whenever IDX will be changed */ 84 #define MAX_CMD_QUEUE_LEN 17 85 86 #define MAX_VOLUME 128 87 #define MAX_LABEL 16 88 #define MAX_TRANSACTIONS_PER_SESSION 16 89 #define PLAY_STATUS_PLAYING 1 90 #define BTIF_RC_NUM_CONN BT_RC_NUM_APP 91 92 #define CHECK_RC_CONNECTED(p_dev) \ 93 do { \ 94 if ((p_dev) == NULL || !(p_dev)->rc_connected) { \ 95 BTIF_TRACE_WARNING("%s: called when RC is not connected", __func__); \ 96 return BT_STATUS_NOT_READY; \ 97 } \ 98 } while (0) 99 100 #define CHECK_BR_CONNECTED(p_dev) \ 101 do { \ 102 if ((p_dev) == NULL || !(p_dev)->br_connected) { \ 103 BTIF_TRACE_WARNING("%s: called when BR is not connected", __func__); \ 104 return BT_STATUS_NOT_READY; \ 105 } \ 106 } while (0) 107 108 /***************************************************************************** 109 * Local type definitions 110 *****************************************************************************/ 111 typedef struct { 112 uint8_t bNotify; 113 uint8_t label; 114 } btif_rc_reg_notifications_t; 115 116 typedef struct { 117 uint8_t label; 118 uint8_t ctype; 119 bool is_rsp_pending; 120 } btif_rc_cmd_ctxt_t; 121 122 /* 2 second timeout to get interim response */ 123 #define BTIF_TIMEOUT_RC_INTERIM_RSP_MS (2 * 1000) 124 #define BTIF_TIMEOUT_RC_STATUS_CMD_MS (2 * 1000) 125 #define BTIF_TIMEOUT_RC_CONTROL_CMD_MS (2 * 1000) 126 127 typedef enum { 128 eNOT_REGISTERED, 129 eREGISTERED, 130 eINTERIM 131 } btif_rc_nfn_reg_status_t; 132 133 typedef struct { 134 uint8_t event_id; 135 uint8_t label; 136 btif_rc_nfn_reg_status_t status; 137 } btif_rc_supported_event_t; 138 139 #define BTIF_RC_STS_TIMEOUT 0xFE 140 typedef struct { 141 uint8_t label; 142 uint8_t pdu_id; 143 } btif_rc_status_cmd_timer_t; 144 145 typedef struct { 146 uint8_t label; 147 uint8_t pdu_id; 148 } btif_rc_control_cmd_timer_t; 149 150 typedef struct { 151 union { 152 btif_rc_status_cmd_timer_t rc_status_cmd; 153 btif_rc_control_cmd_timer_t rc_control_cmd; 154 }; 155 RawAddress rc_addr; 156 } btif_rc_timer_context_t; 157 158 typedef struct { 159 bool query_started; 160 uint8_t num_attrs; 161 uint8_t num_ext_attrs; 162 163 uint8_t attr_index; 164 uint8_t ext_attr_index; 165 uint8_t ext_val_index; 166 btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE]; 167 btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE]; 168 } btif_rc_player_app_settings_t; 169 170 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single 171 * struct */ 172 typedef struct { 173 bool rc_connected; 174 bool br_connected; // Browsing channel. 175 uint8_t rc_handle; 176 tBTA_AV_FEAT rc_features; 177 btrc_connection_state_t rc_state; 178 RawAddress rc_addr; 179 uint16_t rc_pending_play; 180 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN]; 181 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS]; 182 unsigned int rc_volume; 183 uint8_t rc_vol_label; 184 list_t* rc_supported_event_list; 185 btif_rc_player_app_settings_t rc_app_settings; 186 alarm_t* rc_play_status_timer; 187 bool rc_features_processed; 188 uint64_t rc_playing_uid; 189 bool rc_procedure_complete; 190 } btif_rc_device_cb_t; 191 192 typedef struct { 193 std::mutex lock; 194 btif_rc_device_cb_t rc_multi_cb[BTIF_RC_NUM_CONN]; 195 } rc_cb_t; 196 197 typedef struct { 198 bool in_use; 199 uint8_t lbl; 200 uint8_t handle; 201 btif_rc_timer_context_t txn_timer_context; 202 alarm_t* txn_timer; 203 } rc_transaction_t; 204 205 typedef struct { 206 std::recursive_mutex lbllock; 207 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION]; 208 } rc_device_t; 209 210 typedef struct { 211 uint8_t label; 212 RawAddress rc_addr; 213 } rc_context_t; 214 215 typedef struct { uint8_t handle; } btif_rc_handle_t; 216 217 rc_device_t device; 218 219 static void sleep_ms(period_ms_t timeout_ms); 220 221 /* Response status code - Unknown Error - this is changed to "reserved" */ 222 #define BTIF_STS_GEN_ERROR 0x06 223 224 /* Utility table to map hal status codes to bta status codes for the response 225 * status */ 226 static const uint8_t status_code_map[] = { 227 /* BTA_Status codes HAL_Status codes */ 228 AVRC_STS_BAD_CMD, /* BTRC_STS_BAD_CMD */ 229 AVRC_STS_BAD_PARAM, /* BTRC_STS_BAD_PARAM */ 230 AVRC_STS_NOT_FOUND, /* BTRC_STS_NOT_FOUND */ 231 AVRC_STS_INTERNAL_ERR, /* BTRC_STS_INTERNAL_ERR */ 232 AVRC_STS_NO_ERROR, /* BTRC_STS_NO_ERROR */ 233 AVRC_STS_UID_CHANGED, /* BTRC_STS_UID_CHANGED */ 234 BTIF_STS_GEN_ERROR, /* BTRC_STS_RESERVED */ 235 AVRC_STS_BAD_DIR, /* BTRC_STS_INV_DIRN */ 236 AVRC_STS_NOT_DIR, /* BTRC_STS_INV_DIRECTORY */ 237 AVRC_STS_NOT_EXIST, /* BTRC_STS_INV_ITEM */ 238 AVRC_STS_BAD_SCOPE, /* BTRC_STS_INV_SCOPE */ 239 AVRC_STS_BAD_RANGE, /* BTRC_STS_INV_RANGE */ 240 AVRC_STS_UID_IS_DIR, /* BTRC_STS_DIRECTORY */ 241 AVRC_STS_IN_USE, /* BTRC_STS_MEDIA_IN_USE */ 242 AVRC_STS_NOW_LIST_FULL, /* BTRC_STS_PLAY_LIST_FULL */ 243 AVRC_STS_SEARCH_NOT_SUP, /* BTRC_STS_SRCH_NOT_SPRTD */ 244 AVRC_STS_SEARCH_BUSY, /* BTRC_STS_SRCH_IN_PROG */ 245 AVRC_STS_BAD_PLAYER_ID, /* BTRC_STS_INV_PLAYER */ 246 AVRC_STS_PLAYER_N_BR, /* BTRC_STS_PLAY_NOT_BROW */ 247 AVRC_STS_PLAYER_N_ADDR, /* BTRC_STS_PLAY_NOT_ADDR */ 248 AVRC_STS_BAD_SEARCH_RES, /* BTRC_STS_INV_RESULTS */ 249 AVRC_STS_NO_AVAL_PLAYER, /* BTRC_STS_NO_AVBL_PLAY */ 250 AVRC_STS_ADDR_PLAYER_CHG, /* BTRC_STS_ADDR_PLAY_CHGD */ 251 }; 252 253 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, 254 uint8_t status, uint8_t opcode); 255 static uint8_t opcode_from_pdu(uint8_t pdu); 256 static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index, 257 uint8_t label, tBTA_AV_CODE code, 258 tAVRC_RESPONSE* pmetamsg_resp); 259 static void register_volumechange(uint8_t label, btif_rc_device_cb_t* p_dev); 260 static void lbl_init(); 261 static void init_all_transactions(); 262 static bt_status_t get_transaction(rc_transaction_t** ptransaction); 263 static void release_transaction(uint8_t label); 264 static rc_transaction_t* get_transaction_by_lbl(uint8_t label); 265 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, 266 btif_rc_device_cb_t* p_dev); 267 268 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg); 269 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg); 270 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, 271 tAVRC_COMMAND* pavrc_cmd, 272 uint8_t label, 273 btif_rc_device_cb_t* p_dev); 274 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev); 275 static void rc_stop_play_status_timer(btif_rc_device_cb_t* p_dev); 276 static void register_for_event_notification(btif_rc_supported_event_t* p_event, 277 btif_rc_device_cb_t* p_dev); 278 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, 279 tAVRC_GET_CAPS_RSP* p_rsp); 280 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, 281 tAVRC_LIST_APP_ATTR_RSP* p_rsp); 282 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, 283 tAVRC_LIST_APP_VALUES_RSP* p_rsp); 284 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg, 285 tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp); 286 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg, 287 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp); 288 static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg, 289 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp); 290 static void cleanup_app_attr_val_txt_response( 291 btif_rc_player_app_settings_t* p_app_settings); 292 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, 293 tAVRC_GET_PLAY_STATUS_RSP* p_rsp); 294 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, 295 tAVRC_RSP* p_rsp); 296 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, 297 uint8_t item_count); 298 static void handle_get_elem_attr_response(tBTA_AV_META_MSG* pmeta_msg, 299 tAVRC_GET_ATTRS_RSP* p_rsp); 300 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, 301 tAVRC_RSP* p_rsp); 302 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev); 303 static bt_status_t get_player_app_setting_attr_text_cmd( 304 uint8_t* attrs, uint8_t num_attrs, btif_rc_device_cb_t* p_dev); 305 static bt_status_t get_player_app_setting_value_text_cmd( 306 uint8_t* vals, uint8_t num_vals, btif_rc_device_cb_t* p_dev); 307 static bt_status_t register_notification_cmd(uint8_t label, uint8_t event_id, 308 uint32_t event_value, 309 btif_rc_device_cb_t* p_dev); 310 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, 311 uint32_t* p_attr_ids, 312 btif_rc_device_cb_t* p_dev); 313 static bt_status_t getcapabilities_cmd(uint8_t cap_id, 314 btif_rc_device_cb_t* p_dev); 315 static bt_status_t list_player_app_setting_attrib_cmd( 316 btif_rc_device_cb_t* p_dev); 317 static bt_status_t list_player_app_setting_value_cmd( 318 uint8_t attrib_id, btif_rc_device_cb_t* p_dev); 319 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, 320 uint8_t* attrib_ids, 321 btif_rc_device_cb_t* p_dev); 322 void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, 323 btrc_folder_items_t* btrc_item); 324 void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item, 325 btrc_folder_items_t* btrc_item); 326 void get_folder_item_type_player(const tAVRC_ITEM* avrc_item, 327 btrc_folder_items_t* btrc_item); 328 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, 329 uint8_t scope, uint32_t start_item, 330 uint32_t end_item); 331 332 static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* p_param, 333 uint8_t ctype, uint8_t label, 334 btif_rc_device_cb_t* p_dev); 335 336 static void btif_rc_upstreams_rsp_evt(uint16_t event, 337 tAVRC_RESPONSE* pavrc_resp, uint8_t ctype, 338 uint8_t label, 339 btif_rc_device_cb_t* p_dev); 340 341 static void rc_start_play_status_timer(btif_rc_device_cb_t* p_dev); 342 static bool absolute_volume_disabled(void); 343 344 /***************************************************************************** 345 * Static variables 346 *****************************************************************************/ 347 static rc_cb_t btif_rc_cb; 348 static btrc_callbacks_t* bt_rc_callbacks = NULL; 349 static btrc_ctrl_callbacks_t* bt_rc_ctrl_callbacks = NULL; 350 351 /***************************************************************************** 352 * Static functions 353 *****************************************************************************/ 354 355 /***************************************************************************** 356 * Externs 357 *****************************************************************************/ 358 extern bool check_cod(const RawAddress& remote_bdaddr, uint32_t cod); 359 360 /***************************************************************************** 361 * Functions 362 *****************************************************************************/ 363 static btif_rc_device_cb_t* alloc_device() { 364 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 365 if (btif_rc_cb.rc_multi_cb[idx].rc_state == 366 BTRC_CONNECTION_STATE_DISCONNECTED) { 367 return (&btif_rc_cb.rc_multi_cb[idx]); 368 } 369 } 370 return NULL; 371 } 372 373 static btif_rc_device_cb_t* get_connected_device(int index) { 374 BTIF_TRACE_DEBUG("%s: index: %d", __func__, index); 375 if (index > BTIF_RC_NUM_CONN) { 376 BTIF_TRACE_ERROR("%s: can't support more than %d connections", __func__, 377 BTIF_RC_NUM_CONN); 378 return NULL; 379 } 380 if (btif_rc_cb.rc_multi_cb[index].rc_state != 381 BTRC_CONNECTION_STATE_CONNECTED) { 382 BTIF_TRACE_ERROR("%s: returning NULL", __func__); 383 return NULL; 384 } 385 return (&btif_rc_cb.rc_multi_cb[index]); 386 } 387 388 static int get_num_connected_devices() { 389 int connected_devices = 0; 390 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 391 if (btif_rc_cb.rc_multi_cb[idx].rc_state == 392 BTRC_CONNECTION_STATE_CONNECTED) { 393 connected_devices++; 394 } 395 } 396 BTIF_TRACE_DEBUG("%s: returning connected_devices: %d", __func__, 397 connected_devices); 398 return connected_devices; 399 } 400 401 btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress& bd_addr) { 402 VLOG(1) << __func__ << ": bd_addr: " << bd_addr; 403 404 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 405 if ((btif_rc_cb.rc_multi_cb[idx].rc_state != 406 BTRC_CONNECTION_STATE_DISCONNECTED) && 407 btif_rc_cb.rc_multi_cb[idx].rc_addr == bd_addr) { 408 return (&btif_rc_cb.rc_multi_cb[idx]); 409 } 410 } 411 BTIF_TRACE_ERROR("%s: device not found, returning NULL!", __func__); 412 return NULL; 413 } 414 415 btif_rc_device_cb_t* btif_rc_get_device_by_handle(uint8_t handle) { 416 BTIF_TRACE_DEBUG("%s: handle: 0x%x", __func__, handle); 417 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 418 if ((btif_rc_cb.rc_multi_cb[idx].rc_state != 419 BTRC_CONNECTION_STATE_DISCONNECTED) && 420 (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) { 421 BTIF_TRACE_DEBUG("%s: btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x%x", 422 __func__, btif_rc_cb.rc_multi_cb[idx].rc_handle); 423 return (&btif_rc_cb.rc_multi_cb[idx]); 424 } 425 } 426 BTIF_TRACE_ERROR("%s: returning NULL", __func__); 427 return NULL; 428 } 429 430 void fill_pdu_queue(int index, uint8_t ctype, uint8_t label, bool pending, 431 btif_rc_device_cb_t* p_dev) { 432 p_dev->rc_pdu_info[index].ctype = ctype; 433 p_dev->rc_pdu_info[index].label = label; 434 p_dev->rc_pdu_info[index].is_rsp_pending = pending; 435 } 436 437 void fill_avrc_attr_entry(tAVRC_ATTR_ENTRY* attr_vals, int num_attrs, 438 btrc_element_attr_val_t* p_attrs) { 439 for (int attr_cnt = 0; attr_cnt < num_attrs; attr_cnt++) { 440 attr_vals[attr_cnt].attr_id = p_attrs[attr_cnt].attr_id; 441 attr_vals[attr_cnt].name.charset_id = AVRC_CHARSET_ID_UTF8; 442 attr_vals[attr_cnt].name.str_len = 443 (uint16_t)strlen((char*)p_attrs[attr_cnt].text); 444 attr_vals[attr_cnt].name.p_str = p_attrs[attr_cnt].text; 445 BTIF_TRACE_DEBUG( 446 "%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", __func__, 447 (unsigned int)attr_vals[attr_cnt].attr_id, 448 attr_vals[attr_cnt].name.charset_id, attr_vals[attr_cnt].name.str_len, 449 attr_vals[attr_cnt].name.p_str); 450 } 451 } 452 453 void rc_cleanup_sent_cmd(void* p_data) { BTIF_TRACE_DEBUG("%s: ", __func__); } 454 455 void handle_rc_ctrl_features(btif_rc_device_cb_t* p_dev) { 456 if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG) && 457 (!(p_dev->rc_features & BTA_AV_FEAT_RCCT) || 458 !(p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL))) { 459 return; 460 } 461 462 int rc_features = 0; 463 464 if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) && 465 (p_dev->rc_features & BTA_AV_FEAT_RCCT)) { 466 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME; 467 } 468 469 if ((p_dev->rc_features & BTA_AV_FEAT_METADATA) && 470 (p_dev->rc_features & BTA_AV_FEAT_VENDOR) && 471 (p_dev->rc_features_processed != true)) { 472 rc_features |= BTRC_FEAT_METADATA; 473 474 /* Mark rc features processed to avoid repeating 475 * the AVRCP procedure every time on receiving this 476 * update. 477 */ 478 p_dev->rc_features_processed = true; 479 if (btif_av_is_sink_enabled()) { 480 getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev); 481 } 482 } 483 484 /* Add browsing feature capability */ 485 if (p_dev->rc_features & BTA_AV_FEAT_BROWSE) { 486 rc_features |= BTRC_FEAT_BROWSE; 487 } 488 489 BTIF_TRACE_DEBUG("%s: Update rc features to CTRL: %d", __func__, rc_features); 490 do_in_jni_thread(FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->getrcfeatures_cb, 491 p_dev->rc_addr, rc_features)); 492 } 493 494 void handle_rc_features(btif_rc_device_cb_t* p_dev) { 495 496 CHECK(bt_rc_callbacks); 497 498 btrc_remote_features_t rc_features = BTRC_FEAT_NONE; 499 RawAddress avdtp_source_active_peer_addr = btif_av_source_active_peer(); 500 RawAddress avdtp_sink_active_peer_addr = btif_av_sink_active_peer(); 501 502 BTIF_TRACE_DEBUG( 503 "%s: AVDTP Source Active Peer Address: %s " 504 "AVDTP Sink Active Peer Address: %s " 505 "AVCTP address: %s", 506 __func__, avdtp_source_active_peer_addr.ToString().c_str(), 507 avdtp_sink_active_peer_addr.ToString().c_str(), 508 p_dev->rc_addr.ToString().c_str()); 509 510 if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &p_dev->rc_addr) || 511 absolute_volume_disabled() || 512 (avdtp_source_active_peer_addr != p_dev->rc_addr && 513 avdtp_sink_active_peer_addr != p_dev->rc_addr)) { 514 p_dev->rc_features &= ~BTA_AV_FEAT_ADV_CTRL; 515 } 516 517 if (p_dev->rc_features & BTA_AV_FEAT_BROWSE) { 518 rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_BROWSE); 519 } 520 521 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 522 if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) && 523 (p_dev->rc_features & BTA_AV_FEAT_RCTG)) { 524 rc_features = 525 (btrc_remote_features_t)(rc_features | BTRC_FEAT_ABSOLUTE_VOLUME); 526 } 527 #endif 528 529 if (p_dev->rc_features & BTA_AV_FEAT_METADATA) { 530 rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_METADATA); 531 } 532 533 BTIF_TRACE_DEBUG("%s: rc_features: 0x%x", __func__, rc_features); 534 HAL_CBACK(bt_rc_callbacks, remote_features_cb, p_dev->rc_addr, rc_features); 535 536 #if (AVRC_ADV_CTRL_INCLUDED == TRUE) 537 BTIF_TRACE_DEBUG( 538 "%s: Checking for feature flags in btif_rc_handler with label: %d", 539 __func__, p_dev->rc_vol_label); 540 // Register for volume change on connect 541 if (p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL && 542 p_dev->rc_features & BTA_AV_FEAT_RCTG) { 543 rc_transaction_t* p_transaction = NULL; 544 bt_status_t status = BT_STATUS_NOT_READY; 545 if (MAX_LABEL == p_dev->rc_vol_label) { 546 status = get_transaction(&p_transaction); 547 } else { 548 p_transaction = get_transaction_by_lbl(p_dev->rc_vol_label); 549 if (NULL != p_transaction) { 550 BTIF_TRACE_DEBUG( 551 "%s: register_volumechange already in progress for label: %d", 552 __func__, p_dev->rc_vol_label); 553 return; 554 } 555 status = get_transaction(&p_transaction); 556 } 557 if (BT_STATUS_SUCCESS == status && NULL != p_transaction) { 558 p_dev->rc_vol_label = p_transaction->lbl; 559 register_volumechange(p_dev->rc_vol_label, p_dev); 560 } 561 } 562 #endif 563 } 564 565 /*************************************************************************** 566 * Function handle_rc_connect 567 * 568 * - Argument: tBTA_AV_RC_OPEN browse RC open data structure 569 * 570 * - Description: browse RC connection event handler 571 * 572 ***************************************************************************/ 573 void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) { 574 BTIF_TRACE_DEBUG("%s: rc_handle %d status %d", __func__, 575 p_rc_br_open->rc_handle, p_rc_br_open->status); 576 btif_rc_device_cb_t* p_dev = 577 btif_rc_get_device_by_handle(p_rc_br_open->rc_handle); 578 579 if (!p_dev) { 580 BTIF_TRACE_ERROR("%s p_dev is null", __func__); 581 return; 582 } 583 584 /* check that we are already connected to this address since being connected 585 * to a browse when not connected to the control channel over AVRCP is 586 * probably not preferred anyways. */ 587 if (p_rc_br_open->status == BTA_AV_SUCCESS) { 588 p_dev->br_connected = true; 589 do_in_jni_thread(FROM_HERE, 590 base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, true, 591 true, p_dev->rc_addr)); 592 } 593 } 594 595 /*************************************************************************** 596 * Function handle_rc_connect 597 * 598 * - Argument: tBTA_AV_RC_OPEN RC open data structure 599 * 600 * - Description: RC connection event handler 601 * 602 ***************************************************************************/ 603 void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { 604 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __func__, p_rc_open->rc_handle); 605 606 btif_rc_device_cb_t* p_dev = alloc_device(); 607 if (p_dev == NULL) { 608 BTIF_TRACE_ERROR("%s: p_dev is NULL", __func__); 609 return; 610 } 611 612 if (!(p_rc_open->status == BTA_AV_SUCCESS)) { 613 BTIF_TRACE_ERROR("%s: Connect failed with error code: %d", __func__, 614 p_rc_open->status); 615 p_dev->rc_connected = false; 616 } 617 618 // check if already some RC is connected 619 if (p_dev->rc_connected) { 620 BTIF_TRACE_ERROR( 621 "%s: Got RC OPEN in connected state, Connected RC: %d \ 622 and Current RC: %d", 623 __func__, p_dev->rc_handle, p_rc_open->rc_handle); 624 if (p_dev->rc_handle != p_rc_open->rc_handle && 625 p_dev->rc_addr != p_rc_open->peer_addr) { 626 BTIF_TRACE_DEBUG("%s: Got RC connected for some other handle", __func__); 627 BTA_AvCloseRc(p_rc_open->rc_handle); 628 return; 629 } 630 } 631 p_dev->rc_addr = p_rc_open->peer_addr; 632 p_dev->rc_features = p_rc_open->peer_features; 633 BTIF_TRACE_DEBUG("%s: handle_rc_connect in features: 0x%x out features 0x%x", 634 __func__, p_rc_open->peer_features, p_dev->rc_features); 635 p_dev->rc_vol_label = MAX_LABEL; 636 p_dev->rc_volume = MAX_VOLUME; 637 638 p_dev->rc_connected = true; 639 p_dev->rc_handle = p_rc_open->rc_handle; 640 p_dev->rc_state = BTRC_CONNECTION_STATE_CONNECTED; 641 /* on locally initiated connection we will get remote features as part of 642 * connect */ 643 if (p_dev->rc_features != 0 && bt_rc_callbacks != NULL) { 644 handle_rc_features(p_dev); 645 } 646 647 p_dev->rc_playing_uid = RC_INVALID_TRACK_ID; 648 if (bt_rc_ctrl_callbacks != NULL) { 649 do_in_jni_thread(FROM_HERE, 650 base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, true, 651 false, p_dev->rc_addr)); 652 } 653 /* report connection state if remote device is AVRCP target */ 654 handle_rc_ctrl_features(p_dev); 655 } 656 657 /*************************************************************************** 658 * Function handle_rc_disconnect 659 * 660 * - Argument: tBTA_AV_RC_CLOSE RC close data structure 661 * 662 * - Description: RC disconnection event handler 663 * 664 ***************************************************************************/ 665 void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) { 666 btif_rc_device_cb_t* p_dev = NULL; 667 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __func__, p_rc_close->rc_handle); 668 669 p_dev = btif_rc_get_device_by_handle(p_rc_close->rc_handle); 670 if (p_dev == NULL) { 671 BTIF_TRACE_ERROR("%s: Got disconnect from invalid rc handle", __func__); 672 return; 673 } 674 675 if (p_rc_close->rc_handle != p_dev->rc_handle && 676 p_dev->rc_addr != p_rc_close->peer_addr) { 677 BTIF_TRACE_ERROR("Got disconnect of unknown device"); 678 return; 679 } 680 /* report connection state if device is AVRCP target */ 681 if (bt_rc_ctrl_callbacks != NULL) { 682 do_in_jni_thread( 683 FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, false, 684 false, p_dev->rc_addr)); 685 } 686 /* Clean up AVRCP procedure flags */ 687 memset(&p_dev->rc_app_settings, 0, sizeof(btif_rc_player_app_settings_t)); 688 p_dev->rc_features_processed = false; 689 p_dev->rc_procedure_complete = false; 690 rc_stop_play_status_timer(p_dev); 691 /* Check and clear the notification event list */ 692 if (p_dev->rc_supported_event_list != NULL) { 693 list_clear(p_dev->rc_supported_event_list); 694 p_dev->rc_supported_event_list = NULL; 695 } 696 697 /* check if there is another device connected */ 698 if (p_dev->rc_state == BTRC_CONNECTION_STATE_CONNECTED) { 699 p_dev->rc_handle = 0; 700 p_dev->rc_connected = false; 701 p_dev->rc_state = BTRC_CONNECTION_STATE_DISCONNECTED; 702 703 memset(p_dev->rc_notif, 0, sizeof(p_dev->rc_notif)); 704 705 p_dev->rc_features = 0; 706 p_dev->rc_vol_label = MAX_LABEL; 707 p_dev->rc_volume = MAX_VOLUME; 708 709 p_dev->rc_addr = RawAddress::kEmpty; 710 } 711 if (get_num_connected_devices() == 0) { 712 BTIF_TRACE_DEBUG("%s: Closing all handles", __func__); 713 init_all_transactions(); 714 } 715 716 p_dev->rc_addr = RawAddress::kEmpty; 717 } 718 719 /*************************************************************************** 720 * Function handle_rc_passthrough_cmd 721 * 722 * - Argument: tBTA_AV_RC rc_id remote control command ID 723 * tBTA_AV_STATE key_state status of key press 724 * 725 * - Description: Remote control command handler 726 * 727 ***************************************************************************/ 728 void handle_rc_passthrough_cmd(tBTA_AV_REMOTE_CMD* p_remote_cmd) { 729 if (p_remote_cmd == NULL) { 730 BTIF_TRACE_ERROR("%s: No remote command!", __func__); 731 return; 732 } 733 734 btif_rc_device_cb_t* p_dev = 735 btif_rc_get_device_by_handle(p_remote_cmd->rc_handle); 736 if (p_dev == NULL) { 737 BTIF_TRACE_ERROR("%s: Got passthrough command from invalid rc handle", 738 __func__); 739 return; 740 } 741 742 743 BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id: %d", __func__, 744 p_remote_cmd->rc_id); 745 746 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up 747 * this PLAY */ 748 if ((p_remote_cmd->rc_id == AVRC_ID_PLAY) && (!btif_av_is_connected())) { 749 if (p_remote_cmd->key_state == AVRC_STATE_PRESS) { 750 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", 751 __func__); 752 p_dev->rc_pending_play = true; 753 } 754 return; 755 } 756 757 /* If we previously queued a play and we get a PAUSE, clear it. */ 758 if ((p_remote_cmd->rc_id == AVRC_ID_PAUSE) && (p_dev->rc_pending_play)) { 759 APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", 760 __func__); 761 p_dev->rc_pending_play = false; 762 return; 763 } 764 765 if ((p_remote_cmd->rc_id == AVRC_ID_STOP) && 766 (!btif_av_stream_started_ready())) { 767 APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd", __func__); 768 return; 769 } 770 771 int pressed = (p_remote_cmd->key_state == AVRC_STATE_PRESS) ? 1 : 0; 772 773 /* pass all commands up */ 774 BTIF_TRACE_DEBUG("%s: rc_features: %d, cmd->rc_id: %d, pressed: %d", __func__, 775 p_dev->rc_features, p_remote_cmd->rc_id, pressed); 776 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed, 777 p_dev->rc_addr); 778 } 779 780 /*************************************************************************** 781 * Function handle_rc_passthrough_rsp 782 * 783 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response 784 * 785 * - Description: Remote control passthrough response handler 786 * 787 ***************************************************************************/ 788 void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { 789 btif_rc_device_cb_t* p_dev = NULL; 790 791 p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle); 792 if (p_dev == NULL) { 793 BTIF_TRACE_ERROR("%s: passthrough response for Invalid rc handle", 794 __func__); 795 return; 796 } 797 798 799 if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG)) { 800 BTIF_TRACE_ERROR("%s: DUT does not support AVRCP controller role", 801 __func__); 802 return; 803 } 804 805 const char* status = (p_remote_rsp->key_state == 1) ? "released" : "pressed"; 806 BTIF_TRACE_DEBUG("%s: rc_id: %d state: %s", __func__, p_remote_rsp->rc_id, 807 status); 808 809 release_transaction(p_remote_rsp->label); 810 if (bt_rc_ctrl_callbacks != NULL) { 811 do_in_jni_thread( 812 FROM_HERE, 813 base::Bind(bt_rc_ctrl_callbacks->passthrough_rsp_cb, p_dev->rc_addr, 814 p_remote_rsp->rc_id, p_remote_rsp->key_state)); 815 } 816 } 817 818 /*************************************************************************** 819 * Function handle_rc_vendorunique_rsp 820 * 821 * - Argument: tBTA_AV_REMOTE_RSP command response 822 * 823 * - Description: Remote control vendor unique response handler 824 * 825 ***************************************************************************/ 826 void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { 827 btif_rc_device_cb_t* p_dev = NULL; 828 const char* status; 829 uint8_t vendor_id = 0; 830 831 p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle); 832 if (p_dev == NULL) { 833 BTIF_TRACE_ERROR("%s: Got vendorunique rsp from invalid rc handle", 834 __func__); 835 return; 836 } 837 838 if (p_dev->rc_features & BTA_AV_FEAT_RCTG) { 839 int key_state; 840 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) { 841 status = "released"; 842 key_state = 1; 843 } else { 844 status = "pressed"; 845 key_state = 0; 846 } 847 848 if (p_remote_rsp->len > 0) { 849 if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN) 850 vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN - 1]; 851 osi_free_and_reset((void**)&p_remote_rsp->p_data); 852 } 853 BTIF_TRACE_DEBUG("%s: vendor_id: %d status: %s", __func__, vendor_id, 854 status); 855 856 release_transaction(p_remote_rsp->label); 857 do_in_jni_thread(FROM_HERE, 858 base::Bind(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb, 859 vendor_id, key_state)); 860 } else { 861 BTIF_TRACE_ERROR("%s: Remote does not support AVRCP TG role", __func__); 862 } 863 } 864 865 /*************************************************************************** 866 * Function handle_rc_metamsg_cmd 867 * 868 * - Argument: tBTA_AV_VENDOR Structure containing the received 869 * metamsg command 870 * 871 * - Description: Remote control metamsg command handler (AVRCP 1.3) 872 * 873 ***************************************************************************/ 874 void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { 875 /* Parse the metamsg command and pass it on to BTL-IFS */ 876 uint8_t scratch_buf[512] = {0}; 877 tAVRC_COMMAND avrc_command = {0}; 878 tAVRC_STS status; 879 btif_rc_device_cb_t* p_dev = NULL; 880 881 if (NULL == pmeta_msg) { 882 BTIF_TRACE_EVENT("%s: Exiting as pmeta_msg is NULL", __func__); 883 return; 884 } 885 886 if (NULL == pmeta_msg->p_msg) { 887 BTIF_TRACE_EVENT("%s: Exiting as pmeta_msg->p_msg is NULL", __func__); 888 return; 889 } 890 891 BTIF_TRACE_EVENT("%s: pmeta_msg: opcode: %x, code: %x", __func__, 892 pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); 893 894 p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 895 if (p_dev == NULL) { 896 BTIF_TRACE_ERROR("%s: Meta msg event for Invalid rc handle", __func__); 897 return; 898 } 899 900 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR && 901 pmeta_msg->p_msg->hdr.opcode != AVRC_OP_BROWSE) { 902 BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode); 903 return; 904 } 905 906 if (pmeta_msg->len < 3) { 907 BTIF_TRACE_WARNING("%s: Invalid length. opcode: 0x%x, len: 0x%x", __func__, 908 pmeta_msg->p_msg->hdr.opcode, pmeta_msg->len); 909 return; 910 } 911 912 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) { 913 { 914 rc_transaction_t* transaction = NULL; 915 transaction = get_transaction_by_lbl(pmeta_msg->label); 916 if (transaction != NULL) { 917 handle_rc_metamsg_rsp(pmeta_msg, p_dev); 918 } else { 919 BTIF_TRACE_DEBUG( 920 "%s: Discard vendor dependent rsp. code: %d label: %d.", __func__, 921 pmeta_msg->code, pmeta_msg->label); 922 } 923 return; 924 } 925 } 926 927 status = AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, 928 sizeof(scratch_buf)); 929 BTIF_TRACE_DEBUG("%s: Received vendor command.code,PDU and label: %d, %d, %d", 930 __func__, pmeta_msg->code, avrc_command.cmd.pdu, 931 pmeta_msg->label); 932 933 if (status != AVRC_STS_NO_ERROR) { 934 /* return error */ 935 BTIF_TRACE_WARNING( 936 "%s: Error in parsing received metamsg command. status: 0x%02x", 937 __func__, status); 938 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, 939 avrc_command.pdu, status, 940 pmeta_msg->p_msg->hdr.opcode); 941 } else { 942 /* if RegisterNotification, add it to our registered queue */ 943 944 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) { 945 uint8_t event_id = avrc_command.reg_notif.event_id; 946 947 BTIF_TRACE_EVENT( 948 "%s: New register notification received.event_id: %s, label: 0x%x, " 949 "code: %x", 950 __func__, dump_rc_notification_event_id(event_id), pmeta_msg->label, 951 pmeta_msg->code); 952 p_dev->rc_notif[event_id - 1].bNotify = true; 953 p_dev->rc_notif[event_id - 1].label = pmeta_msg->label; 954 } 955 956 BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s", 957 __func__, dump_rc_pdu(avrc_command.cmd.pdu)); 958 959 /* Since handle_rc_metamsg_cmd() itself is called from 960 *btif context, no context switching is required. Invoke 961 * btif_rc_upstreams_evt directly from here. */ 962 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, 963 pmeta_msg->code, pmeta_msg->label, p_dev); 964 } 965 } 966 967 /*************************************************************************** 968 ** 969 ** Function btif_rc_handler 970 ** 971 ** Description RC event handler 972 ** 973 ***************************************************************************/ 974 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { 975 BTIF_TRACE_DEBUG("%s: event: %s", __func__, dump_rc_event(event)); 976 btif_rc_device_cb_t* p_dev = NULL; 977 switch (event) { 978 case BTA_AV_RC_OPEN_EVT: { 979 BTIF_TRACE_DEBUG("%s: Peer_features: %x", __func__, 980 p_data->rc_open.peer_features); 981 handle_rc_connect(&(p_data->rc_open)); 982 } break; 983 984 case BTA_AV_RC_BROWSE_OPEN_EVT: { 985 /* tell the UL that we have connection to browse channel and that 986 * browse commands can be directed accordingly. */ 987 handle_rc_browse_connect(&p_data->rc_browse_open); 988 } break; 989 990 case BTA_AV_RC_CLOSE_EVT: { 991 handle_rc_disconnect(&(p_data->rc_close)); 992 } break; 993 994 case BTA_AV_RC_BROWSE_CLOSE_EVT: { 995 BTIF_TRACE_DEBUG("%s: BTA_AV_RC_BROWSE_CLOSE_EVT", __func__); 996 } break; 997 998 case BTA_AV_REMOTE_CMD_EVT: { 999 if (bt_rc_callbacks != NULL) { 1000 BTIF_TRACE_DEBUG("%s: rc_id: 0x%x key_state: %d", __func__, 1001 p_data->remote_cmd.rc_id, 1002 p_data->remote_cmd.key_state); 1003 handle_rc_passthrough_cmd((&p_data->remote_cmd)); 1004 } else { 1005 BTIF_TRACE_ERROR("%s: AVRCP TG role not up, drop passthrough commands", 1006 __func__); 1007 } 1008 } break; 1009 1010 case BTA_AV_REMOTE_RSP_EVT: { 1011 BTIF_TRACE_DEBUG("%s: RSP: rc_id: 0x%x key_state: %d", __func__, 1012 p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state); 1013 1014 if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR) { 1015 handle_rc_vendorunique_rsp((&p_data->remote_rsp)); 1016 } else { 1017 handle_rc_passthrough_rsp((&p_data->remote_rsp)); 1018 } 1019 } break; 1020 1021 case BTA_AV_RC_FEAT_EVT: { 1022 BTIF_TRACE_DEBUG("%s: Peer_features: %x", __func__, 1023 p_data->rc_feat.peer_features); 1024 p_dev = btif_rc_get_device_by_handle(p_data->rc_feat.rc_handle); 1025 if (p_dev == NULL) { 1026 BTIF_TRACE_ERROR("%s: RC Feature event for Invalid rc handle", 1027 __func__); 1028 break; 1029 } 1030 1031 p_dev->rc_features = p_data->rc_feat.peer_features; 1032 if (bt_rc_callbacks != NULL) { 1033 handle_rc_features(p_dev); 1034 } 1035 1036 if ((p_dev->rc_connected) && (bt_rc_ctrl_callbacks != NULL)) { 1037 handle_rc_ctrl_features(p_dev); 1038 } 1039 } break; 1040 1041 case BTA_AV_META_MSG_EVT: { 1042 if (bt_rc_callbacks != NULL) { 1043 BTIF_TRACE_DEBUG("%s: BTA_AV_META_MSG_EVT code: %d label: %d", __func__, 1044 p_data->meta_msg.code, p_data->meta_msg.label); 1045 BTIF_TRACE_DEBUG("%s: company_id: 0x%x len: %d handle: %d", __func__, 1046 p_data->meta_msg.company_id, p_data->meta_msg.len, 1047 p_data->meta_msg.rc_handle); 1048 1049 /* handle the metamsg command */ 1050 handle_rc_metamsg_cmd(&(p_data->meta_msg)); 1051 1052 /* Free the Memory allocated for tAVRC_MSG */ 1053 } else if (bt_rc_ctrl_callbacks != NULL) { 1054 /* This is case of Sink + CT + TG(for abs vol)) */ 1055 BTIF_TRACE_DEBUG( 1056 "%s BTA_AV_META_MSG_EVT code:%d label:%d opcode %d ctype %d", 1057 __func__, p_data->meta_msg.code, p_data->meta_msg.label, 1058 p_data->meta_msg.p_msg->hdr.opcode, 1059 p_data->meta_msg.p_msg->hdr.ctype); 1060 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d", __func__, 1061 p_data->meta_msg.company_id, p_data->meta_msg.len, 1062 p_data->meta_msg.rc_handle); 1063 switch (p_data->meta_msg.p_msg->hdr.opcode) { 1064 case AVRC_OP_VENDOR: 1065 if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL) && 1066 (p_data->meta_msg.code <= AVRC_RSP_INTERIM)) { 1067 /* Its a response */ 1068 handle_avk_rc_metamsg_rsp(&(p_data->meta_msg)); 1069 } else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ) { 1070 /* Its a command */ 1071 handle_avk_rc_metamsg_cmd(&(p_data->meta_msg)); 1072 } 1073 break; 1074 1075 case AVRC_OP_BROWSE: 1076 if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_CMD) { 1077 handle_avk_rc_metamsg_cmd(&(p_data->meta_msg)); 1078 } else if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_RSP) { 1079 handle_avk_rc_metamsg_rsp(&(p_data->meta_msg)); 1080 } 1081 break; 1082 } 1083 } else { 1084 BTIF_TRACE_ERROR("Neither CTRL, nor TG is up, drop meta commands"); 1085 } 1086 } break; 1087 1088 default: 1089 BTIF_TRACE_DEBUG("%s: Unhandled RC event : 0x%x", __func__, event); 1090 } 1091 } 1092 1093 bool btif_rc_is_connected_peer(const RawAddress& peer_addr) { 1094 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 1095 btif_rc_device_cb_t* p_dev = get_connected_device(idx); 1096 if (p_dev != NULL && (p_dev->rc_connected == TRUE) && 1097 peer_addr == p_dev->rc_addr) { 1098 return true; 1099 } 1100 } 1101 return false; 1102 } 1103 1104 /*************************************************************************** 1105 ** 1106 ** Function btif_rc_get_connected_peer_handle 1107 ** 1108 ** Description Fetches the connected headset's handle if any 1109 ** 1110 ***************************************************************************/ 1111 uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr) { 1112 btif_rc_device_cb_t* p_dev = NULL; 1113 p_dev = btif_rc_get_device_by_bda(peer_addr); 1114 1115 if (p_dev == NULL) { 1116 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 1117 return BTRC_HANDLE_NONE; 1118 } 1119 return p_dev->rc_handle; 1120 } 1121 1122 /*************************************************************************** 1123 ** 1124 ** Function btif_rc_check_handle_pending_play 1125 ** 1126 ** Description Clears the queued PLAY command. if |bSendToApp| is true, 1127 ** forwards to app 1128 ** 1129 ***************************************************************************/ 1130 1131 /* clear the queued PLAY command. if |bSendToApp| is true, forward to app */ 1132 void btif_rc_check_handle_pending_play(const RawAddress& peer_addr, 1133 bool bSendToApp) { 1134 btif_rc_device_cb_t* p_dev = NULL; 1135 p_dev = btif_rc_get_device_by_bda(peer_addr); 1136 1137 if (p_dev == NULL) { 1138 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 1139 return; 1140 } 1141 1142 BTIF_TRACE_DEBUG("%s: bSendToApp: %d", __func__, bSendToApp); 1143 if (p_dev->rc_pending_play) { 1144 if (bSendToApp) { 1145 tBTA_AV_REMOTE_CMD remote_cmd; 1146 APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __func__); 1147 1148 memset(&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); 1149 remote_cmd.rc_handle = p_dev->rc_handle; 1150 remote_cmd.rc_id = AVRC_ID_PLAY; 1151 remote_cmd.hdr.ctype = AVRC_CMD_CTRL; 1152 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU; 1153 1154 /* delay sending to app, else there is a timing issue in the framework, 1155 ** which causes the audio to be on th device's speaker. Delay between 1156 ** OPEN & RC_PLAYs 1157 */ 1158 sleep_ms(200); 1159 /* send to app - both PRESSED & RELEASED */ 1160 remote_cmd.key_state = AVRC_STATE_PRESS; 1161 handle_rc_passthrough_cmd(&remote_cmd); 1162 1163 sleep_ms(100); 1164 1165 remote_cmd.key_state = AVRC_STATE_RELEASE; 1166 handle_rc_passthrough_cmd(&remote_cmd); 1167 } 1168 p_dev->rc_pending_play = false; 1169 } 1170 } 1171 1172 /* Generic reject response */ 1173 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, 1174 uint8_t status, uint8_t opcode) { 1175 uint8_t ctype = AVRC_RSP_REJ; 1176 tAVRC_RESPONSE avrc_rsp; 1177 BT_HDR* p_msg = NULL; 1178 memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 1179 1180 avrc_rsp.rsp.opcode = opcode; 1181 avrc_rsp.rsp.pdu = pdu; 1182 avrc_rsp.rsp.status = status; 1183 1184 status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg); 1185 1186 if (status != AVRC_STS_NO_ERROR) { 1187 BTIF_TRACE_ERROR("%s: status not AVRC_STS_NO_ERROR", __func__); 1188 return; 1189 } 1190 1191 BTIF_TRACE_DEBUG( 1192 "%s: Sending error notification to handle: %d. pdu: %s,status: 0x%02x", 1193 __func__, rc_handle, dump_rc_pdu(pdu), status); 1194 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); 1195 } 1196 1197 /*************************************************************************** 1198 * Function get_rsp_type_code 1199 * 1200 * - Argument: status 1201 * - Description: Returns response type codes for particular command code and 1202 * status. 1203 * 1204 ***************************************************************************/ 1205 static tBTA_AV_CODE get_rsp_type_code(tAVRC_STS status, tBTA_AV_CODE code) { 1206 if (status != AVRC_STS_NO_ERROR) { 1207 return AVRC_RSP_REJ; 1208 } 1209 1210 if (code < AVRC_RSP_NOT_IMPL) { 1211 if (code == AVRC_CMD_NOTIF) return AVRC_RSP_INTERIM; 1212 1213 if (code == AVRC_CMD_STATUS) return AVRC_RSP_IMPL_STBL; 1214 1215 return AVRC_RSP_ACCEPT; 1216 } 1217 1218 return code; 1219 } 1220 1221 /*************************************************************************** 1222 * Function send_metamsg_rsp 1223 * 1224 * - Argument: 1225 * p_dev Dev pointer 1226 * index Command index (= -1 if not used) 1227 * label Label of the RC response 1228 * code Response type 1229 * pmetamsg_resp Vendor response 1230 * 1231 * - Description: Remote control metamsg response handler 1232 * 1233 ***************************************************************************/ 1234 static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index, 1235 uint8_t label, tBTA_AV_CODE code, 1236 tAVRC_RESPONSE* pmetamsg_resp) { 1237 uint8_t ctype; 1238 1239 if (p_dev == NULL) { 1240 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 1241 return; 1242 } 1243 1244 if (pmetamsg_resp == NULL) { 1245 BTIF_TRACE_WARNING("%s: Invalid response received from application", 1246 __func__); 1247 return; 1248 } 1249 1250 BTIF_TRACE_EVENT( 1251 "%s: rc_handle: %d, index: %d, label: %d, code: 0x%02x, pdu: %s", 1252 __func__, p_dev->rc_handle, index, label, code, 1253 dump_rc_pdu(pmetamsg_resp->rsp.pdu)); 1254 1255 if (index >= 0 && !p_dev->rc_pdu_info[index].is_rsp_pending) { 1256 BTIF_TRACE_ERROR("%s: is_rsp_pending false, returning", __func__); 1257 return; 1258 } 1259 1260 ctype = get_rsp_type_code(pmetamsg_resp->rsp.status, code); 1261 1262 /* if response is for register_notification, make sure the rc has 1263 actually registered for this */ 1264 if ((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && 1265 ((code == AVRC_RSP_CHANGED) || (code == AVRC_RSP_INTERIM))) { 1266 bool bSent = false; 1267 uint8_t event_id = pmetamsg_resp->reg_notif.event_id; 1268 bool bNotify = 1269 (p_dev->rc_connected) && (p_dev->rc_notif[event_id - 1].bNotify); 1270 1271 /* de-register this notification for a CHANGED response */ 1272 p_dev->rc_notif[event_id - 1].bNotify = false; 1273 BTIF_TRACE_DEBUG("%s: rc_handle: %d. event_id: 0x%02d bNotify: %u", 1274 __func__, p_dev->rc_handle, event_id, bNotify); 1275 if (bNotify) { 1276 BT_HDR* p_msg = NULL; 1277 tAVRC_STS status; 1278 1279 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse( 1280 p_dev->rc_handle, pmetamsg_resp, &p_msg))) { 1281 BTIF_TRACE_DEBUG( 1282 "%s: Sending notification to rc_handle: %d. event_id: 0x%02d", 1283 __func__, p_dev->rc_handle, event_id); 1284 bSent = true; 1285 BTA_AvMetaRsp(p_dev->rc_handle, p_dev->rc_notif[event_id - 1].label, 1286 ctype, p_msg); 1287 } else { 1288 BTIF_TRACE_WARNING( 1289 "%s: failed to build metamsg response. status: 0x%02x", __func__, 1290 status); 1291 } 1292 } 1293 1294 if (!bSent) { 1295 BTIF_TRACE_DEBUG( 1296 "%s: Notification not sent, as there are no RC connections or the \ 1297 CT has not subscribed for event_id: %s", 1298 __func__, dump_rc_notification_event_id(event_id)); 1299 } 1300 } else { 1301 /* All other commands go here */ 1302 1303 BT_HDR* p_msg = NULL; 1304 tAVRC_STS status; 1305 1306 status = AVRC_BldResponse(p_dev->rc_handle, pmetamsg_resp, &p_msg); 1307 1308 if (status == AVRC_STS_NO_ERROR) { 1309 BTA_AvMetaRsp(p_dev->rc_handle, label, ctype, p_msg); 1310 } else { 1311 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x", 1312 __func__, status); 1313 } 1314 } 1315 1316 if (index >= 0) { 1317 p_dev->rc_pdu_info[index].ctype = 0; 1318 p_dev->rc_pdu_info[index].label = 0; 1319 p_dev->rc_pdu_info[index].is_rsp_pending = false; 1320 } 1321 } 1322 1323 static uint8_t opcode_from_pdu(uint8_t pdu) { 1324 uint8_t opcode = 0; 1325 1326 switch (pdu) { 1327 case AVRC_PDU_SET_BROWSED_PLAYER: 1328 case AVRC_PDU_GET_FOLDER_ITEMS: 1329 case AVRC_PDU_CHANGE_PATH: 1330 case AVRC_PDU_GET_ITEM_ATTRIBUTES: 1331 case AVRC_PDU_ADD_TO_NOW_PLAYING: 1332 case AVRC_PDU_SEARCH: 1333 case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS: 1334 case AVRC_PDU_GENERAL_REJECT: 1335 opcode = AVRC_OP_BROWSE; 1336 break; 1337 1338 case AVRC_PDU_NEXT_GROUP: 1339 case AVRC_PDU_PREV_GROUP: /* pass thru */ 1340 opcode = AVRC_OP_PASS_THRU; 1341 break; 1342 1343 default: /* vendor */ 1344 opcode = AVRC_OP_VENDOR; 1345 break; 1346 } 1347 1348 return opcode; 1349 } 1350 1351 /*************************************************************************** 1352 * Function: fill_attribute_id_array 1353 * 1354 * - Argument: 1355 * cmd_attribute_number input attribute number from AVRCP command 1356 * cmd_attribute_id_array input attribute list from AVRCP command 1357 * out_array_size allocated size of out attribute id array 1358 * out_attribute_id_array output attribute list resolved here 1359 * 1360 * - Description: 1361 * Resolve attribute id array as defined by the AVRCP specification. 1362 * 1363 * - Returns: 1364 * The number of attributes filled in 1365 * 1366 ***************************************************************************/ 1367 static uint8_t fill_attribute_id_array( 1368 uint8_t cmd_attribute_number, btrc_media_attr_t* cmd_attribute_id_array, 1369 size_t out_array_size, btrc_media_attr_t* out_attribute_id_array) { 1370 /* Reset attribute array */ 1371 memset(out_attribute_id_array, 0, out_array_size); 1372 /* Default case for cmd_attribute_number == 0xFF, No attribute */ 1373 uint8_t out_attribute_number = 0; 1374 if (cmd_attribute_number == 0) { 1375 /* All attributes */ 1376 out_attribute_number = out_array_size < AVRC_MAX_NUM_MEDIA_ATTR_ID 1377 ? out_array_size 1378 : AVRC_MAX_NUM_MEDIA_ATTR_ID; 1379 for (int i = 0; i < out_attribute_number; i++) { 1380 out_attribute_id_array[i] = (btrc_media_attr_t)(i + 1); 1381 } 1382 } else if (cmd_attribute_number != 0xFF) { 1383 /* Attribute List */ 1384 out_attribute_number = 0; 1385 int filled_id_count = 0; 1386 for (int i = 0; (i < cmd_attribute_number) && 1387 (out_attribute_number < out_array_size) && 1388 (out_attribute_number < AVRC_MAX_NUM_MEDIA_ATTR_ID); 1389 i++) { 1390 /* Fill only valid entries */ 1391 if (AVRC_IS_VALID_MEDIA_ATTRIBUTE(cmd_attribute_id_array[i])) { 1392 /* Skip the duplicate entries */ 1393 for (filled_id_count = 0; filled_id_count < out_attribute_number; 1394 filled_id_count++) { 1395 if (out_attribute_id_array[filled_id_count] == 1396 cmd_attribute_id_array[i]) 1397 break; 1398 } 1399 /* New ID */ 1400 if (filled_id_count == out_attribute_number) { 1401 out_attribute_id_array[out_attribute_number] = 1402 (btrc_media_attr_t)cmd_attribute_id_array[i]; 1403 out_attribute_number++; 1404 } 1405 } 1406 } 1407 } 1408 return out_attribute_number; 1409 } 1410 1411 /******************************************************************************* 1412 * 1413 * Function btif_rc_upstreams_evt 1414 * 1415 * Description Executes AVRC UPSTREAMS events in btif context. 1416 * 1417 * Returns void 1418 * 1419 ******************************************************************************/ 1420 static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, 1421 uint8_t ctype, uint8_t label, 1422 btif_rc_device_cb_t* p_dev) { 1423 BTIF_TRACE_EVENT("%s: pdu: %s handle: 0x%x ctype: %x label: %x event ID: %x", 1424 __func__, dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle, 1425 ctype, label, pavrc_cmd->reg_notif.event_id); 1426 1427 switch (event) { 1428 case AVRC_PDU_GET_PLAY_STATUS: { 1429 fill_pdu_queue(IDX_GET_PLAY_STATUS_RSP, ctype, label, true, p_dev); 1430 HAL_CBACK(bt_rc_callbacks, get_play_status_cb, p_dev->rc_addr); 1431 } break; 1432 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 1433 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 1434 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 1435 case AVRC_PDU_SET_PLAYER_APP_VALUE: 1436 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 1437 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: { 1438 /* TODO: Add support for Application Settings */ 1439 send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, 1440 AVRC_STS_BAD_CMD, pavrc_cmd->cmd.opcode); 1441 } break; 1442 case AVRC_PDU_GET_ELEMENT_ATTR: { 1443 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1444 uint8_t num_attr = fill_attribute_id_array( 1445 pavrc_cmd->get_elem_attrs.num_attr, 1446 (btrc_media_attr_t*)pavrc_cmd->get_elem_attrs.attrs, 1447 BTRC_MAX_ELEM_ATTR_SIZE, element_attrs); 1448 if (num_attr == 0) { 1449 BTIF_TRACE_ERROR( 1450 "%s: No valid attributes requested in GET_ELEMENT_ATTRIBUTES", 1451 __func__); 1452 send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, 1453 AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); 1454 return; 1455 } 1456 fill_pdu_queue(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, true, p_dev); 1457 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs, 1458 p_dev->rc_addr); 1459 } break; 1460 case AVRC_PDU_REGISTER_NOTIFICATION: { 1461 if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED && 1462 pavrc_cmd->reg_notif.param == 0) { 1463 BTIF_TRACE_WARNING( 1464 "%s: Device registering position changed with illegal param 0.", 1465 __func__); 1466 send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, 1467 AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); 1468 /* de-register this notification for a rejected response */ 1469 p_dev->rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = false; 1470 return; 1471 } 1472 HAL_CBACK(bt_rc_callbacks, register_notification_cb, 1473 (btrc_event_id_t)pavrc_cmd->reg_notif.event_id, 1474 pavrc_cmd->reg_notif.param, p_dev->rc_addr); 1475 } break; 1476 case AVRC_PDU_INFORM_DISPLAY_CHARSET: { 1477 tAVRC_RESPONSE avrc_rsp; 1478 BTIF_TRACE_EVENT("%s: AVRC_PDU_INFORM_DISPLAY_CHARSET", __func__); 1479 if (p_dev->rc_connected) { 1480 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP)); 1481 avrc_rsp.inform_charset.opcode = 1482 opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET); 1483 avrc_rsp.inform_charset.pdu = AVRC_PDU_INFORM_DISPLAY_CHARSET; 1484 avrc_rsp.inform_charset.status = AVRC_STS_NO_ERROR; 1485 send_metamsg_rsp(p_dev, -1, label, ctype, &avrc_rsp); 1486 } 1487 } break; 1488 1489 case AVRC_PDU_GET_FOLDER_ITEMS: { 1490 uint32_t attr_ids[BTRC_MAX_ELEM_ATTR_SIZE]; 1491 uint8_t num_attr; 1492 num_attr = pavrc_cmd->get_items.attr_count; 1493 1494 BTIF_TRACE_EVENT( 1495 "%s: AVRC_PDU_GET_FOLDER_ITEMS num_attr: %d, start_item [%d] \ 1496 end_item [%d]", 1497 __func__, num_attr, pavrc_cmd->get_items.start_item, 1498 pavrc_cmd->get_items.end_item); 1499 1500 /* num_attr requested: 1501 * 0x00: All attributes requested 1502 * 0xFF: No Attributes requested 1503 * 0x01 to 0x07: Specified number of attributes 1504 */ 1505 if ((num_attr != 0xFF && num_attr > BTRC_MAX_ELEM_ATTR_SIZE)) { 1506 send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, 1507 AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); 1508 return; 1509 } 1510 1511 /* Except num_attr is None(0xff) / All(0x00), request follows with an 1512 * Attribute List */ 1513 if ((num_attr != 0xFF) && (num_attr != 0x00)) { 1514 memcpy(attr_ids, pavrc_cmd->get_items.p_attr_list, 1515 sizeof(uint32_t) * num_attr); 1516 } 1517 1518 fill_pdu_queue(IDX_GET_FOLDER_ITEMS_RSP, ctype, label, true, p_dev); 1519 HAL_CBACK(bt_rc_callbacks, get_folder_items_cb, 1520 pavrc_cmd->get_items.scope, pavrc_cmd->get_items.start_item, 1521 pavrc_cmd->get_items.end_item, num_attr, attr_ids, 1522 p_dev->rc_addr); 1523 } break; 1524 1525 case AVRC_PDU_SET_ADDRESSED_PLAYER: { 1526 fill_pdu_queue(IDX_SET_ADDR_PLAYER_RSP, ctype, label, true, p_dev); 1527 HAL_CBACK(bt_rc_callbacks, set_addressed_player_cb, 1528 pavrc_cmd->addr_player.player_id, p_dev->rc_addr); 1529 } break; 1530 1531 case AVRC_PDU_SET_BROWSED_PLAYER: { 1532 fill_pdu_queue(IDX_SET_BROWSED_PLAYER_RSP, ctype, label, true, p_dev); 1533 HAL_CBACK(bt_rc_callbacks, set_browsed_player_cb, 1534 pavrc_cmd->br_player.player_id, p_dev->rc_addr); 1535 } break; 1536 1537 case AVRC_PDU_REQUEST_CONTINUATION_RSP: { 1538 BTIF_TRACE_EVENT("%s() REQUEST CONTINUATION: target_pdu: 0x%02d", 1539 __func__, pavrc_cmd->continu.target_pdu); 1540 tAVRC_RESPONSE avrc_rsp; 1541 if (p_dev->rc_connected == TRUE) { 1542 memset(&(avrc_rsp.continu), 0, sizeof(tAVRC_NEXT_RSP)); 1543 avrc_rsp.continu.opcode = 1544 opcode_from_pdu(AVRC_PDU_REQUEST_CONTINUATION_RSP); 1545 avrc_rsp.continu.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP; 1546 avrc_rsp.continu.status = AVRC_STS_NO_ERROR; 1547 avrc_rsp.continu.target_pdu = pavrc_cmd->continu.target_pdu; 1548 send_metamsg_rsp(p_dev, -1, label, ctype, &avrc_rsp); 1549 } 1550 } break; 1551 1552 case AVRC_PDU_ABORT_CONTINUATION_RSP: { 1553 BTIF_TRACE_EVENT("%s() ABORT CONTINUATION: target_pdu: 0x%02d", __func__, 1554 pavrc_cmd->abort.target_pdu); 1555 tAVRC_RESPONSE avrc_rsp; 1556 if (p_dev->rc_connected == TRUE) { 1557 memset(&(avrc_rsp.abort), 0, sizeof(tAVRC_NEXT_RSP)); 1558 avrc_rsp.abort.opcode = 1559 opcode_from_pdu(AVRC_PDU_ABORT_CONTINUATION_RSP); 1560 avrc_rsp.abort.pdu = AVRC_PDU_ABORT_CONTINUATION_RSP; 1561 avrc_rsp.abort.status = AVRC_STS_NO_ERROR; 1562 avrc_rsp.abort.target_pdu = pavrc_cmd->continu.target_pdu; 1563 send_metamsg_rsp(p_dev, -1, label, ctype, &avrc_rsp); 1564 } 1565 } break; 1566 1567 case AVRC_PDU_CHANGE_PATH: { 1568 fill_pdu_queue(IDX_CHG_PATH_RSP, ctype, label, true, p_dev); 1569 HAL_CBACK(bt_rc_callbacks, change_path_cb, pavrc_cmd->chg_path.direction, 1570 pavrc_cmd->chg_path.folder_uid, p_dev->rc_addr); 1571 } break; 1572 1573 case AVRC_PDU_SEARCH: { 1574 fill_pdu_queue(IDX_SEARCH_RSP, ctype, label, true, p_dev); 1575 HAL_CBACK(bt_rc_callbacks, search_cb, pavrc_cmd->search.string.charset_id, 1576 pavrc_cmd->search.string.str_len, 1577 pavrc_cmd->search.string.p_str, p_dev->rc_addr); 1578 } break; 1579 1580 case AVRC_PDU_GET_ITEM_ATTRIBUTES: { 1581 btrc_media_attr_t item_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1582 uint8_t num_attr = fill_attribute_id_array( 1583 pavrc_cmd->get_attrs.attr_count, 1584 (btrc_media_attr_t*)pavrc_cmd->get_attrs.p_attr_list, 1585 BTRC_MAX_ELEM_ATTR_SIZE, item_attrs); 1586 if (num_attr == 0) { 1587 BTIF_TRACE_ERROR( 1588 "%s: No valid attributes requested in GET_ITEM_ATTRIBUTES", 1589 __func__); 1590 send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, 1591 AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); 1592 return; 1593 } 1594 fill_pdu_queue(IDX_GET_ITEM_ATTR_RSP, ctype, label, true, p_dev); 1595 BTIF_TRACE_DEBUG("%s: GET_ITEM_ATTRIBUTES: num_attr: %d", __func__, 1596 num_attr); 1597 HAL_CBACK(bt_rc_callbacks, get_item_attr_cb, pavrc_cmd->get_attrs.scope, 1598 pavrc_cmd->get_attrs.uid, pavrc_cmd->get_attrs.uid_counter, 1599 num_attr, item_attrs, p_dev->rc_addr); 1600 } break; 1601 1602 case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS: { 1603 fill_pdu_queue(IDX_GET_TOTAL_NUM_OF_ITEMS_RSP, ctype, label, true, p_dev); 1604 HAL_CBACK(bt_rc_callbacks, get_total_num_of_items_cb, 1605 pavrc_cmd->get_num_of_items.scope, p_dev->rc_addr); 1606 } break; 1607 1608 case AVRC_PDU_ADD_TO_NOW_PLAYING: { 1609 fill_pdu_queue(IDX_ADD_TO_NOW_PLAYING_RSP, ctype, label, true, p_dev); 1610 HAL_CBACK(bt_rc_callbacks, add_to_now_playing_cb, 1611 pavrc_cmd->add_to_play.scope, pavrc_cmd->add_to_play.uid, 1612 pavrc_cmd->add_to_play.uid_counter, p_dev->rc_addr); 1613 } break; 1614 1615 case AVRC_PDU_PLAY_ITEM: { 1616 fill_pdu_queue(IDX_PLAY_ITEM_RSP, ctype, label, true, p_dev); 1617 HAL_CBACK(bt_rc_callbacks, play_item_cb, pavrc_cmd->play_item.scope, 1618 pavrc_cmd->play_item.uid_counter, pavrc_cmd->play_item.uid, 1619 p_dev->rc_addr); 1620 } break; 1621 1622 default: { 1623 send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, 1624 AVRC_STS_BAD_CMD, pavrc_cmd->cmd.opcode); 1625 return; 1626 } break; 1627 } 1628 } 1629 1630 /******************************************************************************* 1631 * 1632 * Function btif_rc_ctrl_upstreams_rsp_cmd 1633 * 1634 * Description Executes AVRC UPSTREAMS response events in btif context. 1635 * 1636 * Returns void 1637 * 1638 ******************************************************************************/ 1639 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, 1640 tAVRC_COMMAND* pavrc_cmd, 1641 uint8_t label, 1642 btif_rc_device_cb_t* p_dev) { 1643 BTIF_TRACE_DEBUG("%s: pdu: %s: handle: 0x%x", __func__, 1644 dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle); 1645 switch (event) { 1646 case AVRC_PDU_SET_ABSOLUTE_VOLUME: 1647 do_in_jni_thread( 1648 FROM_HERE, 1649 base::Bind(bt_rc_ctrl_callbacks->setabsvol_cmd_cb, p_dev->rc_addr, 1650 pavrc_cmd->volume.volume, label)); 1651 break; 1652 case AVRC_PDU_REGISTER_NOTIFICATION: 1653 if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE) { 1654 do_in_jni_thread( 1655 FROM_HERE, 1656 base::Bind(bt_rc_ctrl_callbacks->registernotification_absvol_cb, 1657 p_dev->rc_addr, label)); 1658 } 1659 break; 1660 } 1661 } 1662 1663 /******************************************************************************* 1664 * 1665 * Function btif_rc_upstreams_rsp_evt 1666 * 1667 * Description Executes AVRC UPSTREAMS response events in btif context. 1668 * 1669 * Returns void 1670 * 1671 ******************************************************************************/ 1672 static void btif_rc_upstreams_rsp_evt(uint16_t event, 1673 tAVRC_RESPONSE* pavrc_resp, uint8_t ctype, 1674 uint8_t label, 1675 btif_rc_device_cb_t* p_dev) { 1676 BTIF_TRACE_EVENT("%s: pdu: %s: handle: 0x%x ctype: %x label: %x", __func__, 1677 dump_rc_pdu(pavrc_resp->pdu), p_dev->rc_handle, ctype, 1678 label); 1679 1680 switch (event) { 1681 case AVRC_PDU_REGISTER_NOTIFICATION: { 1682 if (AVRC_RSP_CHANGED == ctype) 1683 p_dev->rc_volume = pavrc_resp->reg_notif.param.volume; 1684 HAL_CBACK(bt_rc_callbacks, volume_change_cb, 1685 pavrc_resp->reg_notif.param.volume, ctype, p_dev->rc_addr); 1686 } break; 1687 1688 case AVRC_PDU_SET_ABSOLUTE_VOLUME: { 1689 BTIF_TRACE_DEBUG( 1690 "%s: Set absolute volume change event received: volume: %d, ctype: " 1691 "%d", 1692 __func__, pavrc_resp->volume.volume, ctype); 1693 if (AVRC_RSP_ACCEPT == ctype) 1694 p_dev->rc_volume = pavrc_resp->volume.volume; 1695 HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->volume.volume, 1696 ctype, p_dev->rc_addr); 1697 } break; 1698 1699 default: 1700 return; 1701 } 1702 } 1703 1704 /******************************************************************************* 1705 * AVRCP API Functions 1706 ******************************************************************************/ 1707 1708 /******************************************************************************* 1709 * 1710 * Function init 1711 * 1712 * Description Initializes the AVRC interface 1713 * 1714 * Returns bt_status_t 1715 * 1716 ******************************************************************************/ 1717 static bt_status_t init(btrc_callbacks_t* callbacks) { 1718 BTIF_TRACE_EVENT("%s: ", __func__); 1719 bt_status_t result = BT_STATUS_SUCCESS; 1720 1721 if (bt_rc_callbacks) return BT_STATUS_DONE; 1722 1723 bt_rc_callbacks = callbacks; 1724 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 1725 memset(&btif_rc_cb.rc_multi_cb[idx], 0, 1726 sizeof(btif_rc_cb.rc_multi_cb[idx])); 1727 btif_rc_cb.rc_multi_cb[idx].rc_vol_label = MAX_LABEL; 1728 btif_rc_cb.rc_multi_cb[idx].rc_volume = MAX_VOLUME; 1729 btif_rc_cb.rc_multi_cb[idx].rc_state = BTRC_CONNECTION_STATE_DISCONNECTED; 1730 } 1731 lbl_init(); 1732 1733 return result; 1734 } 1735 1736 /******************************************************************************* 1737 * 1738 * Function init_ctrl 1739 * 1740 * Description Initializes the AVRC interface 1741 * 1742 * Returns bt_status_t 1743 * 1744 ******************************************************************************/ 1745 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks) { 1746 BTIF_TRACE_EVENT("%s: ", __func__); 1747 bt_status_t result = BT_STATUS_SUCCESS; 1748 1749 if (bt_rc_ctrl_callbacks) return BT_STATUS_DONE; 1750 1751 bt_rc_ctrl_callbacks = callbacks; 1752 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 1753 memset(&btif_rc_cb.rc_multi_cb[idx], 0, 1754 sizeof(btif_rc_cb.rc_multi_cb[idx])); 1755 btif_rc_cb.rc_multi_cb[idx].rc_vol_label = MAX_LABEL; 1756 btif_rc_cb.rc_multi_cb[idx].rc_volume = MAX_VOLUME; 1757 } 1758 lbl_init(); 1759 1760 return result; 1761 } 1762 1763 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev) { 1764 if (p_dev == NULL) { 1765 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 1766 return; 1767 } 1768 1769 if (p_dev->rc_procedure_complete) { 1770 return; 1771 } 1772 p_dev->rc_procedure_complete = true; 1773 uint32_t attr_list[] = { 1774 AVRC_MEDIA_ATTR_ID_TITLE, AVRC_MEDIA_ATTR_ID_ARTIST, 1775 AVRC_MEDIA_ATTR_ID_ALBUM, AVRC_MEDIA_ATTR_ID_TRACK_NUM, 1776 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, AVRC_MEDIA_ATTR_ID_GENRE, 1777 AVRC_MEDIA_ATTR_ID_PLAYING_TIME}; 1778 get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, p_dev); 1779 } 1780 1781 /*************************************************************************** 1782 * 1783 * Function get_play_status_rsp 1784 * 1785 * Description Returns the current play status. 1786 * This method is called in response to 1787 * GetPlayStatus request. 1788 * 1789 * Returns bt_status_t 1790 * 1791 **************************************************************************/ 1792 static bt_status_t get_play_status_rsp(const RawAddress& bd_addr, 1793 btrc_play_status_t play_status, 1794 uint32_t song_len, uint32_t song_pos) { 1795 tAVRC_RESPONSE avrc_rsp; 1796 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 1797 1798 BTIF_TRACE_DEBUG("%s: song len %d song pos %d", __func__, song_len, song_pos); 1799 CHECK_RC_CONNECTED(p_dev); 1800 1801 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP)); 1802 1803 avrc_rsp.get_play_status.song_len = song_len; 1804 avrc_rsp.get_play_status.song_pos = song_pos; 1805 avrc_rsp.get_play_status.play_status = play_status; 1806 1807 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 1808 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS); 1809 avrc_rsp.get_play_status.status = 1810 ((play_status != BTRC_PLAYSTATE_ERROR) ? AVRC_STS_NO_ERROR 1811 : AVRC_STS_BAD_PARAM); 1812 1813 /* Send the response */ 1814 send_metamsg_rsp(p_dev, IDX_GET_PLAY_STATUS_RSP, 1815 p_dev->rc_pdu_info[IDX_GET_PLAY_STATUS_RSP].label, 1816 p_dev->rc_pdu_info[IDX_GET_PLAY_STATUS_RSP].ctype, 1817 &avrc_rsp); 1818 1819 return BT_STATUS_SUCCESS; 1820 } 1821 1822 /*************************************************************************** 1823 * 1824 * Function get_element_attr_rsp 1825 * 1826 * Description Returns the current songs' element attributes 1827 * in text. 1828 * 1829 * Returns bt_status_t 1830 * 1831 **************************************************************************/ 1832 static bt_status_t get_element_attr_rsp(const RawAddress& bd_addr, 1833 uint8_t num_attr, 1834 btrc_element_attr_val_t* p_attrs) { 1835 tAVRC_RESPONSE avrc_rsp; 1836 uint32_t i; 1837 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 1838 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 1839 1840 BTIF_TRACE_DEBUG("%s", __func__); 1841 CHECK_RC_CONNECTED(p_dev); 1842 1843 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); 1844 1845 if (num_attr == 0) { 1846 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM; 1847 } else { 1848 for (i = 0; i < num_attr; i++) { 1849 element_attrs[i].attr_id = p_attrs[i].attr_id; 1850 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8; 1851 element_attrs[i].name.str_len = (uint16_t)strlen((char*)p_attrs[i].text); 1852 element_attrs[i].name.p_str = p_attrs[i].text; 1853 BTIF_TRACE_DEBUG( 1854 "%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", __func__, 1855 (unsigned int)element_attrs[i].attr_id, 1856 element_attrs[i].name.charset_id, element_attrs[i].name.str_len, 1857 element_attrs[i].name.p_str); 1858 } 1859 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1860 } 1861 avrc_rsp.get_attrs.num_attrs = num_attr; 1862 avrc_rsp.get_attrs.p_attrs = element_attrs; 1863 avrc_rsp.get_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 1864 avrc_rsp.get_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR); 1865 1866 /* Send the response */ 1867 send_metamsg_rsp(p_dev, IDX_GET_ELEMENT_ATTR_RSP, 1868 p_dev->rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP].label, 1869 p_dev->rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP].ctype, 1870 &avrc_rsp); 1871 1872 return BT_STATUS_SUCCESS; 1873 } 1874 1875 /*************************************************************************** 1876 * 1877 * Function register_notification_rsp 1878 * 1879 * Description Response to the register notification request. 1880 * 1881 * Returns bt_status_t 1882 * 1883 **************************************************************************/ 1884 static bt_status_t register_notification_rsp( 1885 btrc_event_id_t event_id, btrc_notification_type_t type, 1886 btrc_register_notification_t* p_param) { 1887 tAVRC_RESPONSE avrc_rsp; 1888 BTIF_TRACE_EVENT("%s: event_id: %s", __func__, 1889 dump_rc_notification_event_id(event_id)); 1890 std::unique_lock<std::mutex> lock(btif_rc_cb.lock); 1891 1892 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP)); 1893 1894 avrc_rsp.reg_notif.event_id = event_id; 1895 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 1896 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION); 1897 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; 1898 1899 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 1900 memset(&(avrc_rsp.reg_notif.param), 0, sizeof(tAVRC_NOTIF_RSP_PARAM)); 1901 1902 if (!(btif_rc_cb.rc_multi_cb[idx].rc_connected)) { 1903 BTIF_TRACE_ERROR("%s: Avrcp device is not connected, handle: 0x%x", 1904 __func__, btif_rc_cb.rc_multi_cb[idx].rc_handle); 1905 continue; 1906 } 1907 1908 if (!btif_rc_cb.rc_multi_cb[idx].rc_notif[event_id - 1].bNotify) { 1909 BTIF_TRACE_WARNING( 1910 "%s: Avrcp Event id is not registered: event_id: %x, handle: 0x%x", 1911 __func__, event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle); 1912 continue; 1913 } 1914 1915 BTIF_TRACE_DEBUG( 1916 "%s: Avrcp Event id is registered: event_id: %x handle: 0x%x", __func__, 1917 event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle); 1918 1919 switch (event_id) { 1920 case BTRC_EVT_PLAY_STATUS_CHANGED: 1921 avrc_rsp.reg_notif.param.play_status = p_param->play_status; 1922 if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING) 1923 btif_av_clear_remote_suspend_flag(); 1924 break; 1925 case BTRC_EVT_TRACK_CHANGE: 1926 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), 1927 sizeof(btrc_uid_t)); 1928 break; 1929 case BTRC_EVT_PLAY_POS_CHANGED: 1930 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos; 1931 break; 1932 case BTRC_EVT_AVAL_PLAYER_CHANGE: 1933 break; 1934 case BTRC_EVT_ADDR_PLAYER_CHANGE: 1935 avrc_rsp.reg_notif.param.addr_player.player_id = 1936 p_param->addr_player_changed.player_id; 1937 avrc_rsp.reg_notif.param.addr_player.uid_counter = 1938 p_param->addr_player_changed.uid_counter; 1939 break; 1940 case BTRC_EVT_UIDS_CHANGED: 1941 avrc_rsp.reg_notif.param.uid_counter = 1942 p_param->uids_changed.uid_counter; 1943 break; 1944 case BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED: 1945 break; 1946 1947 default: 1948 BTIF_TRACE_WARNING("%s: Unhandled event ID: 0x%x", __func__, event_id); 1949 return BT_STATUS_UNHANDLED; 1950 } 1951 1952 /* Send the response. */ 1953 send_metamsg_rsp( 1954 &btif_rc_cb.rc_multi_cb[idx], -1, 1955 btif_rc_cb.rc_multi_cb[idx].rc_notif[event_id - 1].label, 1956 ((type == BTRC_NOTIFICATION_TYPE_INTERIM) ? AVRC_CMD_NOTIF 1957 : AVRC_RSP_CHANGED), 1958 &avrc_rsp); 1959 } 1960 return BT_STATUS_SUCCESS; 1961 } 1962 1963 /*************************************************************************** 1964 * 1965 * Function get_folder_items_list_rsp 1966 * 1967 * Description Returns the list of media items in current folder along with 1968 * requested attributes. This is called in response to 1969 * GetFolderItems request. 1970 * 1971 * Returns bt_status_t 1972 * BT_STATUS_NOT_READY - when RC is not connected. 1973 * BT_STATUS_SUCCESS - always if RC is connected 1974 * BT_STATUS_UNHANDLED - when rsp is not pending for 1975 * get_folder_items_list PDU 1976 * 1977 **************************************************************************/ 1978 static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr, 1979 btrc_status_t rsp_status, 1980 uint16_t uid_counter, 1981 uint8_t num_items, 1982 btrc_folder_items_t* p_items) { 1983 tAVRC_RESPONSE avrc_rsp; 1984 tAVRC_ITEM item; 1985 tBTA_AV_CODE code = 0, ctype = 0; 1986 BT_HDR* p_msg = NULL; 1987 int item_cnt; 1988 tAVRC_STS status = AVRC_STS_NO_ERROR; 1989 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 1990 btrc_folder_items_t* cur_item = NULL; 1991 1992 BTIF_TRACE_DEBUG("%s: uid_counter %d num_items %d", __func__, uid_counter, 1993 num_items); 1994 CHECK_RC_CONNECTED(p_dev); 1995 1996 /* check if rsp to previous cmd was completed */ 1997 if (!p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].is_rsp_pending) { 1998 BTIF_TRACE_WARNING("%s: Not sending response as no PDU was registered", 1999 __func__); 2000 return BT_STATUS_UNHANDLED; 2001 } 2002 2003 memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 2004 memset(&item, 0, sizeof(tAVRC_ITEM)); 2005 2006 avrc_rsp.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS; 2007 avrc_rsp.get_items.opcode = opcode_from_pdu(AVRC_PDU_GET_FOLDER_ITEMS); 2008 avrc_rsp.get_items.status = status_code_map[rsp_status]; 2009 2010 if (avrc_rsp.get_items.status != AVRC_STS_NO_ERROR) { 2011 BTIF_TRACE_WARNING( 2012 "%s: Error in parsing the received getfolderitems cmd. status: 0x%02x", 2013 __func__, avrc_rsp.get_items.status); 2014 status = avrc_rsp.get_items.status; 2015 } else { 2016 avrc_rsp.get_items.uid_counter = uid_counter; 2017 avrc_rsp.get_items.item_count = 1; 2018 2019 /* create single item and build response iteratively for all num_items */ 2020 for (item_cnt = 0; item_cnt < num_items; item_cnt++) { 2021 cur_item = &p_items[item_cnt]; 2022 item.item_type = p_items->item_type; 2023 /* build respective item based on item_type. All items should be of same 2024 * type within 2025 * a response */ 2026 switch (p_items->item_type) { 2027 case AVRC_ITEM_PLAYER: { 2028 item.u.player.name.charset_id = cur_item->player.charset_id; 2029 memcpy(&(item.u.player.features), &(cur_item->player.features), 2030 sizeof(cur_item->player.features)); 2031 item.u.player.major_type = cur_item->player.major_type; 2032 item.u.player.sub_type = cur_item->player.sub_type; 2033 item.u.player.play_status = cur_item->player.play_status; 2034 item.u.player.player_id = cur_item->player.player_id; 2035 item.u.player.name.p_str = cur_item->player.name; 2036 item.u.player.name.str_len = 2037 (uint16_t)strlen((char*)(cur_item->player.name)); 2038 } break; 2039 2040 case AVRC_ITEM_FOLDER: { 2041 memcpy(item.u.folder.uid, cur_item->folder.uid, sizeof(tAVRC_UID)); 2042 item.u.folder.type = cur_item->folder.type; 2043 item.u.folder.playable = cur_item->folder.playable; 2044 item.u.folder.name.charset_id = AVRC_CHARSET_ID_UTF8; 2045 item.u.folder.name.str_len = strlen((char*)cur_item->folder.name); 2046 item.u.folder.name.p_str = cur_item->folder.name; 2047 } break; 2048 2049 case AVRC_ITEM_MEDIA: { 2050 tAVRC_ATTR_ENTRY attr_vals[BTRC_MAX_ELEM_ATTR_SIZE]; 2051 2052 memcpy(item.u.media.uid, cur_item->media.uid, sizeof(tAVRC_UID)); 2053 item.u.media.type = cur_item->media.type; 2054 item.u.media.name.charset_id = cur_item->media.charset_id; 2055 item.u.media.name.str_len = strlen((char*)cur_item->media.name); 2056 item.u.media.name.p_str = cur_item->media.name; 2057 item.u.media.attr_count = cur_item->media.num_attrs; 2058 2059 /* Handle attributes of given item */ 2060 if (item.u.media.attr_count == 0) { 2061 item.u.media.p_attr_list = NULL; 2062 } else { 2063 memset(&attr_vals, 0, 2064 sizeof(tAVRC_ATTR_ENTRY) * BTRC_MAX_ELEM_ATTR_SIZE); 2065 fill_avrc_attr_entry(attr_vals, item.u.media.attr_count, 2066 cur_item->media.p_attrs); 2067 item.u.media.p_attr_list = attr_vals; 2068 } 2069 } break; 2070 2071 default: { 2072 BTIF_TRACE_ERROR("%s: Unknown item_type: %d. Internal Error", 2073 __func__, p_items->item_type); 2074 status = AVRC_STS_INTERNAL_ERR; 2075 } break; 2076 } 2077 2078 avrc_rsp.get_items.p_item_list = &item; 2079 2080 /* Add current item to buffer and build response if no error in item type 2081 */ 2082 if (status != AVRC_STS_NO_ERROR) { 2083 /* Reject response due to error occured for unknown item_type, break the 2084 * loop */ 2085 break; 2086 } 2087 2088 int len_before = p_msg ? p_msg->len : 0; 2089 BTIF_TRACE_DEBUG("%s: item_cnt: %d len: %d", __func__, item_cnt, 2090 len_before); 2091 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); 2092 BTIF_TRACE_DEBUG("%s: Build rsp status: %d len: %d", __func__, status, 2093 (p_msg ? p_msg->len : 0)); 2094 int len_after = p_msg ? p_msg->len : 0; 2095 if (status != AVRC_STS_NO_ERROR || len_before == len_after) { 2096 /* Error occured in build response or we ran out of buffer so break the 2097 * loop */ 2098 break; 2099 } 2100 } 2101 2102 /* setting the error status */ 2103 avrc_rsp.get_items.status = status; 2104 } 2105 2106 /* if packet built successfully, send the built items to BTA layer */ 2107 if (status == AVRC_STS_NO_ERROR) { 2108 code = p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].ctype; 2109 ctype = get_rsp_type_code(avrc_rsp.get_items.status, code); 2110 BTA_AvMetaRsp(p_dev->rc_handle, 2111 p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label, ctype, 2112 p_msg); 2113 } else /* Error occured, send reject response */ 2114 { 2115 BTIF_TRACE_ERROR("%s: Error status: 0x%02X. Sending reject rsp", __func__, 2116 avrc_rsp.rsp.status); 2117 send_reject_response( 2118 p_dev->rc_handle, p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label, 2119 avrc_rsp.pdu, avrc_rsp.get_items.status, avrc_rsp.get_items.opcode); 2120 } 2121 2122 /* Reset values for current pdu. */ 2123 p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].ctype = 0; 2124 p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label = 0; 2125 p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].is_rsp_pending = false; 2126 2127 return status == AVRC_STS_NO_ERROR ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; 2128 } 2129 2130 /*************************************************************************** 2131 * 2132 * Function set_addressed_player_rsp 2133 * 2134 * Description Response to set the addressed player for specified media 2135 * player based on id in the media player list. 2136 * 2137 * Returns bt_status_t 2138 * BT_STATUS_NOT_READY - when RC is not connected. 2139 * BT_STATUS_SUCCESS - always if RC is connected 2140 * 2141 **************************************************************************/ 2142 static bt_status_t set_addressed_player_rsp(const RawAddress& bd_addr, 2143 btrc_status_t rsp_status) { 2144 tAVRC_RESPONSE avrc_rsp; 2145 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2146 2147 BTIF_TRACE_DEBUG("%s", __func__); 2148 CHECK_RC_CONNECTED(p_dev); 2149 2150 avrc_rsp.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER; 2151 avrc_rsp.addr_player.opcode = opcode_from_pdu(AVRC_PDU_SET_ADDRESSED_PLAYER); 2152 avrc_rsp.addr_player.status = status_code_map[rsp_status]; 2153 2154 /* Send the response. */ 2155 send_metamsg_rsp(p_dev, IDX_SET_ADDR_PLAYER_RSP, 2156 p_dev->rc_pdu_info[IDX_SET_ADDR_PLAYER_RSP].label, 2157 p_dev->rc_pdu_info[IDX_SET_ADDR_PLAYER_RSP].ctype, 2158 &avrc_rsp); 2159 2160 return BT_STATUS_SUCCESS; 2161 } 2162 2163 /*************************************************************************** 2164 * 2165 * Function set_browsed_player_rsp 2166 * 2167 * Description Response to set the browsed player command which contains 2168 * current browsed path of the media player. By default, 2169 * current_path = root and folder_depth = 0 for 2170 * every set_browsed_player request. 2171 * 2172 * Returns bt_status_t 2173 * BT_STATUS_NOT_READY - when RC is not connected. 2174 * BT_STATUS_SUCCESS - if RC is connected and reponse 2175 * sent successfully 2176 * BT_STATUS_UNHANDLED - when rsp is not pending for 2177 * set_browsed_player PDU 2178 * 2179 **************************************************************************/ 2180 static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr, 2181 btrc_status_t rsp_status, 2182 uint32_t num_items, 2183 uint16_t charset_id, 2184 uint8_t folder_depth, 2185 btrc_br_folder_name_t* p_folders) { 2186 tAVRC_RESPONSE avrc_rsp; 2187 tAVRC_NAME item; 2188 BT_HDR* p_msg = NULL; 2189 tBTA_AV_CODE code = 0; 2190 tBTA_AV_CODE ctype = 0; 2191 unsigned int item_cnt; 2192 tAVRC_STS status = AVRC_STS_NO_ERROR; 2193 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2194 2195 CHECK_RC_CONNECTED(p_dev); 2196 2197 memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE)); 2198 memset(&item, 0, sizeof(tAVRC_NAME)); 2199 2200 avrc_rsp.br_player.status = status_code_map[rsp_status]; 2201 avrc_rsp.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER; 2202 avrc_rsp.br_player.opcode = opcode_from_pdu(AVRC_PDU_SET_BROWSED_PLAYER); 2203 2204 BTIF_TRACE_DEBUG("%s: rsp_status: 0x%02X avrc_rsp.br_player.status: 0x%02X", 2205 __func__, rsp_status, avrc_rsp.br_player.status); 2206 2207 /* check if rsp to previous cmd was completed */ 2208 if (!p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].is_rsp_pending) { 2209 BTIF_TRACE_WARNING("%s: Not sending response as no PDU was registered", 2210 __func__); 2211 return BT_STATUS_UNHANDLED; 2212 } 2213 2214 if (AVRC_STS_NO_ERROR == avrc_rsp.get_items.status) { 2215 avrc_rsp.br_player.num_items = num_items; 2216 avrc_rsp.br_player.charset_id = charset_id; 2217 avrc_rsp.br_player.folder_depth = folder_depth; 2218 avrc_rsp.br_player.p_folders = (tAVRC_NAME*)p_folders; 2219 2220 BTIF_TRACE_DEBUG("%s: folder_depth: 0x%02X num_items: %d", __func__, 2221 folder_depth, num_items); 2222 2223 if (folder_depth > 0) { 2224 /* Iteratively build response for all folders across folder depth upto 2225 * current path */ 2226 avrc_rsp.br_player.folder_depth = 1; 2227 for (item_cnt = 0; item_cnt < folder_depth; item_cnt++) { 2228 BTIF_TRACE_DEBUG("%s: iteration: %d", __func__, item_cnt); 2229 item.str_len = p_folders[item_cnt].str_len; 2230 item.p_str = p_folders[item_cnt].p_str; 2231 avrc_rsp.br_player.p_folders = &item; 2232 2233 /* Add current item to buffer and build response */ 2234 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); 2235 if (AVRC_STS_NO_ERROR != status) { 2236 BTIF_TRACE_WARNING("%s: Build rsp status: %d", __func__, status); 2237 /* if the build fails, it is likely that we ran out of buffer. so if 2238 * we have 2239 * some items to send, reset this error to no error for sending what we 2240 * have */ 2241 if (item_cnt > 0) status = AVRC_STS_NO_ERROR; 2242 2243 /* Error occured in build response so break the loop */ 2244 break; 2245 } 2246 } 2247 } else /* current path is root folder, no folders navigated yet */ 2248 { 2249 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); 2250 } 2251 2252 /* setting the error status */ 2253 avrc_rsp.br_player.status = status; 2254 } else /* error received from above layer */ 2255 { 2256 BTIF_TRACE_WARNING( 2257 "%s: Error in parsing the received setbrowsed command. status: 0x%02x", 2258 __func__, avrc_rsp.br_player.status); 2259 status = avrc_rsp.br_player.status; 2260 } 2261 2262 /* if packet built successfully, send the built items to BTA layer */ 2263 if (status == AVRC_STS_NO_ERROR) { 2264 code = p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].ctype; 2265 ctype = get_rsp_type_code(avrc_rsp.br_player.status, code); 2266 BTA_AvMetaRsp(p_dev->rc_handle, 2267 p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label, ctype, 2268 p_msg); 2269 } else /* Error occured, send reject response */ 2270 { 2271 BTIF_TRACE_ERROR("%s: Error status: 0x%02X. Sending reject rsp", __func__, 2272 avrc_rsp.br_player.status); 2273 send_reject_response( 2274 p_dev->rc_handle, p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label, 2275 avrc_rsp.pdu, avrc_rsp.br_player.status, avrc_rsp.get_items.opcode); 2276 } 2277 2278 /* Reset values for set_browsed_player pdu.*/ 2279 p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].ctype = 0; 2280 p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label = 0; 2281 p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].is_rsp_pending = false; 2282 2283 return status == AVRC_STS_NO_ERROR ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; 2284 } 2285 2286 /******************************************************************************* 2287 * 2288 * Function change_path_rsp 2289 * 2290 * Description Response to the change path command which 2291 * contains number of items in the changed path. 2292 * 2293 * Returns bt_status_t 2294 * BT_STATUS_NOT_READY - when RC is not connected. 2295 * BT_STATUS_SUCCESS - always if RC is connected 2296 * 2297 **************************************************************************/ 2298 static bt_status_t change_path_rsp(const RawAddress& bd_addr, 2299 btrc_status_t rsp_status, 2300 uint32_t num_items) { 2301 tAVRC_RESPONSE avrc_rsp; 2302 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2303 2304 BTIF_TRACE_DEBUG("%s", __func__); 2305 CHECK_RC_CONNECTED(p_dev); 2306 2307 avrc_rsp.chg_path.pdu = AVRC_PDU_CHANGE_PATH; 2308 avrc_rsp.chg_path.opcode = opcode_from_pdu(AVRC_PDU_CHANGE_PATH); 2309 avrc_rsp.chg_path.num_items = num_items; 2310 avrc_rsp.chg_path.status = status_code_map[rsp_status]; 2311 2312 /* Send the response. */ 2313 send_metamsg_rsp(p_dev, IDX_CHG_PATH_RSP, 2314 p_dev->rc_pdu_info[IDX_CHG_PATH_RSP].label, 2315 p_dev->rc_pdu_info[IDX_CHG_PATH_RSP].ctype, &avrc_rsp); 2316 2317 return BT_STATUS_SUCCESS; 2318 } 2319 2320 /*************************************************************************** 2321 * 2322 * Function search_rsp 2323 * 2324 * Description Response to search a string from media content command. 2325 * 2326 * Returns bt_status_t 2327 * BT_STATUS_NOT_READY - when RC is not connected. 2328 * BT_STATUS_SUCCESS - always if RC is connected 2329 * 2330 **************************************************************************/ 2331 static bt_status_t search_rsp(const RawAddress& bd_addr, 2332 btrc_status_t rsp_status, uint32_t uid_counter, 2333 uint32_t num_items) { 2334 tAVRC_RESPONSE avrc_rsp; 2335 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2336 2337 BTIF_TRACE_DEBUG("%s", __func__); 2338 CHECK_RC_CONNECTED(p_dev); 2339 2340 avrc_rsp.search.pdu = AVRC_PDU_SEARCH; 2341 avrc_rsp.search.opcode = opcode_from_pdu(AVRC_PDU_SEARCH); 2342 avrc_rsp.search.num_items = num_items; 2343 avrc_rsp.search.uid_counter = uid_counter; 2344 avrc_rsp.search.status = status_code_map[rsp_status]; 2345 2346 /* Send the response. */ 2347 send_metamsg_rsp(p_dev, IDX_SEARCH_RSP, 2348 p_dev->rc_pdu_info[IDX_SEARCH_RSP].label, 2349 p_dev->rc_pdu_info[IDX_SEARCH_RSP].ctype, &avrc_rsp); 2350 2351 return BT_STATUS_SUCCESS; 2352 } 2353 /*************************************************************************** 2354 * 2355 * Function get_item_attr_rsp 2356 * 2357 * Description Response to the get item's attributes command which 2358 * contains number of attributes and values list in text. 2359 * 2360 * Returns bt_status_t 2361 * BT_STATUS_NOT_READY - when RC is not connected. 2362 * BT_STATUS_SUCCESS - always if RC is connected 2363 * 2364 **************************************************************************/ 2365 static bt_status_t get_item_attr_rsp(const RawAddress& bd_addr, 2366 btrc_status_t rsp_status, uint8_t num_attr, 2367 btrc_element_attr_val_t* p_attrs) { 2368 tAVRC_RESPONSE avrc_rsp; 2369 tAVRC_ATTR_ENTRY item_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; 2370 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2371 2372 BTIF_TRACE_DEBUG("%s", __func__); 2373 CHECK_RC_CONNECTED(p_dev); 2374 2375 memset(item_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); 2376 2377 avrc_rsp.get_attrs.status = status_code_map[rsp_status]; 2378 if (rsp_status == BTRC_STS_NO_ERROR) { 2379 fill_avrc_attr_entry(item_attrs, num_attr, p_attrs); 2380 } 2381 2382 avrc_rsp.get_attrs.num_attrs = num_attr; 2383 avrc_rsp.get_attrs.p_attrs = item_attrs; 2384 avrc_rsp.get_attrs.pdu = AVRC_PDU_GET_ITEM_ATTRIBUTES; 2385 avrc_rsp.get_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ITEM_ATTRIBUTES); 2386 2387 /* Send the response. */ 2388 send_metamsg_rsp(p_dev, IDX_GET_ITEM_ATTR_RSP, 2389 p_dev->rc_pdu_info[IDX_GET_ITEM_ATTR_RSP].label, 2390 p_dev->rc_pdu_info[IDX_GET_ITEM_ATTR_RSP].ctype, &avrc_rsp); 2391 2392 return BT_STATUS_SUCCESS; 2393 } 2394 2395 /*************************************************************************** 2396 * 2397 * Function add_to_now_playing_rsp 2398 * 2399 * Description Response to command for adding speciafied media item 2400 * to Now Playing queue. 2401 * 2402 * Returns bt_status_t 2403 * BT_STATUS_NOT_READY - when RC is not connected. 2404 * BT_STATUS_SUCCESS - always if RC is connected 2405 * 2406 **************************************************************************/ 2407 static bt_status_t add_to_now_playing_rsp(const RawAddress& bd_addr, 2408 btrc_status_t rsp_status) { 2409 tAVRC_RESPONSE avrc_rsp; 2410 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2411 2412 BTIF_TRACE_DEBUG("%s", __func__); 2413 CHECK_RC_CONNECTED(p_dev); 2414 2415 avrc_rsp.add_to_play.pdu = AVRC_PDU_ADD_TO_NOW_PLAYING; 2416 avrc_rsp.add_to_play.opcode = opcode_from_pdu(AVRC_PDU_ADD_TO_NOW_PLAYING); 2417 avrc_rsp.add_to_play.status = status_code_map[rsp_status]; 2418 2419 /* Send the response. */ 2420 send_metamsg_rsp(p_dev, IDX_ADD_TO_NOW_PLAYING_RSP, 2421 p_dev->rc_pdu_info[IDX_ADD_TO_NOW_PLAYING_RSP].label, 2422 p_dev->rc_pdu_info[IDX_ADD_TO_NOW_PLAYING_RSP].ctype, 2423 &avrc_rsp); 2424 2425 return BT_STATUS_SUCCESS; 2426 } 2427 2428 /*************************************************************************** 2429 * 2430 * Function play_item_rsp 2431 * 2432 * Description Response to command for playing the specified media item. 2433 * 2434 * Returns bt_status_t 2435 * BT_STATUS_NOT_READY - when RC is not connected. 2436 * BT_STATUS_SUCCESS - always if RC is connected 2437 * 2438 **************************************************************************/ 2439 static bt_status_t play_item_rsp(const RawAddress& bd_addr, 2440 btrc_status_t rsp_status) { 2441 tAVRC_RESPONSE avrc_rsp; 2442 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2443 2444 BTIF_TRACE_DEBUG("%s", __func__); 2445 CHECK_RC_CONNECTED(p_dev); 2446 2447 avrc_rsp.play_item.pdu = AVRC_PDU_PLAY_ITEM; 2448 avrc_rsp.play_item.opcode = opcode_from_pdu(AVRC_PDU_PLAY_ITEM); 2449 avrc_rsp.play_item.status = status_code_map[rsp_status]; 2450 2451 /* Send the response. */ 2452 send_metamsg_rsp(p_dev, IDX_PLAY_ITEM_RSP, 2453 p_dev->rc_pdu_info[IDX_PLAY_ITEM_RSP].label, 2454 p_dev->rc_pdu_info[IDX_PLAY_ITEM_RSP].ctype, &avrc_rsp); 2455 2456 return BT_STATUS_SUCCESS; 2457 } 2458 2459 /*************************************************************************** 2460 * 2461 * Function get_total_num_of_items_rsp 2462 * 2463 * Description response to command to get the Number of Items 2464 * in the selected folder at the selected scope 2465 * 2466 * Returns bt_status_t 2467 * BT_STATUS_NOT_READY - when RC is not connected. 2468 * BT_STATUS_SUCCESS - always if RC is connected 2469 * 2470 **************************************************************************/ 2471 static bt_status_t get_total_num_of_items_rsp(const RawAddress& bd_addr, 2472 btrc_status_t rsp_status, 2473 uint32_t uid_counter, 2474 uint32_t num_items) { 2475 tAVRC_RESPONSE avrc_rsp; 2476 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 2477 2478 BTIF_TRACE_DEBUG("%s", __func__); 2479 CHECK_RC_CONNECTED(p_dev); 2480 2481 avrc_rsp.get_num_of_items.pdu = AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS; 2482 avrc_rsp.get_num_of_items.opcode = 2483 opcode_from_pdu(AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS); 2484 avrc_rsp.get_num_of_items.num_items = num_items; 2485 avrc_rsp.get_num_of_items.uid_counter = uid_counter; 2486 avrc_rsp.get_num_of_items.status = status_code_map[rsp_status]; 2487 2488 /* Send the response. */ 2489 send_metamsg_rsp(p_dev, IDX_GET_TOTAL_NUM_OF_ITEMS_RSP, 2490 p_dev->rc_pdu_info[IDX_GET_TOTAL_NUM_OF_ITEMS_RSP].label, 2491 p_dev->rc_pdu_info[IDX_GET_TOTAL_NUM_OF_ITEMS_RSP].ctype, 2492 &avrc_rsp); 2493 2494 return BT_STATUS_SUCCESS; 2495 } 2496 2497 /*************************************************************************** 2498 * 2499 * Function set_volume 2500 * 2501 * Description Send current volume setting to remote side. 2502 * Support limited to SetAbsoluteVolume 2503 * This can be enhanced to support Relative Volume (AVRCP 1.0). 2504 * With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN 2505 * as opposed to absolute volume level 2506 * volume: Should be in the range 0-127. bit7 is reseved and cannot be set 2507 * 2508 * Returns bt_status_t 2509 * 2510 **************************************************************************/ 2511 static bt_status_t set_volume(uint8_t volume) { 2512 BTIF_TRACE_DEBUG("%s: volume: %d", __func__, volume); 2513 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 2514 2515 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 2516 if (!btif_rc_cb.rc_multi_cb[idx].rc_connected) continue; 2517 2518 if (btif_rc_cb.rc_multi_cb[idx].rc_volume == volume) { 2519 status = BT_STATUS_DONE; 2520 BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x", __func__, 2521 volume); 2522 continue; 2523 } 2524 2525 if ((btif_rc_cb.rc_multi_cb[idx].rc_volume == volume) || 2526 btif_rc_cb.rc_multi_cb[idx].rc_state != 2527 BTRC_CONNECTION_STATE_CONNECTED) { 2528 continue; 2529 } 2530 2531 if ((btif_rc_cb.rc_multi_cb[idx].rc_features & BTA_AV_FEAT_RCTG) == 0) { 2532 status = BT_STATUS_NOT_READY; 2533 continue; 2534 } 2535 2536 if (!(btif_rc_cb.rc_multi_cb[idx].rc_features & BTA_AV_FEAT_ADV_CTRL)) 2537 continue; 2538 2539 BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume: %d", 2540 __func__, volume); 2541 2542 tAVRC_COMMAND avrc_cmd = {.volume = {.opcode = AVRC_OP_VENDOR, 2543 .pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME, 2544 .status = AVRC_STS_NO_ERROR, 2545 .volume = volume}}; 2546 2547 BT_HDR* p_msg = NULL; 2548 if (AVRC_BldCommand(&avrc_cmd, &p_msg) != AVRC_STS_NO_ERROR) { 2549 BTIF_TRACE_ERROR( 2550 "%s: failed to build absolute volume command. status: 0x%02x", 2551 __func__, status); 2552 status = BT_STATUS_FAIL; 2553 continue; 2554 } 2555 2556 rc_transaction_t* p_transaction = NULL; 2557 bt_status_t tran_status = get_transaction(&p_transaction); 2558 2559 if (tran_status != BT_STATUS_SUCCESS || !p_transaction) { 2560 osi_free_and_reset((void**)&p_msg); 2561 BTIF_TRACE_ERROR( 2562 "%s: failed to obtain transaction details. status: 0x%02x", __func__, 2563 tran_status); 2564 status = BT_STATUS_FAIL; 2565 continue; 2566 } 2567 2568 BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__, 2569 p_transaction->lbl); 2570 BTA_AvMetaCmd(btif_rc_cb.rc_multi_cb[idx].rc_handle, p_transaction->lbl, 2571 AVRC_CMD_CTRL, p_msg); 2572 status = BT_STATUS_SUCCESS; 2573 } 2574 return (bt_status_t)status; 2575 } 2576 2577 /*************************************************************************** 2578 * 2579 * Function register_volumechange 2580 * 2581 * Description Register for volume change notification from remote side. 2582 * 2583 * Returns void 2584 * 2585 **************************************************************************/ 2586 2587 static void register_volumechange(uint8_t lbl, btif_rc_device_cb_t* p_dev) { 2588 tAVRC_COMMAND avrc_cmd = {0}; 2589 BT_HDR* p_msg = NULL; 2590 tAVRC_STS BldResp = AVRC_STS_BAD_CMD; 2591 rc_transaction_t* p_transaction = NULL; 2592 2593 BTIF_TRACE_DEBUG("%s: label: %d", __func__, lbl); 2594 2595 avrc_cmd.cmd.opcode = 0x00; 2596 avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 2597 avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE; 2598 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR; 2599 avrc_cmd.reg_notif.param = 0; 2600 2601 BldResp = AVRC_BldCommand(&avrc_cmd, &p_msg); 2602 if (AVRC_STS_NO_ERROR == BldResp && p_msg) { 2603 p_transaction = get_transaction_by_lbl(lbl); 2604 if (p_transaction != NULL) { 2605 BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_NOTIF, 2606 p_msg); 2607 BTIF_TRACE_DEBUG("%s: BTA_AvMetaCmd called", __func__); 2608 } else { 2609 osi_free(p_msg); 2610 BTIF_TRACE_ERROR("%s: transaction not obtained with label: %d", __func__, 2611 lbl); 2612 } 2613 } else { 2614 BTIF_TRACE_ERROR("%s: failed to build command: %d", __func__, BldResp); 2615 } 2616 } 2617 2618 /*************************************************************************** 2619 * 2620 * Function handle_rc_metamsg_rsp 2621 * 2622 * Description Handle RC metamessage response 2623 * 2624 * Returns void 2625 * 2626 **************************************************************************/ 2627 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, 2628 btif_rc_device_cb_t* p_dev) { 2629 tAVRC_RESPONSE avrc_response = {0}; 2630 uint8_t scratch_buf[512] = {0}; 2631 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 2632 2633 BTIF_TRACE_DEBUG("%s: ", __func__); 2634 2635 if (AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode && 2636 (AVRC_RSP_CHANGED == pmeta_msg->code || 2637 AVRC_RSP_INTERIM == pmeta_msg->code || 2638 AVRC_RSP_ACCEPT == pmeta_msg->code || AVRC_RSP_REJ == pmeta_msg->code || 2639 AVRC_RSP_NOT_IMPL == pmeta_msg->code)) { 2640 status = AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, 2641 sizeof(scratch_buf)); 2642 BTIF_TRACE_DEBUG( 2643 "%s: code:%d, event ID: %d, PDU: %x, parsing status: %d, label: %d", 2644 __func__, pmeta_msg->code, avrc_response.reg_notif.event_id, 2645 avrc_response.reg_notif.pdu, status, pmeta_msg->label); 2646 2647 if (status != AVRC_STS_NO_ERROR) { 2648 if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu && 2649 AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id && 2650 p_dev->rc_vol_label == pmeta_msg->label) { 2651 p_dev->rc_vol_label = MAX_LABEL; 2652 release_transaction(p_dev->rc_vol_label); 2653 } else if (AVRC_PDU_SET_ABSOLUTE_VOLUME == avrc_response.rsp.pdu) { 2654 release_transaction(pmeta_msg->label); 2655 } 2656 return; 2657 } 2658 2659 if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu && 2660 AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id && 2661 p_dev->rc_vol_label != pmeta_msg->label) { 2662 // Just discard the message, if the device sends back with an incorrect 2663 // label 2664 BTIF_TRACE_DEBUG( 2665 "%s: Discarding register notification in rsp.code: %d and label: %d", 2666 __func__, pmeta_msg->code, pmeta_msg->label); 2667 return; 2668 } 2669 2670 if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu && 2671 AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id && 2672 (AVRC_RSP_REJ == pmeta_msg->code || 2673 AVRC_RSP_NOT_IMPL == pmeta_msg->code)) { 2674 BTIF_TRACE_DEBUG("%s remove AbsoluteVolume feature flag.", __func__); 2675 p_dev->rc_features &= ~BTA_AV_FEAT_ADV_CTRL; 2676 handle_rc_features(p_dev); 2677 return; 2678 } 2679 } else { 2680 BTIF_TRACE_DEBUG( 2681 "%s: Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not " 2682 "processing it.", 2683 __func__, pmeta_msg->code, pmeta_msg->len); 2684 return; 2685 } 2686 2687 if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu && 2688 AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id && 2689 AVRC_RSP_CHANGED == pmeta_msg->code) { 2690 /* re-register for volume change notification */ 2691 // Do not re-register for rejected case, as it might get into endless loop 2692 register_volumechange(p_dev->rc_vol_label, p_dev); 2693 } else if (AVRC_PDU_SET_ABSOLUTE_VOLUME == avrc_response.rsp.pdu) { 2694 /* free up the label here */ 2695 release_transaction(pmeta_msg->label); 2696 } 2697 2698 BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s", 2699 __func__, dump_rc_pdu(avrc_response.pdu)); 2700 btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, 2701 pmeta_msg->code, pmeta_msg->label, p_dev); 2702 } 2703 2704 /*************************************************************************** 2705 * 2706 * Function iterate_supported_event_list_for_interim_rsp 2707 * 2708 * Description iterator callback function to match the event and handle 2709 * timer cleanup 2710 * Returns true to continue iterating, false to stop 2711 * 2712 **************************************************************************/ 2713 bool iterate_supported_event_list_for_interim_rsp(void* data, void* cb_data) { 2714 uint8_t* p_event_id; 2715 btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data; 2716 2717 p_event_id = (uint8_t*)cb_data; 2718 2719 if (p_event->event_id == *p_event_id) { 2720 p_event->status = eINTERIM; 2721 return false; 2722 } 2723 return true; 2724 } 2725 2726 /*************************************************************************** 2727 * 2728 * Function iterate_supported_event_list_for_timeout 2729 * 2730 * Description Iterator callback function for timeout handling. 2731 * As part of the failure handling, it releases the 2732 * transaction label and removes the event from list, 2733 * this event will not be requested again during 2734 * the lifetime of the connection. 2735 * Returns false to stop iterating, true to continue 2736 * 2737 **************************************************************************/ 2738 bool iterate_supported_event_list_for_timeout(void* data, void* cb_data) { 2739 rc_context_t* cntxt = (rc_context_t*)cb_data; 2740 uint8_t label = cntxt->label & 0xFF; 2741 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(cntxt->rc_addr); 2742 btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data; 2743 2744 if (p_event->label == label) { 2745 list_remove(p_dev->rc_supported_event_list, p_event); 2746 return false; 2747 } 2748 return true; 2749 } 2750 2751 /*************************************************************************** 2752 * 2753 * Function rc_notification_interim_timout 2754 * 2755 * Description Interim response timeout handler. 2756 * Runs the iterator to check and clear the timed out event. 2757 * Proceeds to register for the unregistered events. 2758 * Returns None 2759 * 2760 **************************************************************************/ 2761 static void rc_notification_interim_timout(uint8_t label, 2762 btif_rc_device_cb_t* p_dev) { 2763 list_node_t* node; 2764 rc_context_t cntxt; 2765 memset(&cntxt, 0, sizeof(rc_context_t)); 2766 cntxt.label = label; 2767 cntxt.rc_addr = p_dev->rc_addr; 2768 2769 list_foreach(p_dev->rc_supported_event_list, 2770 iterate_supported_event_list_for_timeout, &cntxt); 2771 /* Timeout happened for interim response for the registered event, 2772 * check if there are any pending for registration 2773 */ 2774 node = list_begin(p_dev->rc_supported_event_list); 2775 while (node != NULL) { 2776 btif_rc_supported_event_t* p_event; 2777 2778 p_event = (btif_rc_supported_event_t*)list_node(node); 2779 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) { 2780 register_for_event_notification(p_event, p_dev); 2781 break; 2782 } 2783 node = list_next(node); 2784 } 2785 /* Todo. Need to initiate application settings query if this 2786 * is the last event registration. 2787 */ 2788 } 2789 2790 /*************************************************************************** 2791 * 2792 * Function btif_rc_status_cmd_timeout_handler 2793 * 2794 * Description RC status command timeout handler (Runs in BTIF context). 2795 * Returns None 2796 * 2797 **************************************************************************/ 2798 static void btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event, 2799 char* data) { 2800 btif_rc_timer_context_t* p_context; 2801 tAVRC_RESPONSE avrc_response = {0}; 2802 tBTA_AV_META_MSG meta_msg; 2803 btif_rc_device_cb_t* p_dev = NULL; 2804 2805 p_context = (btif_rc_timer_context_t*)data; 2806 memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG)); 2807 p_dev = btif_rc_get_device_by_bda(p_context->rc_addr); 2808 if (p_dev == NULL) { 2809 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 2810 return; 2811 } 2812 meta_msg.rc_handle = p_dev->rc_handle; 2813 2814 switch (p_context->rc_status_cmd.pdu_id) { 2815 case AVRC_PDU_REGISTER_NOTIFICATION: 2816 rc_notification_interim_timout(p_context->rc_status_cmd.label, p_dev); 2817 break; 2818 2819 case AVRC_PDU_GET_CAPABILITIES: 2820 avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT; 2821 handle_get_capability_response(&meta_msg, &avrc_response.get_caps); 2822 break; 2823 2824 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 2825 avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT; 2826 handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr); 2827 break; 2828 2829 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 2830 avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT; 2831 handle_app_val_response(&meta_msg, &avrc_response.list_app_values); 2832 break; 2833 2834 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 2835 avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT; 2836 handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val); 2837 break; 2838 2839 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 2840 avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT; 2841 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt); 2842 break; 2843 2844 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 2845 avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT; 2846 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt); 2847 break; 2848 2849 case AVRC_PDU_GET_ELEMENT_ATTR: 2850 avrc_response.get_attrs.status = BTIF_RC_STS_TIMEOUT; 2851 handle_get_elem_attr_response(&meta_msg, &avrc_response.get_attrs); 2852 break; 2853 2854 case AVRC_PDU_GET_PLAY_STATUS: 2855 avrc_response.get_play_status.status = BTIF_RC_STS_TIMEOUT; 2856 handle_get_playstatus_response(&meta_msg, &avrc_response.get_play_status); 2857 break; 2858 } 2859 release_transaction(p_context->rc_status_cmd.label); 2860 } 2861 2862 /*************************************************************************** 2863 * 2864 * Function btif_rc_status_cmd_timer_timeout 2865 * 2866 * Description RC status command timeout callback. 2867 * This is called from BTU context and switches to BTIF 2868 * context to handle the timeout events 2869 * Returns None 2870 * 2871 **************************************************************************/ 2872 static void btif_rc_status_cmd_timer_timeout(void* data) { 2873 btif_rc_timer_context_t* p_data = (btif_rc_timer_context_t*)data; 2874 2875 btif_transfer_context(btif_rc_status_cmd_timeout_handler, 0, (char*)p_data, 2876 sizeof(btif_rc_timer_context_t), NULL); 2877 } 2878 2879 /*************************************************************************** 2880 * 2881 * Function btif_rc_control_cmd_timeout_handler 2882 * 2883 * Description RC control command timeout handler (Runs in BTIF context). 2884 * Returns None 2885 * 2886 **************************************************************************/ 2887 static void btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event, 2888 char* data) { 2889 btif_rc_timer_context_t* p_context = (btif_rc_timer_context_t*)data; 2890 tAVRC_RESPONSE avrc_response = {0}; 2891 tBTA_AV_META_MSG meta_msg; 2892 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(p_context->rc_addr); 2893 if (p_dev == NULL) { 2894 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 2895 return; 2896 } 2897 2898 memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG)); 2899 meta_msg.rc_handle = p_dev->rc_handle; 2900 2901 switch (p_context->rc_control_cmd.pdu_id) { 2902 case AVRC_PDU_SET_PLAYER_APP_VALUE: 2903 avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT; 2904 handle_set_app_attr_val_response(&meta_msg, &avrc_response.set_app_val); 2905 break; 2906 } 2907 release_transaction(p_context->rc_control_cmd.label); 2908 } 2909 2910 /*************************************************************************** 2911 * 2912 * Function btif_rc_control_cmd_timer_timeout 2913 * 2914 * Description RC control command timeout callback. 2915 * This is called from BTU context and switches to BTIF 2916 * context to handle the timeout events 2917 * Returns None 2918 * 2919 **************************************************************************/ 2920 static void btif_rc_control_cmd_timer_timeout(void* data) { 2921 btif_rc_timer_context_t* p_data = (btif_rc_timer_context_t*)data; 2922 2923 btif_transfer_context(btif_rc_control_cmd_timeout_handler, 0, (char*)p_data, 2924 sizeof(btif_rc_timer_context_t), NULL); 2925 } 2926 2927 /*************************************************************************** 2928 * 2929 * Function btif_rc_play_status_timeout_handler 2930 * 2931 * Description RC play status timeout handler (Runs in BTIF context). 2932 * Returns None 2933 * 2934 **************************************************************************/ 2935 static void btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event, 2936 char* p_data) { 2937 btif_rc_handle_t* rc_handle = (btif_rc_handle_t*)p_data; 2938 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(rc_handle->handle); 2939 if (p_dev == NULL) { 2940 BTIF_TRACE_ERROR("%s timeout handler but no device found for handle %d", 2941 __func__, rc_handle->handle); 2942 return; 2943 } 2944 get_play_status_cmd(p_dev); 2945 rc_start_play_status_timer(p_dev); 2946 } 2947 2948 /*************************************************************************** 2949 * 2950 * Function btif_rc_play_status_timer_timeout 2951 * 2952 * Description RC play status timeout callback. 2953 * This is called from BTU context and switches to BTIF 2954 * context to handle the timeout events 2955 * Returns None 2956 * 2957 **************************************************************************/ 2958 static void btif_rc_play_status_timer_timeout(void* data) { 2959 btif_rc_handle_t rc_handle; 2960 rc_handle.handle = PTR_TO_UINT(data); 2961 BTIF_TRACE_DEBUG("%s called with handle: %d", __func__, rc_handle); 2962 btif_transfer_context(btif_rc_play_status_timeout_handler, 0, 2963 (char*)(&rc_handle), sizeof(btif_rc_handle_t), NULL); 2964 } 2965 2966 /*************************************************************************** 2967 * 2968 * Function rc_start_play_status_timer 2969 * 2970 * Description Helper function to start the timer to fetch play status. 2971 * Returns None 2972 * 2973 **************************************************************************/ 2974 static void rc_start_play_status_timer(btif_rc_device_cb_t* p_dev) { 2975 /* Start the Play status timer only if it is not started */ 2976 if (!alarm_is_scheduled(p_dev->rc_play_status_timer)) { 2977 if (p_dev->rc_play_status_timer == NULL) { 2978 p_dev->rc_play_status_timer = alarm_new("p_dev->rc_play_status_timer"); 2979 } 2980 alarm_set_on_mloop( 2981 p_dev->rc_play_status_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS, 2982 btif_rc_play_status_timer_timeout, UINT_TO_PTR(p_dev->rc_handle)); 2983 } 2984 } 2985 2986 /*************************************************************************** 2987 * 2988 * Function rc_stop_play_status_timer 2989 * 2990 * Description Helper function to stop the play status timer. 2991 * Returns None 2992 * 2993 **************************************************************************/ 2994 void rc_stop_play_status_timer(btif_rc_device_cb_t* p_dev) { 2995 alarm_cancel(p_dev->rc_play_status_timer); 2996 } 2997 2998 /*************************************************************************** 2999 * 3000 * Function register_for_event_notification 3001 * 3002 * Description Helper function registering notification events 3003 * sets an interim response timeout to handle if the remote 3004 * does not respond. 3005 * Returns None 3006 * 3007 **************************************************************************/ 3008 static void register_for_event_notification(btif_rc_supported_event_t* p_event, 3009 btif_rc_device_cb_t* p_dev) { 3010 rc_transaction_t* p_transaction = NULL; 3011 bt_status_t status = get_transaction(&p_transaction); 3012 if (status != BT_STATUS_SUCCESS) { 3013 BTIF_TRACE_ERROR("%s: no more transaction labels: %d", __func__, status); 3014 return; 3015 } 3016 3017 status = register_notification_cmd(p_transaction->lbl, p_event->event_id, 0, 3018 p_dev); 3019 if (status != BT_STATUS_SUCCESS) { 3020 BTIF_TRACE_ERROR("%s: Error in Notification registration: %d", __func__, 3021 status); 3022 release_transaction(p_transaction->lbl); 3023 return; 3024 } 3025 3026 btif_rc_timer_context_t* p_context = &p_transaction->txn_timer_context; 3027 p_event->label = p_transaction->lbl; 3028 p_event->status = eREGISTERED; 3029 p_context->rc_status_cmd.label = p_transaction->lbl; 3030 p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION; 3031 p_context->rc_addr = p_dev->rc_addr; 3032 3033 alarm_free(p_transaction->txn_timer); 3034 p_transaction->txn_timer = alarm_new("btif_rc.status_command_txn_timer"); 3035 alarm_set_on_mloop(p_transaction->txn_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS, 3036 btif_rc_status_cmd_timer_timeout, p_context); 3037 } 3038 3039 static void start_status_command_timer(uint8_t pdu_id, rc_transaction_t* p_txn, 3040 btif_rc_device_cb_t* p_dev) { 3041 btif_rc_timer_context_t* p_context = &p_txn->txn_timer_context; 3042 p_context->rc_status_cmd.label = p_txn->lbl; 3043 p_context->rc_status_cmd.pdu_id = pdu_id; 3044 p_context->rc_addr = p_dev->rc_addr; 3045 3046 alarm_free(p_txn->txn_timer); 3047 p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer"); 3048 alarm_set_on_mloop(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS, 3049 btif_rc_status_cmd_timer_timeout, p_context); 3050 } 3051 3052 static void start_control_command_timer(uint8_t pdu_id, rc_transaction_t* p_txn, 3053 btif_rc_device_cb_t* p_dev) { 3054 btif_rc_timer_context_t* p_context = &p_txn->txn_timer_context; 3055 p_context->rc_control_cmd.label = p_txn->lbl; 3056 p_context->rc_control_cmd.pdu_id = pdu_id; 3057 p_context->rc_addr = p_dev->rc_addr; 3058 3059 alarm_free(p_txn->txn_timer); 3060 p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer"); 3061 alarm_set_on_mloop(p_txn->txn_timer, BTIF_TIMEOUT_RC_CONTROL_CMD_MS, 3062 btif_rc_control_cmd_timer_timeout, p_context); 3063 } 3064 3065 bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd, 3066 tBTA_AV_CODE cmd_code, 3067 btif_rc_device_cb_t* p_dev) { 3068 rc_transaction_t* p_transaction = NULL; 3069 bt_status_t tran_status = get_transaction(&p_transaction); 3070 if (BT_STATUS_SUCCESS != tran_status) return BT_STATUS_FAIL; 3071 3072 BT_HDR* p_msg = NULL; 3073 tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg); 3074 if (status == AVRC_STS_NO_ERROR && p_msg != NULL) { 3075 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; 3076 BTIF_TRACE_DEBUG("%s: %s msgreq being sent out with label: %d", __func__, 3077 dump_rc_pdu(avrc_cmd->pdu), p_transaction->lbl); 3078 BTA_AvVendorCmd(p_dev->rc_handle, p_transaction->lbl, cmd_code, data_start, 3079 p_msg->len); 3080 status = BT_STATUS_SUCCESS; 3081 if (cmd_code == AVRC_CMD_STATUS) { 3082 start_status_command_timer(avrc_cmd->pdu, p_transaction, p_dev); 3083 } else if (cmd_code == AVRC_CMD_CTRL) { 3084 start_control_command_timer(avrc_cmd->pdu, p_transaction, p_dev); 3085 } 3086 } else { 3087 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__, 3088 status); 3089 } 3090 osi_free(p_msg); 3091 return (bt_status_t)status; 3092 } 3093 3094 /*************************************************************************** 3095 * 3096 * Function handle_get_capability_response 3097 * 3098 * Description Handles the get_cap_response to populate company id info 3099 * and query the supported events. 3100 * Initiates Notification registration for events supported 3101 * Returns None 3102 * 3103 **************************************************************************/ 3104 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, 3105 tAVRC_GET_CAPS_RSP* p_rsp) { 3106 int xx = 0; 3107 btif_rc_device_cb_t* p_dev = 3108 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3109 3110 /* Todo: Do we need to retry on command timeout */ 3111 if (p_rsp->status != AVRC_STS_NO_ERROR) { 3112 BTIF_TRACE_ERROR("%s: Error capability response: 0x%02X", __func__, 3113 p_rsp->status); 3114 return; 3115 } 3116 3117 if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED) { 3118 btif_rc_supported_event_t* p_event; 3119 3120 /* Todo: Check if list can be active when we hit here */ 3121 p_dev->rc_supported_event_list = list_new(osi_free); 3122 for (xx = 0; xx < p_rsp->count; xx++) { 3123 /* Skip registering for Play position change notification */ 3124 if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE) || 3125 (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE) || 3126 (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE) || 3127 (p_rsp->param.event_id[xx] == AVRC_EVT_ADDR_PLAYER_CHANGE) || 3128 (p_rsp->param.event_id[xx] == AVRC_EVT_UIDS_CHANGE)) { 3129 p_event = (btif_rc_supported_event_t*)osi_malloc( 3130 sizeof(btif_rc_supported_event_t)); 3131 p_event->event_id = p_rsp->param.event_id[xx]; 3132 p_event->status = eNOT_REGISTERED; 3133 list_append(p_dev->rc_supported_event_list, p_event); 3134 } 3135 } 3136 p_event = 3137 (btif_rc_supported_event_t*)list_front(p_dev->rc_supported_event_list); 3138 if (p_event != NULL) { 3139 register_for_event_notification(p_event, p_dev); 3140 } 3141 } else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) { 3142 getcapabilities_cmd(AVRC_CAP_EVENTS_SUPPORTED, p_dev); 3143 BTIF_TRACE_EVENT("%s: AVRC_CAP_COMPANY_ID: ", __func__); 3144 for (xx = 0; xx < p_rsp->count; xx++) { 3145 BTIF_TRACE_EVENT("%s: company_id: %d", __func__, 3146 p_rsp->param.company_id[xx]); 3147 } 3148 } 3149 } 3150 3151 bool rc_is_track_id_valid(tAVRC_UID uid) { 3152 tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 3153 3154 if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0) { 3155 return false; 3156 } else { 3157 return true; 3158 } 3159 } 3160 3161 /*************************************************************************** 3162 * 3163 * Function handle_notification_response 3164 * 3165 * Description Main handler for notification responses to registered events 3166 * 1. Register for unregistered event(in interim response path) 3167 * 2. After registering for all supported events, start 3168 * retrieving application settings and values 3169 * 3. Reregister for events on getting changed response 3170 * 4. Run play status timer for getting position when the 3171 * status changes to playing 3172 * 5. Get the Media details when the track change happens 3173 * or track change interim response is received with 3174 * valid track id 3175 * 6. HAL callback for play status change and application 3176 * setting change 3177 * Returns None 3178 * 3179 **************************************************************************/ 3180 static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, 3181 tAVRC_REG_NOTIF_RSP* p_rsp) { 3182 btif_rc_device_cb_t* p_dev = 3183 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3184 uint32_t attr_list[] = { 3185 AVRC_MEDIA_ATTR_ID_TITLE, AVRC_MEDIA_ATTR_ID_ARTIST, 3186 AVRC_MEDIA_ATTR_ID_ALBUM, AVRC_MEDIA_ATTR_ID_TRACK_NUM, 3187 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, AVRC_MEDIA_ATTR_ID_GENRE, 3188 AVRC_MEDIA_ATTR_ID_PLAYING_TIME}; 3189 3190 if (p_dev == NULL) { 3191 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3192 return; 3193 } 3194 3195 3196 if (pmeta_msg->code == AVRC_RSP_INTERIM) { 3197 btif_rc_supported_event_t* p_event; 3198 list_node_t* node; 3199 3200 BTIF_TRACE_DEBUG("%s: Interim response: 0x%2X ", __func__, p_rsp->event_id); 3201 switch (p_rsp->event_id) { 3202 case AVRC_EVT_PLAY_STATUS_CHANGE: 3203 /* Start timer to get play status periodically 3204 * if the play state is playing. 3205 */ 3206 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING || 3207 p_rsp->param.play_status == AVRC_PLAYSTATE_REV_SEEK || 3208 p_rsp->param.play_status == AVRC_PLAYSTATE_FWD_SEEK) { 3209 rc_start_play_status_timer(p_dev); 3210 } 3211 do_in_jni_thread( 3212 FROM_HERE, 3213 base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb, 3214 p_dev->rc_addr, 3215 (btrc_play_status_t)p_rsp->param.play_status)); 3216 break; 3217 3218 case AVRC_EVT_TRACK_CHANGE: 3219 if (rc_is_track_id_valid(p_rsp->param.track) != true) { 3220 break; 3221 } else { 3222 uint8_t* p_data = p_rsp->param.track; 3223 /* Update the UID for current track 3224 * Attributes will be fetched after the AVRCP procedure 3225 */ 3226 BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data); 3227 } 3228 break; 3229 3230 case AVRC_EVT_APP_SETTING_CHANGE: 3231 break; 3232 3233 case AVRC_EVT_NOW_PLAYING_CHANGE: 3234 break; 3235 3236 case AVRC_EVT_AVAL_PLAYERS_CHANGE: 3237 break; 3238 3239 case AVRC_EVT_ADDR_PLAYER_CHANGE: 3240 do_in_jni_thread( 3241 FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->set_addressed_player_cb, 3242 p_dev->rc_addr, BTRC_STS_ADDR_PLAY_CHGD)); 3243 break; 3244 3245 case AVRC_EVT_UIDS_CHANGE: 3246 break; 3247 3248 case AVRC_EVT_TRACK_REACHED_END: 3249 case AVRC_EVT_TRACK_REACHED_START: 3250 case AVRC_EVT_PLAY_POS_CHANGED: 3251 case AVRC_EVT_BATTERY_STATUS_CHANGE: 3252 case AVRC_EVT_SYSTEM_STATUS_CHANGE: 3253 default: 3254 BTIF_TRACE_ERROR("%s: Unhandled interim response: 0x%2X", __func__, 3255 p_rsp->event_id); 3256 return; 3257 } 3258 3259 list_foreach(p_dev->rc_supported_event_list, 3260 iterate_supported_event_list_for_interim_rsp, 3261 &p_rsp->event_id); 3262 3263 node = list_begin(p_dev->rc_supported_event_list); 3264 3265 while (node != NULL) { 3266 p_event = (btif_rc_supported_event_t*)list_node(node); 3267 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) { 3268 register_for_event_notification(p_event, p_dev); 3269 break; 3270 } 3271 node = list_next(node); 3272 p_event = NULL; 3273 } 3274 /* Registered for all events, we can request application settings */ 3275 if (p_event == NULL && !p_dev->rc_app_settings.query_started) { 3276 /* we need to do this only if remote TG supports 3277 * player application settings 3278 */ 3279 p_dev->rc_app_settings.query_started = true; 3280 if (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING) { 3281 list_player_app_setting_attrib_cmd(p_dev); 3282 } else { 3283 BTIF_TRACE_DEBUG("%s: App setting not supported, complete procedure", 3284 __func__); 3285 rc_ctrl_procedure_complete(p_dev); 3286 } 3287 } 3288 } else if (pmeta_msg->code == AVRC_RSP_CHANGED) { 3289 btif_rc_supported_event_t* p_event; 3290 list_node_t* node; 3291 3292 BTIF_TRACE_DEBUG("%s: Notification completed: 0x%2X ", __func__, 3293 p_rsp->event_id); 3294 3295 node = list_begin(p_dev->rc_supported_event_list); 3296 3297 while (node != NULL) { 3298 p_event = (btif_rc_supported_event_t*)list_node(node); 3299 if (p_event != NULL && p_event->event_id == p_rsp->event_id) { 3300 p_event->status = eNOT_REGISTERED; 3301 register_for_event_notification(p_event, p_dev); 3302 break; 3303 } 3304 node = list_next(node); 3305 } 3306 3307 switch (p_rsp->event_id) { 3308 case AVRC_EVT_PLAY_STATUS_CHANGE: 3309 /* Start timer to get play status periodically 3310 * if the play state is playing. 3311 */ 3312 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING) { 3313 rc_start_play_status_timer(p_dev); 3314 get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, 3315 p_dev); 3316 } else { 3317 rc_stop_play_status_timer(p_dev); 3318 } 3319 do_in_jni_thread( 3320 FROM_HERE, 3321 base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb, 3322 p_dev->rc_addr, 3323 (btrc_play_status_t)p_rsp->param.play_status)); 3324 3325 break; 3326 3327 case AVRC_EVT_TRACK_CHANGE: 3328 if (rc_is_track_id_valid(p_rsp->param.track) != true) { 3329 break; 3330 } 3331 get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, p_dev); 3332 break; 3333 3334 case AVRC_EVT_APP_SETTING_CHANGE: { 3335 btrc_player_settings_t app_settings; 3336 uint16_t xx; 3337 3338 app_settings.num_attr = p_rsp->param.player_setting.num_attr; 3339 for (xx = 0; xx < app_settings.num_attr; xx++) { 3340 app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx]; 3341 app_settings.attr_values[xx] = 3342 p_rsp->param.player_setting.attr_value[xx]; 3343 } 3344 do_in_jni_thread( 3345 FROM_HERE, 3346 base::Bind( 3347 bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb, 3348 p_dev->rc_addr, app_settings)); 3349 } break; 3350 3351 case AVRC_EVT_NOW_PLAYING_CHANGE: 3352 break; 3353 3354 case AVRC_EVT_AVAL_PLAYERS_CHANGE: 3355 break; 3356 3357 case AVRC_EVT_ADDR_PLAYER_CHANGE: 3358 break; 3359 3360 case AVRC_EVT_UIDS_CHANGE: 3361 break; 3362 3363 case AVRC_EVT_TRACK_REACHED_END: 3364 case AVRC_EVT_TRACK_REACHED_START: 3365 case AVRC_EVT_PLAY_POS_CHANGED: 3366 case AVRC_EVT_BATTERY_STATUS_CHANGE: 3367 case AVRC_EVT_SYSTEM_STATUS_CHANGE: 3368 default: 3369 BTIF_TRACE_ERROR("%s: Unhandled completion response: 0x%2X", __func__, 3370 p_rsp->event_id); 3371 return; 3372 } 3373 } 3374 } 3375 3376 /*************************************************************************** 3377 * 3378 * Function handle_app_attr_response 3379 * 3380 * Description handles the the application attributes response and 3381 * initiates procedure to fetch the attribute values 3382 * Returns None 3383 * 3384 **************************************************************************/ 3385 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, 3386 tAVRC_LIST_APP_ATTR_RSP* p_rsp) { 3387 uint8_t xx; 3388 btif_rc_device_cb_t* p_dev = 3389 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3390 3391 if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) { 3392 BTIF_TRACE_ERROR("%s: Error getting Player application settings: 0x%2X", 3393 __func__, p_rsp->status); 3394 rc_ctrl_procedure_complete(p_dev); 3395 return; 3396 } 3397 3398 for (xx = 0; xx < p_rsp->num_attr; xx++) { 3399 uint8_t st_index; 3400 3401 if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT) { 3402 st_index = p_dev->rc_app_settings.num_ext_attrs; 3403 p_dev->rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx]; 3404 p_dev->rc_app_settings.num_ext_attrs++; 3405 } else { 3406 st_index = p_dev->rc_app_settings.num_attrs; 3407 p_dev->rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx]; 3408 p_dev->rc_app_settings.num_attrs++; 3409 } 3410 } 3411 p_dev->rc_app_settings.attr_index = 0; 3412 p_dev->rc_app_settings.ext_attr_index = 0; 3413 p_dev->rc_app_settings.ext_val_index = 0; 3414 if (p_rsp->num_attr) { 3415 list_player_app_setting_value_cmd(p_dev->rc_app_settings.attrs[0].attr_id, 3416 p_dev); 3417 } else { 3418 BTIF_TRACE_ERROR("%s: No Player application settings found", __func__); 3419 } 3420 } 3421 3422 /*************************************************************************** 3423 * 3424 * Function handle_app_val_response 3425 * 3426 * Description handles the the attributes value response and if extended 3427 * menu is available, it initiates query for the attribute 3428 * text. If not, it initiates procedure to get the current 3429 * attribute values and calls the HAL callback for provding 3430 * application settings information. 3431 * Returns None 3432 * 3433 **************************************************************************/ 3434 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, 3435 tAVRC_LIST_APP_VALUES_RSP* p_rsp) { 3436 uint8_t xx, attr_index; 3437 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE]; 3438 btif_rc_player_app_settings_t* p_app_settings; 3439 btif_rc_device_cb_t* p_dev = 3440 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3441 3442 /* Todo: Do we need to retry on command timeout */ 3443 if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) { 3444 BTIF_TRACE_ERROR("%s: Error fetching attribute values: 0x%02X", __func__, 3445 p_rsp->status); 3446 return; 3447 } 3448 3449 p_app_settings = &p_dev->rc_app_settings; 3450 3451 if (p_app_settings->attr_index < p_app_settings->num_attrs) { 3452 attr_index = p_app_settings->attr_index; 3453 p_app_settings->attrs[attr_index].num_val = p_rsp->num_val; 3454 for (xx = 0; xx < p_rsp->num_val; xx++) { 3455 p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx]; 3456 } 3457 attr_index++; 3458 p_app_settings->attr_index++; 3459 if (attr_index < p_app_settings->num_attrs) { 3460 list_player_app_setting_value_cmd( 3461 p_app_settings->attrs[p_app_settings->attr_index].attr_id, p_dev); 3462 } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) { 3463 attr_index = 0; 3464 p_app_settings->ext_attr_index = 0; 3465 list_player_app_setting_value_cmd( 3466 p_app_settings->ext_attrs[attr_index].attr_id, p_dev); 3467 } else { 3468 for (xx = 0; xx < p_app_settings->num_attrs; xx++) { 3469 attrs[xx] = p_app_settings->attrs[xx].attr_id; 3470 } 3471 get_player_app_setting_cmd(p_app_settings->num_attrs, attrs, p_dev); 3472 do_in_jni_thread( 3473 FROM_HERE, 3474 base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, 3475 p_dev->rc_addr, p_app_settings->num_attrs, 3476 p_app_settings->attrs, 0, nullptr)); 3477 } 3478 } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) { 3479 attr_index = p_app_settings->ext_attr_index; 3480 p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val; 3481 for (xx = 0; xx < p_rsp->num_val; xx++) { 3482 p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = 3483 p_rsp->vals[xx]; 3484 } 3485 attr_index++; 3486 p_app_settings->ext_attr_index++; 3487 if (attr_index < p_app_settings->num_ext_attrs) { 3488 list_player_app_setting_value_cmd( 3489 p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id, 3490 p_dev); 3491 } else { 3492 uint8_t attr[AVRC_MAX_APP_ATTR_SIZE]; 3493 3494 for (uint8_t xx = 0; xx < p_app_settings->num_ext_attrs; xx++) { 3495 attr[xx] = p_app_settings->ext_attrs[xx].attr_id; 3496 } 3497 get_player_app_setting_attr_text_cmd(attr, p_app_settings->num_ext_attrs, 3498 p_dev); 3499 } 3500 } 3501 } 3502 3503 /*************************************************************************** 3504 * 3505 * Function handle_app_cur_val_response 3506 * 3507 * Description handles the the get attributes value response. 3508 * 3509 * Returns None 3510 * 3511 **************************************************************************/ 3512 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg, 3513 tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp) { 3514 btrc_player_settings_t app_settings; 3515 uint16_t xx; 3516 btif_rc_device_cb_t* p_dev = NULL; 3517 3518 /* Todo: Do we need to retry on command timeout */ 3519 if (p_rsp->status != AVRC_STS_NO_ERROR) { 3520 BTIF_TRACE_ERROR("%s: Error fetching current settings: 0x%02X", __func__, 3521 p_rsp->status); 3522 return; 3523 } 3524 p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3525 if (p_dev == NULL) { 3526 BTIF_TRACE_ERROR("%s: Error in getting Device Address", __func__); 3527 osi_free_and_reset((void**)&p_rsp->p_vals); 3528 return; 3529 } 3530 3531 3532 app_settings.num_attr = p_rsp->num_val; 3533 3534 if (app_settings.num_attr > BTRC_MAX_APP_SETTINGS) { 3535 android_errorWriteLog(0x534e4554, "73824150"); 3536 app_settings.num_attr = BTRC_MAX_APP_SETTINGS; 3537 } 3538 3539 for (xx = 0; xx < app_settings.num_attr; xx++) { 3540 app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id; 3541 app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val; 3542 } 3543 3544 do_in_jni_thread( 3545 FROM_HERE, 3546 base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb, 3547 p_dev->rc_addr, app_settings)); 3548 /* Application settings are fetched only once for initial values 3549 * initiate anything that follows after RC procedure. 3550 * Defer it if browsing is supported till players query 3551 */ 3552 rc_ctrl_procedure_complete(p_dev); 3553 osi_free_and_reset((void**)&p_rsp->p_vals); 3554 } 3555 3556 /*************************************************************************** 3557 * 3558 * Function handle_app_attr_txt_response 3559 * 3560 * Description handles the the get attributes text response, if fails 3561 * calls HAL callback with just normal settings and initiates 3562 * query for current settings else initiates query for value 3563 * text 3564 * Returns None 3565 * 3566 **************************************************************************/ 3567 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg, 3568 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) { 3569 uint8_t xx; 3570 uint8_t vals[AVRC_MAX_APP_ATTR_SIZE]; 3571 btif_rc_player_app_settings_t* p_app_settings; 3572 btif_rc_device_cb_t* p_dev = 3573 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3574 3575 if (p_dev == NULL) { 3576 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3577 return; 3578 } 3579 3580 p_app_settings = &p_dev->rc_app_settings; 3581 3582 /* Todo: Do we need to retry on command timeout */ 3583 if (p_rsp->status != AVRC_STS_NO_ERROR) { 3584 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE]; 3585 3586 BTIF_TRACE_ERROR("%s: Error fetching attribute text: 0x%02X", __func__, 3587 p_rsp->status); 3588 /* Not able to fetch Text for extended Menu, skip the process 3589 * and cleanup used memory. Proceed to get the current settings 3590 * for standard attributes. 3591 */ 3592 p_app_settings->num_ext_attrs = 0; 3593 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) { 3594 osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str); 3595 } 3596 p_app_settings->ext_attr_index = 0; 3597 3598 if (p_dev) { 3599 for (xx = 0; xx < p_app_settings->num_attrs; xx++) { 3600 attrs[xx] = p_app_settings->attrs[xx].attr_id; 3601 } 3602 3603 do_in_jni_thread( 3604 FROM_HERE, 3605 base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, 3606 p_dev->rc_addr, p_app_settings->num_attrs, 3607 p_app_settings->attrs, 0, nullptr)); 3608 get_player_app_setting_cmd(xx, attrs, p_dev); 3609 } 3610 return; 3611 } 3612 3613 for (xx = 0; xx < p_rsp->num_attr; xx++) { 3614 uint8_t x; 3615 for (x = 0; x < p_app_settings->num_ext_attrs; x++) { 3616 if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) { 3617 p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id; 3618 p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len; 3619 p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str; 3620 break; 3621 } 3622 } 3623 } 3624 3625 for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++) { 3626 vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val; 3627 } 3628 get_player_app_setting_value_text_cmd(vals, xx, p_dev); 3629 } 3630 3631 /*************************************************************************** 3632 * 3633 * Function handle_app_attr_val_txt_response 3634 * 3635 * Description handles the the get attributes value text response, if fails 3636 * calls HAL callback with just normal settings and initiates 3637 * query for current settings 3638 * Returns None 3639 * 3640 **************************************************************************/ 3641 static void handle_app_attr_val_txt_response( 3642 tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) { 3643 uint8_t xx, attr_index; 3644 uint8_t vals[AVRC_MAX_APP_ATTR_SIZE]; 3645 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE]; 3646 btif_rc_player_app_settings_t* p_app_settings; 3647 btif_rc_device_cb_t* p_dev = 3648 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3649 3650 if (p_dev == NULL) { 3651 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3652 return; 3653 } 3654 3655 p_app_settings = &p_dev->rc_app_settings; 3656 3657 /* Todo: Do we need to retry on command timeout */ 3658 if (p_rsp->status != AVRC_STS_NO_ERROR) { 3659 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE]; 3660 3661 BTIF_TRACE_ERROR("%s: Error fetching attribute value text: 0x%02X", 3662 __func__, p_rsp->status); 3663 3664 /* Not able to fetch Text for extended Menu, skip the process 3665 * and cleanup used memory. Proceed to get the current settings 3666 * for standard attributes. 3667 */ 3668 p_app_settings->num_ext_attrs = 0; 3669 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) { 3670 int x; 3671 btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx]; 3672 3673 for (x = 0; x < p_ext_attr->num_val; x++) 3674 osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str); 3675 p_ext_attr->num_val = 0; 3676 osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str); 3677 } 3678 p_app_settings->ext_attr_index = 0; 3679 3680 for (xx = 0; xx < p_app_settings->num_attrs; xx++) { 3681 attrs[xx] = p_app_settings->attrs[xx].attr_id; 3682 } 3683 do_in_jni_thread( 3684 FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, 3685 p_dev->rc_addr, p_app_settings->num_attrs, 3686 p_app_settings->attrs, 0, nullptr)); 3687 3688 get_player_app_setting_cmd(xx, attrs, p_dev); 3689 return; 3690 } 3691 3692 for (xx = 0; xx < p_rsp->num_attr; xx++) { 3693 uint8_t x; 3694 btrc_player_app_ext_attr_t* p_ext_attr; 3695 p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index]; 3696 for (x = 0; x < p_rsp->num_attr; x++) { 3697 if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) { 3698 p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id; 3699 p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len; 3700 p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str; 3701 break; 3702 } 3703 } 3704 } 3705 p_app_settings->ext_val_index++; 3706 3707 if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs) { 3708 attr_index = p_app_settings->ext_val_index; 3709 for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++) { 3710 vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val; 3711 } 3712 get_player_app_setting_value_text_cmd(vals, xx, p_dev); 3713 } else { 3714 uint8_t x; 3715 3716 for (xx = 0; xx < p_app_settings->num_attrs; xx++) { 3717 attrs[xx] = p_app_settings->attrs[xx].attr_id; 3718 } 3719 for (x = 0; x < p_app_settings->num_ext_attrs; x++) { 3720 attrs[xx + x] = p_app_settings->ext_attrs[x].attr_id; 3721 } 3722 do_in_jni_thread( 3723 FROM_HERE, 3724 base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb, 3725 p_dev->rc_addr, p_app_settings->num_attrs, 3726 p_app_settings->attrs, p_app_settings->num_ext_attrs, 3727 p_app_settings->ext_attrs)); 3728 get_player_app_setting_cmd(xx + x, attrs, p_dev); 3729 3730 /* Free the application settings information after sending to 3731 * application. 3732 */ 3733 do_in_jni_thread(FROM_HERE, base::Bind(cleanup_app_attr_val_txt_response, 3734 p_app_settings)); 3735 p_app_settings->num_attrs = 0; 3736 } 3737 } 3738 3739 /*************************************************************************** 3740 * 3741 * Function cleanup_app_attr_val_txt_response 3742 * 3743 * Description Frees the memory that was allocated for reporting player 3744 * application settings. 3745 * Returns None 3746 **************************************************************************/ 3747 static void cleanup_app_attr_val_txt_response( 3748 btif_rc_player_app_settings_t* p_app_settings) { 3749 for (uint8_t xx = 0; xx < p_app_settings->ext_attr_index; xx++) { 3750 int x; 3751 btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx]; 3752 for (x = 0; x < p_ext_attr->num_val; x++) { 3753 osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str); 3754 } 3755 p_ext_attr->num_val = 0; 3756 osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str); 3757 } 3758 } 3759 3760 /*************************************************************************** 3761 * 3762 * Function handle_set_app_attr_val_response 3763 * 3764 * Description handles the the set attributes value response, if fails 3765 * calls HAL callback to indicate the failure 3766 * Returns None 3767 * 3768 **************************************************************************/ 3769 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, 3770 tAVRC_RSP* p_rsp) { 3771 uint8_t accepted = 0; 3772 btif_rc_device_cb_t* p_dev = 3773 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3774 3775 if (p_dev == NULL) { 3776 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3777 return; 3778 } 3779 3780 3781 /* For timeout pmeta_msg will be NULL, else we need to 3782 * check if this is accepted by TG 3783 */ 3784 if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT)) { 3785 accepted = 1; 3786 } 3787 do_in_jni_thread(FROM_HERE, 3788 base::Bind(bt_rc_ctrl_callbacks->setplayerappsetting_rsp_cb, 3789 p_dev->rc_addr, accepted)); 3790 } 3791 3792 /*************************************************************************** 3793 * 3794 * Function handle_get_elem_attr_response 3795 * 3796 * Description handles the the element attributes response, calls 3797 * HAL callback to update track change information. 3798 * Returns None 3799 * 3800 **************************************************************************/ 3801 static void handle_get_elem_attr_response(tBTA_AV_META_MSG* pmeta_msg, 3802 tAVRC_GET_ATTRS_RSP* p_rsp) { 3803 btif_rc_device_cb_t* p_dev = 3804 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3805 3806 if (p_rsp->status == AVRC_STS_NO_ERROR) { 3807 size_t buf_size = p_rsp->num_attrs * sizeof(btrc_element_attr_val_t); 3808 btrc_element_attr_val_t* p_attr = 3809 (btrc_element_attr_val_t*)osi_calloc(buf_size); 3810 3811 if (p_dev == NULL) { 3812 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3813 return; 3814 } 3815 3816 3817 for (int i = 0; i < p_rsp->num_attrs; i++) { 3818 p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id; 3819 /* Todo. Legth limit check to include null */ 3820 if (p_rsp->p_attrs[i].name.str_len && p_rsp->p_attrs[i].name.p_str) { 3821 memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str, 3822 p_rsp->p_attrs[i].name.str_len); 3823 osi_free_and_reset((void**)&p_rsp->p_attrs[i].name.p_str); 3824 } 3825 } 3826 do_in_jni_thread(FROM_HERE, 3827 base::Bind(bt_rc_ctrl_callbacks->track_changed_cb, 3828 p_dev->rc_addr, p_rsp->num_attrs, p_attr)); 3829 do_in_jni_thread(FROM_HERE, base::Bind(osi_free, p_attr)); 3830 } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) { 3831 /* Retry for timeout case, this covers error handling 3832 * for continuation failure also. 3833 */ 3834 uint32_t attr_list[] = { 3835 AVRC_MEDIA_ATTR_ID_TITLE, AVRC_MEDIA_ATTR_ID_ARTIST, 3836 AVRC_MEDIA_ATTR_ID_ALBUM, AVRC_MEDIA_ATTR_ID_TRACK_NUM, 3837 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, AVRC_MEDIA_ATTR_ID_GENRE, 3838 AVRC_MEDIA_ATTR_ID_PLAYING_TIME}; 3839 get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, p_dev); 3840 } else { 3841 BTIF_TRACE_ERROR("%s: Error in get element attr procedure: %d", __func__, 3842 p_rsp->status); 3843 } 3844 } 3845 3846 /*************************************************************************** 3847 * 3848 * Function handle_get_playstatus_response 3849 * 3850 * Description handles the the play status response, calls 3851 * HAL callback to update play position. 3852 * Returns None 3853 * 3854 **************************************************************************/ 3855 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, 3856 tAVRC_GET_PLAY_STATUS_RSP* p_rsp) { 3857 3858 btif_rc_device_cb_t* p_dev = 3859 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3860 3861 if (p_dev == NULL) { 3862 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3863 return; 3864 } 3865 3866 3867 if (p_rsp->status == AVRC_STS_NO_ERROR) { 3868 do_in_jni_thread( 3869 FROM_HERE, 3870 base::Bind(bt_rc_ctrl_callbacks->play_position_changed_cb, 3871 p_dev->rc_addr, p_rsp->song_len, p_rsp->song_pos)); 3872 } else { 3873 BTIF_TRACE_ERROR("%s: Error in get play status procedure: %d", __func__, 3874 p_rsp->status); 3875 } 3876 } 3877 3878 /*************************************************************************** 3879 * 3880 * Function handle_set_addressed_player_response 3881 * 3882 * Description handles the the set addressed player response, calls 3883 * HAL callback 3884 * Returns None 3885 * 3886 **************************************************************************/ 3887 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, 3888 tAVRC_RSP* p_rsp) { 3889 3890 btif_rc_device_cb_t* p_dev = 3891 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3892 3893 if (p_dev == NULL) { 3894 BTIF_TRACE_ERROR("%s: p_dev NULL", __func__); 3895 return; 3896 } 3897 3898 3899 if (p_rsp->status == AVRC_STS_NO_ERROR) { 3900 do_in_jni_thread(FROM_HERE, 3901 base::Bind(bt_rc_ctrl_callbacks->set_addressed_player_cb, 3902 p_dev->rc_addr, p_rsp->status)); 3903 } else { 3904 BTIF_TRACE_ERROR("%s: Error in get play status procedure %d", __func__, 3905 p_rsp->status); 3906 } 3907 } 3908 3909 /*************************************************************************** 3910 * 3911 * Function handle_get_folder_items_response 3912 * 3913 * Description handles the the get folder items response, calls 3914 * HAL callback to send the folder items. 3915 * Returns None 3916 * 3917 **************************************************************************/ 3918 static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg, 3919 tAVRC_GET_ITEMS_RSP* p_rsp) { 3920 btif_rc_device_cb_t* p_dev = 3921 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 3922 3923 if (p_rsp->status == AVRC_STS_NO_ERROR) { 3924 /* Convert the internal folder listing into a response that can 3925 * be passed onto JNI via HAL_CBACK 3926 */ 3927 uint8_t item_count = p_rsp->item_count; 3928 btrc_folder_items_t* btrc_items = (btrc_folder_items_t*)osi_malloc( 3929 sizeof(btrc_folder_items_t) * item_count); 3930 for (uint8_t i = 0; i < item_count; i++) { 3931 const tAVRC_ITEM* avrc_item = &(p_rsp->p_item_list[i]); 3932 btrc_folder_items_t* btrc_item = &(btrc_items[i]); 3933 BTIF_TRACE_DEBUG("%s folder item type %d", __func__, 3934 avrc_item->item_type); 3935 switch (avrc_item->item_type) { 3936 case AVRC_ITEM_MEDIA: 3937 BTIF_TRACE_DEBUG("%s setting type to %d", __func__, BTRC_ITEM_MEDIA); 3938 /* Allocate Space for Attributes */ 3939 btrc_item->media.num_attrs = avrc_item->u.media.attr_count; 3940 btrc_item->media.p_attrs = (btrc_element_attr_val_t*)osi_malloc( 3941 btrc_item->media.num_attrs * sizeof(btrc_element_attr_val_t)); 3942 get_folder_item_type_media(avrc_item, btrc_item); 3943 break; 3944 3945 case AVRC_ITEM_FOLDER: 3946 BTIF_TRACE_DEBUG("%s setting type to BTRC_ITEM_FOLDER", __func__); 3947 get_folder_item_type_folder(avrc_item, btrc_item); 3948 break; 3949 3950 case AVRC_ITEM_PLAYER: 3951 BTIF_TRACE_DEBUG("%s setting type to BTRC_ITEM_PLAYER", __func__); 3952 get_folder_item_type_player(avrc_item, btrc_item); 3953 break; 3954 3955 default: 3956 BTIF_TRACE_ERROR("%s cannot understand folder item type %d", __func__, 3957 avrc_item->item_type); 3958 } 3959 } 3960 3961 do_in_jni_thread( 3962 FROM_HERE, 3963 base::Bind(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr, 3964 BTRC_STS_NO_ERROR, 3965 /* We want to make the ownership explicit in native */ 3966 btrc_items, item_count)); 3967 3968 /* Release the memory block for items and attributes allocated here. 3969 * Since the executor for do_in_jni_thread is a Single Thread Task Runner it 3970 * is okay to queue up the cleanup of btrc_items */ 3971 do_in_jni_thread(FROM_HERE, base::Bind(cleanup_btrc_folder_items, 3972 btrc_items, item_count)); 3973 3974 BTIF_TRACE_DEBUG("%s get_folder_items_cb sent to JNI thread", __func__); 3975 } else { 3976 BTIF_TRACE_ERROR("%s: Error %d", __func__, p_rsp->status); 3977 do_in_jni_thread( 3978 FROM_HERE, 3979 base::Bind(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr, 3980 (btrc_status_t)p_rsp->status, nullptr, 0)); 3981 } 3982 } 3983 /*************************************************************************** 3984 * 3985 * Function cleanup_btrc_folder_items 3986 * 3987 * Description Frees the memory that was allocated for a list of folder 3988 * items. 3989 * Returns None 3990 **************************************************************************/ 3991 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, 3992 uint8_t item_count) { 3993 for (uint8_t i = 0; i < item_count; i++) { 3994 btrc_folder_items_t* btrc_item = &(btrc_items[i]); 3995 switch (btrc_item->item_type) { 3996 case BTRC_ITEM_MEDIA: 3997 osi_free(btrc_item->media.p_attrs); 3998 break; 3999 case BTRC_ITEM_PLAYER: 4000 case BTRC_ITEM_FOLDER: 4001 /*Nothing to free*/ 4002 break; 4003 default: 4004 BTIF_TRACE_WARNING("%s free unspecified type", __func__); 4005 } 4006 } 4007 osi_free(btrc_items); 4008 } 4009 4010 /*************************************************************************** 4011 * 4012 * Function get_folder_item_type_media 4013 * 4014 * Description Converts the AVRC representation of a folder item with 4015 * TYPE media to BTIF representation. 4016 * Returns None 4017 * 4018 **************************************************************************/ 4019 void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, 4020 btrc_folder_items_t* btrc_item) { 4021 btrc_item->item_type = BTRC_ITEM_MEDIA; 4022 const tAVRC_ITEM_MEDIA* avrc_item_media = &(avrc_item->u.media); 4023 btrc_item_media_t* btrc_item_media = &(btrc_item->media); 4024 /* UID */ 4025 memset(btrc_item_media->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t)); 4026 memcpy(btrc_item_media->uid, avrc_item_media->uid, 4027 sizeof(uint8_t) * BTRC_UID_SIZE); 4028 4029 /* Audio/Video type */ 4030 switch (avrc_item_media->type) { 4031 case AVRC_MEDIA_TYPE_AUDIO: 4032 btrc_item_media->type = BTRC_MEDIA_TYPE_AUDIO; 4033 break; 4034 case AVRC_MEDIA_TYPE_VIDEO: 4035 btrc_item_media->type = BTRC_MEDIA_TYPE_VIDEO; 4036 break; 4037 } 4038 4039 /* Charset ID */ 4040 btrc_item_media->charset_id = avrc_item_media->name.charset_id; 4041 4042 /* Copy the name */ 4043 BTIF_TRACE_DEBUG("%s max len %d str len %d", __func__, BTRC_MAX_ATTR_STR_LEN, 4044 avrc_item_media->name.str_len); 4045 memset(btrc_item_media->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t)); 4046 memcpy(btrc_item_media->name, avrc_item_media->name.p_str, 4047 sizeof(uint8_t) * (avrc_item_media->name.str_len)); 4048 4049 /* Extract each attribute */ 4050 for (int i = 0; i < avrc_item_media->attr_count; i++) { 4051 btrc_element_attr_val_t* btrc_attr_pair = &(btrc_item_media->p_attrs[i]); 4052 tAVRC_ATTR_ENTRY* avrc_attr_pair = &(avrc_item_media->p_attr_list[i]); 4053 4054 BTIF_TRACE_DEBUG("%s media attr id 0x%x", __func__, 4055 avrc_attr_pair->attr_id); 4056 4057 switch (avrc_attr_pair->attr_id) { 4058 case AVRC_MEDIA_ATTR_ID_TITLE: 4059 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TITLE; 4060 break; 4061 case AVRC_MEDIA_ATTR_ID_ARTIST: 4062 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ARTIST; 4063 break; 4064 case AVRC_MEDIA_ATTR_ID_ALBUM: 4065 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ALBUM; 4066 break; 4067 case AVRC_MEDIA_ATTR_ID_TRACK_NUM: 4068 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TRACK_NUM; 4069 break; 4070 case AVRC_MEDIA_ATTR_ID_NUM_TRACKS: 4071 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_NUM_TRACKS; 4072 break; 4073 case AVRC_MEDIA_ATTR_ID_GENRE: 4074 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_GENRE; 4075 break; 4076 case AVRC_MEDIA_ATTR_ID_PLAYING_TIME: 4077 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_PLAYING_TIME; 4078 break; 4079 default: 4080 BTIF_TRACE_ERROR("%s invalid media attr id: 0x%x", __func__, 4081 avrc_attr_pair->attr_id); 4082 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_INVALID; 4083 } 4084 4085 memset(btrc_attr_pair->text, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t)); 4086 memcpy(btrc_attr_pair->text, avrc_attr_pair->name.p_str, 4087 avrc_attr_pair->name.str_len); 4088 } 4089 } 4090 4091 /*************************************************************************** 4092 * 4093 * Function get_folder_item_type_folder 4094 * 4095 * Description Converts the AVRC representation of a folder item with 4096 * TYPE folder to BTIF representation. 4097 * Returns None 4098 * 4099 **************************************************************************/ 4100 void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item, 4101 btrc_folder_items_t* btrc_item) { 4102 btrc_item->item_type = BTRC_ITEM_FOLDER; 4103 const tAVRC_ITEM_FOLDER* avrc_item_folder = &(avrc_item->u.folder); 4104 btrc_item_folder_t* btrc_item_folder = &(btrc_item->folder); 4105 /* Copy the UID */ 4106 memset(btrc_item_folder->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t)); 4107 memcpy(btrc_item_folder->uid, avrc_item_folder->uid, 4108 sizeof(uint8_t) * BTRC_UID_SIZE); 4109 4110 /* Copy the type */ 4111 switch (avrc_item_folder->type) { 4112 case AVRC_FOLDER_TYPE_MIXED: 4113 btrc_item_folder->type = BTRC_FOLDER_TYPE_MIXED; 4114 break; 4115 case AVRC_FOLDER_TYPE_TITLES: 4116 btrc_item_folder->type = BTRC_FOLDER_TYPE_TITLES; 4117 break; 4118 case AVRC_FOLDER_TYPE_ALNUMS: 4119 btrc_item_folder->type = BTRC_FOLDER_TYPE_ALBUMS; 4120 break; 4121 case AVRC_FOLDER_TYPE_ARTISTS: 4122 btrc_item_folder->type = BTRC_FOLDER_TYPE_ARTISTS; 4123 break; 4124 case AVRC_FOLDER_TYPE_GENRES: 4125 btrc_item_folder->type = BTRC_FOLDER_TYPE_GENRES; 4126 break; 4127 case AVRC_FOLDER_TYPE_PLAYLISTS: 4128 btrc_item_folder->type = BTRC_FOLDER_TYPE_PLAYLISTS; 4129 break; 4130 case AVRC_FOLDER_TYPE_YEARS: 4131 btrc_item_folder->type = BTRC_FOLDER_TYPE_YEARS; 4132 break; 4133 } 4134 4135 /* Copy if playable */ 4136 btrc_item_folder->playable = avrc_item_folder->playable; 4137 4138 /* Copy name */ 4139 BTIF_TRACE_DEBUG("%s max len %d str len %d", __func__, BTRC_MAX_ATTR_STR_LEN, 4140 avrc_item_folder->name.str_len); 4141 memset(btrc_item_folder->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t)); 4142 memcpy(btrc_item_folder->name, avrc_item_folder->name.p_str, 4143 avrc_item_folder->name.str_len * sizeof(uint8_t)); 4144 4145 /* Copy charset */ 4146 btrc_item_folder->charset_id = avrc_item_folder->name.charset_id; 4147 } 4148 4149 /*************************************************************************** 4150 * 4151 * Function get_folder_item_type_player 4152 * 4153 * Description Converts the AVRC representation of a folder item with 4154 * TYPE player to BTIF representation. 4155 * Returns None 4156 * 4157 **************************************************************************/ 4158 void get_folder_item_type_player(const tAVRC_ITEM* avrc_item, 4159 btrc_folder_items_t* btrc_item) { 4160 btrc_item->item_type = BTRC_ITEM_PLAYER; 4161 const tAVRC_ITEM_PLAYER* avrc_item_player = &(avrc_item->u.player); 4162 btrc_item_player_t* btrc_item_player = &(btrc_item->player); 4163 /* Player ID */ 4164 btrc_item_player->player_id = avrc_item_player->player_id; 4165 /* Major type */ 4166 btrc_item_player->major_type = avrc_item_player->major_type; 4167 /* Sub type */ 4168 btrc_item_player->sub_type = avrc_item_player->sub_type; 4169 /* Play status */ 4170 btrc_item_player->play_status = avrc_item_player->play_status; 4171 /* Features */ 4172 memcpy(btrc_item_player->features, avrc_item_player->features, 4173 BTRC_FEATURE_BIT_MASK_SIZE); 4174 4175 memset(btrc_item_player->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t)); 4176 memcpy(btrc_item_player->name, avrc_item_player->name.p_str, 4177 avrc_item_player->name.str_len); 4178 } 4179 4180 /*************************************************************************** 4181 * 4182 * Function handle_change_path_response 4183 * 4184 * Description handles the the change path response, calls 4185 * HAL callback to send the updated folder 4186 * Returns None 4187 * 4188 **************************************************************************/ 4189 static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg, 4190 tAVRC_CHG_PATH_RSP* p_rsp) { 4191 btif_rc_device_cb_t* p_dev = 4192 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 4193 4194 if (p_rsp->status == AVRC_STS_NO_ERROR) { 4195 do_in_jni_thread(FROM_HERE, 4196 base::Bind(bt_rc_ctrl_callbacks->change_folder_path_cb, 4197 p_dev->rc_addr, p_rsp->num_items)); 4198 } else { 4199 BTIF_TRACE_ERROR("%s error in handle_change_path_response %d", __func__, 4200 p_rsp->status); 4201 } 4202 } 4203 4204 /*************************************************************************** 4205 * 4206 * Function handle_set_browsed_player_response 4207 * 4208 * Description handles the the change path response, calls 4209 * HAL callback to send the updated folder 4210 * Returns None 4211 * 4212 **************************************************************************/ 4213 static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg, 4214 tAVRC_SET_BR_PLAYER_RSP* p_rsp) { 4215 btif_rc_device_cb_t* p_dev = 4216 btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 4217 4218 if (p_rsp->status == AVRC_STS_NO_ERROR) { 4219 do_in_jni_thread( 4220 FROM_HERE, 4221 base::Bind(bt_rc_ctrl_callbacks->set_browsed_player_cb, p_dev->rc_addr, 4222 p_rsp->num_items, p_rsp->folder_depth)); 4223 } else { 4224 BTIF_TRACE_ERROR("%s error %d", __func__, p_rsp->status); 4225 } 4226 } 4227 4228 /*************************************************************************** 4229 * 4230 * Function clear_cmd_timeout 4231 * 4232 * Description helper function to stop the command timeout timer 4233 * Returns None 4234 * 4235 **************************************************************************/ 4236 static void clear_cmd_timeout(uint8_t label) { 4237 rc_transaction_t* p_txn; 4238 4239 p_txn = get_transaction_by_lbl(label); 4240 if (p_txn == NULL) { 4241 BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __func__); 4242 return; 4243 } 4244 4245 if (p_txn->txn_timer != NULL) alarm_cancel(p_txn->txn_timer); 4246 } 4247 4248 /*************************************************************************** 4249 * 4250 * Function handle_avk_rc_metamsg_rsp 4251 * 4252 * Description Handle RC metamessage response 4253 * 4254 * Returns void 4255 * 4256 **************************************************************************/ 4257 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) { 4258 tAVRC_RESPONSE avrc_response = {0}; 4259 uint8_t scratch_buf[512] = {0}; // this variable is unused 4260 uint16_t buf_len; 4261 tAVRC_STS status; 4262 4263 BTIF_TRACE_DEBUG("%s: opcode: %d rsp_code: %d ", __func__, 4264 pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); 4265 4266 status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, 4267 &buf_len); 4268 if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && 4269 (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) && 4270 (pmeta_msg->code <= AVRC_RSP_INTERIM)) { 4271 BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d", __func__, 4272 status, avrc_response.pdu, 4273 pmeta_msg->p_msg->vendor.hdr.ctype); 4274 4275 switch (avrc_response.pdu) { 4276 case AVRC_PDU_REGISTER_NOTIFICATION: 4277 handle_notification_response(pmeta_msg, &avrc_response.reg_notif); 4278 if (pmeta_msg->code == AVRC_RSP_INTERIM) { 4279 /* Don't free the transaction Id */ 4280 clear_cmd_timeout(pmeta_msg->label); 4281 return; 4282 } 4283 break; 4284 4285 case AVRC_PDU_GET_CAPABILITIES: 4286 handle_get_capability_response(pmeta_msg, &avrc_response.get_caps); 4287 break; 4288 4289 case AVRC_PDU_LIST_PLAYER_APP_ATTR: 4290 handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr); 4291 break; 4292 4293 case AVRC_PDU_LIST_PLAYER_APP_VALUES: 4294 handle_app_val_response(pmeta_msg, &avrc_response.list_app_values); 4295 break; 4296 4297 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: 4298 handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val); 4299 break; 4300 4301 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: 4302 handle_app_attr_txt_response(pmeta_msg, 4303 &avrc_response.get_app_attr_txt); 4304 break; 4305 4306 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: 4307 handle_app_attr_val_txt_response(pmeta_msg, 4308 &avrc_response.get_app_val_txt); 4309 break; 4310 4311 case AVRC_PDU_SET_PLAYER_APP_VALUE: 4312 handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val); 4313 break; 4314 4315 case AVRC_PDU_GET_ELEMENT_ATTR: 4316 handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_attrs); 4317 break; 4318 4319 case AVRC_PDU_GET_PLAY_STATUS: 4320 handle_get_playstatus_response(pmeta_msg, 4321 &avrc_response.get_play_status); 4322 break; 4323 4324 case AVRC_PDU_SET_ADDRESSED_PLAYER: 4325 handle_set_addressed_player_response(pmeta_msg, &avrc_response.rsp); 4326 break; 4327 } 4328 } else if (AVRC_OP_BROWSE == pmeta_msg->p_msg->hdr.opcode) { 4329 BTIF_TRACE_DEBUG("%s AVRC_OP_BROWSE pdu %d", __func__, avrc_response.pdu); 4330 /* check what kind of command it is for browsing */ 4331 switch (avrc_response.pdu) { 4332 case AVRC_PDU_GET_FOLDER_ITEMS: 4333 handle_get_folder_items_response(pmeta_msg, &avrc_response.get_items); 4334 break; 4335 case AVRC_PDU_CHANGE_PATH: 4336 handle_change_path_response(pmeta_msg, &avrc_response.chg_path); 4337 break; 4338 case AVRC_PDU_SET_BROWSED_PLAYER: 4339 handle_set_browsed_player_response(pmeta_msg, &avrc_response.br_player); 4340 break; 4341 default: 4342 BTIF_TRACE_ERROR("%s cannot handle browse pdu %d", __func__, 4343 pmeta_msg->p_msg->hdr.opcode); 4344 } 4345 } else { 4346 BTIF_TRACE_DEBUG( 4347 "%s: Invalid Vendor Command code: %d len: %d. Not processing it.", 4348 __func__, pmeta_msg->code, pmeta_msg->len); 4349 return; 4350 } 4351 BTIF_TRACE_DEBUG("XX __func__ release transaction %d", pmeta_msg->label); 4352 release_transaction(pmeta_msg->label); 4353 } 4354 4355 /*************************************************************************** 4356 * 4357 * Function handle_avk_rc_metamsg_cmd 4358 * 4359 * Description Handle RC metamessage response 4360 * 4361 * Returns void 4362 * 4363 **************************************************************************/ 4364 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { 4365 tAVRC_COMMAND avrc_cmd = {0}; 4366 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 4367 btif_rc_device_cb_t* p_dev = NULL; 4368 4369 BTIF_TRACE_DEBUG("%s: opcode: %d rsp_code: %d", __func__, 4370 pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); 4371 status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd); 4372 if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && 4373 (pmeta_msg->code <= AVRC_CMD_GEN_INQ)) { 4374 BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d", 4375 __func__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label); 4376 4377 if (status != AVRC_STS_NO_ERROR) { 4378 /* return error */ 4379 BTIF_TRACE_WARNING( 4380 "%s: Error in parsing received metamsg command. status: 0x%02x", 4381 __func__, status); 4382 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, 4383 status, pmeta_msg->p_msg->hdr.opcode); 4384 } else { 4385 p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); 4386 if (p_dev == NULL) { 4387 BTIF_TRACE_ERROR("%s: avk rc meta msg cmd for Invalid rc handle", 4388 __func__); 4389 return; 4390 } 4391 4392 if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) { 4393 uint8_t event_id = avrc_cmd.reg_notif.event_id; 4394 BTIF_TRACE_EVENT("%s: Register notification event_id: %s", __func__, 4395 dump_rc_notification_event_id(event_id)); 4396 } else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) { 4397 BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __func__); 4398 } 4399 4400 btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label, 4401 p_dev); 4402 } 4403 } else { 4404 BTIF_TRACE_DEBUG( 4405 "%s: Invalid Vendor Command code: %d len: %d. Not processing it.", 4406 __func__, pmeta_msg->code, pmeta_msg->len); 4407 return; 4408 } 4409 } 4410 4411 /*************************************************************************** 4412 * 4413 * Function cleanup 4414 * 4415 * Description Closes the AVRC interface 4416 * 4417 * Returns void 4418 * 4419 **************************************************************************/ 4420 static void cleanup() { 4421 BTIF_TRACE_EVENT("%s: ", __func__); 4422 if (bt_rc_callbacks) { 4423 bt_rc_callbacks = NULL; 4424 } 4425 4426 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 4427 alarm_free(btif_rc_cb.rc_multi_cb[idx].rc_play_status_timer); 4428 memset(&btif_rc_cb.rc_multi_cb[idx], 0, 4429 sizeof(btif_rc_cb.rc_multi_cb[idx])); 4430 } 4431 4432 BTIF_TRACE_EVENT("%s: completed", __func__); 4433 } 4434 4435 /*************************************************************************** 4436 * 4437 * Function cleanup_ctrl 4438 * 4439 * Description Closes the AVRC Controller interface 4440 * 4441 * Returns void 4442 * 4443 **************************************************************************/ 4444 static void cleanup_ctrl() { 4445 BTIF_TRACE_EVENT("%s: ", __func__); 4446 4447 if (bt_rc_ctrl_callbacks) { 4448 bt_rc_ctrl_callbacks = NULL; 4449 } 4450 4451 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { 4452 alarm_free(btif_rc_cb.rc_multi_cb[idx].rc_play_status_timer); 4453 memset(&btif_rc_cb.rc_multi_cb[idx], 0, 4454 sizeof(btif_rc_cb.rc_multi_cb[idx])); 4455 } 4456 4457 memset(&btif_rc_cb.rc_multi_cb, 0, sizeof(btif_rc_cb.rc_multi_cb)); 4458 BTIF_TRACE_EVENT("%s: completed", __func__); 4459 } 4460 4461 /*************************************************************************** 4462 * 4463 * Function getcapabilities_cmd 4464 * 4465 * Description GetCapabilties from Remote(Company_ID, Events_Supported) 4466 * 4467 * Returns void 4468 * 4469 **************************************************************************/ 4470 static bt_status_t getcapabilities_cmd(uint8_t cap_id, 4471 btif_rc_device_cb_t* p_dev) { 4472 BTIF_TRACE_DEBUG("%s: cap_id: %d", __func__, cap_id); 4473 CHECK_RC_CONNECTED(p_dev); 4474 4475 tAVRC_COMMAND avrc_cmd = {0}; 4476 avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR; 4477 avrc_cmd.get_caps.capability_id = cap_id; 4478 avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES; 4479 avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR; 4480 4481 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 4482 } 4483 4484 /*************************************************************************** 4485 * 4486 * Function list_player_app_setting_attrib_cmd 4487 * 4488 * Description Get supported List Player Attributes 4489 * 4490 * Returns void 4491 * 4492 **************************************************************************/ 4493 static bt_status_t list_player_app_setting_attrib_cmd( 4494 btif_rc_device_cb_t* p_dev) { 4495 BTIF_TRACE_DEBUG("%s", __func__); 4496 CHECK_RC_CONNECTED(p_dev); 4497 4498 tAVRC_COMMAND avrc_cmd = {0}; 4499 avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR; 4500 avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR; 4501 avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR; 4502 4503 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 4504 } 4505 4506 /*************************************************************************** 4507 * 4508 * Function list_player_app_setting_value_cmd 4509 * 4510 * Description Get values of supported Player Attributes 4511 * 4512 * Returns void 4513 * 4514 **************************************************************************/ 4515 static bt_status_t list_player_app_setting_value_cmd( 4516 uint8_t attrib_id, btif_rc_device_cb_t* p_dev) { 4517 BTIF_TRACE_DEBUG("%s: attrib_id: %d", __func__, attrib_id); 4518 CHECK_RC_CONNECTED(p_dev); 4519 4520 tAVRC_COMMAND avrc_cmd = {0}; 4521 avrc_cmd.list_app_values.attr_id = attrib_id; 4522 avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR; 4523 avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES; 4524 avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR; 4525 4526 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 4527 } 4528 4529 /*************************************************************************** 4530 * 4531 * Function get_player_app_setting_cmd 4532 * 4533 * Description Get current values of Player Attributes 4534 * 4535 * Returns void 4536 * 4537 **************************************************************************/ 4538 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, 4539 uint8_t* attrib_ids, 4540 btif_rc_device_cb_t* p_dev) { 4541 BTIF_TRACE_DEBUG("%s: num_attrib: %d", __func__, num_attrib); 4542 CHECK_RC_CONNECTED(p_dev); 4543 4544 tAVRC_COMMAND avrc_cmd = {0}; 4545 avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR; 4546 avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR; 4547 avrc_cmd.get_cur_app_val.num_attr = num_attrib; 4548 avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE; 4549 4550 for (int count = 0; count < num_attrib; count++) { 4551 avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count]; 4552 } 4553 4554 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 4555 } 4556 4557 /*************************************************************************** 4558 * 4559 * Function get_playback_state_cmd 4560 * 4561 * Description Fetch the current playback state for the device 4562 * 4563 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4564 * BT_STATUS_FAIL. 4565 * 4566 **************************************************************************/ 4567 static bt_status_t get_playback_state_cmd(const RawAddress& bd_addr) { 4568 BTIF_TRACE_DEBUG("%s", __func__); 4569 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4570 return get_play_status_cmd(p_dev); 4571 } 4572 4573 /*************************************************************************** 4574 * 4575 * Function get_now_playing_list_cmd 4576 * 4577 * Description Fetch the now playing list 4578 * 4579 * Paramters start_item: First item to fetch (0 to fetch from beganning) 4580 * end_item: Last item to fetch (0xffffffff to fetch until end) 4581 * 4582 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4583 * BT_STATUS_FAIL. 4584 * 4585 **************************************************************************/ 4586 static bt_status_t get_now_playing_list_cmd(const RawAddress& bd_addr, 4587 uint32_t start_item, 4588 uint32_t end_item) { 4589 BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, end_item); 4590 return get_folder_items_cmd(bd_addr, AVRC_SCOPE_NOW_PLAYING, start_item, 4591 end_item); 4592 } 4593 4594 /*************************************************************************** 4595 * 4596 * Function get_folder_list_cmd 4597 * 4598 * Description Fetch the currently selected folder list 4599 * 4600 * Paramters start_item: First item to fetch (0 to fetch from beganning) 4601 * end_item: Last item to fetch (0xffffffff to fetch until end) 4602 * 4603 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4604 * BT_STATUS_FAIL. 4605 * 4606 **************************************************************************/ 4607 static bt_status_t get_folder_list_cmd(const RawAddress& bd_addr, 4608 uint32_t start_item, uint32_t end_item) { 4609 BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, end_item); 4610 return get_folder_items_cmd(bd_addr, AVRC_SCOPE_FILE_SYSTEM, start_item, 4611 end_item); 4612 } 4613 4614 /*************************************************************************** 4615 * 4616 * Function get_player_list_cmd 4617 * 4618 * Description Fetch the player list 4619 * 4620 * Paramters start_item: First item to fetch (0 to fetch from beganning) 4621 * end_item: Last item to fetch (0xffffffff to fetch until end) 4622 * 4623 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4624 * BT_STATUS_FAIL. 4625 * 4626 **************************************************************************/ 4627 static bt_status_t get_player_list_cmd(const RawAddress& bd_addr, 4628 uint32_t start_item, uint32_t end_item) { 4629 BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, end_item); 4630 return get_folder_items_cmd(bd_addr, AVRC_SCOPE_PLAYER_LIST, start_item, 4631 end_item); 4632 } 4633 4634 /*************************************************************************** 4635 * 4636 * Function change_folder_path_cmd 4637 * 4638 * Description Change the folder. 4639 * 4640 * Paramters direction: Direction (Up/Down) to change folder 4641 * uid: The UID of folder to move to 4642 * start_item: First item to fetch (0 to fetch from beganning) 4643 * end_item: Last item to fetch (0xffffffff to fetch until end) 4644 * 4645 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4646 * BT_STATUS_FAIL. 4647 * 4648 **************************************************************************/ 4649 static bt_status_t change_folder_path_cmd(const RawAddress& bd_addr, 4650 uint8_t direction, uint8_t* uid) { 4651 BTIF_TRACE_DEBUG("%s: direction %d", __func__, direction); 4652 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4653 CHECK_RC_CONNECTED(p_dev); 4654 CHECK_BR_CONNECTED(p_dev); 4655 4656 tAVRC_COMMAND avrc_cmd = {0}; 4657 4658 avrc_cmd.chg_path.pdu = AVRC_PDU_CHANGE_PATH; 4659 avrc_cmd.chg_path.status = AVRC_STS_NO_ERROR; 4660 // TODO(sanketa): Improve for database aware clients. 4661 avrc_cmd.chg_path.uid_counter = 0; 4662 avrc_cmd.chg_path.direction = direction; 4663 4664 memset(avrc_cmd.chg_path.folder_uid, 0, AVRC_UID_SIZE * sizeof(uint8_t)); 4665 memcpy(avrc_cmd.chg_path.folder_uid, uid, AVRC_UID_SIZE * sizeof(uint8_t)); 4666 4667 BT_HDR* p_msg = NULL; 4668 tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg); 4669 if (status != AVRC_STS_NO_ERROR) { 4670 BTIF_TRACE_ERROR("%s failed to build command status %d", __func__, status); 4671 return BT_STATUS_FAIL; 4672 } 4673 4674 rc_transaction_t* p_transaction = NULL; 4675 bt_status_t tran_status = get_transaction(&p_transaction); 4676 if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) { 4677 osi_free(p_msg); 4678 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x", 4679 __func__, tran_status); 4680 return BT_STATUS_FAIL; 4681 } 4682 4683 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__, 4684 p_transaction->lbl); 4685 BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg); 4686 return BT_STATUS_SUCCESS; 4687 } 4688 4689 /*************************************************************************** 4690 * 4691 * Function set_browsed_player_cmd 4692 * 4693 * Description Change the browsed player. 4694 * 4695 * Paramters id: The UID of player to move to 4696 * 4697 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4698 * BT_STATUS_FAIL. 4699 * 4700 **************************************************************************/ 4701 static bt_status_t set_browsed_player_cmd(const RawAddress& bd_addr, 4702 uint16_t id) { 4703 BTIF_TRACE_DEBUG("%s: id %d", __func__, id); 4704 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4705 CHECK_RC_CONNECTED(p_dev); 4706 CHECK_BR_CONNECTED(p_dev); 4707 4708 rc_transaction_t* p_transaction = NULL; 4709 4710 tAVRC_COMMAND avrc_cmd = {0}; 4711 avrc_cmd.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER; 4712 avrc_cmd.br_player.status = AVRC_STS_NO_ERROR; 4713 // TODO(sanketa): Improve for database aware clients. 4714 avrc_cmd.br_player.player_id = id; 4715 4716 BT_HDR* p_msg = NULL; 4717 tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg); 4718 if (status != AVRC_STS_NO_ERROR) { 4719 BTIF_TRACE_ERROR("%s failed to build command status %d", __func__, status); 4720 return BT_STATUS_FAIL; 4721 } 4722 4723 bt_status_t tran_status = get_transaction(&p_transaction); 4724 if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) { 4725 osi_free(p_msg); 4726 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x", 4727 __func__, tran_status); 4728 return BT_STATUS_FAIL; 4729 } 4730 4731 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__, 4732 p_transaction->lbl); 4733 BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg); 4734 return BT_STATUS_SUCCESS; 4735 } 4736 4737 /*************************************************************************** 4738 ** 4739 ** Function set_addressed_player_cmd 4740 ** 4741 ** Description Change the addressed player. 4742 ** 4743 ** Paramters id: The UID of player to move to 4744 ** 4745 ** Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4746 ** BT_STATUS_FAIL. 4747 ** 4748 ***************************************************************************/ 4749 static bt_status_t set_addressed_player_cmd(const RawAddress& bd_addr, 4750 uint16_t id) { 4751 BTIF_TRACE_DEBUG("%s: id %d", __func__, id); 4752 4753 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4754 CHECK_RC_CONNECTED(p_dev); 4755 CHECK_BR_CONNECTED(p_dev); 4756 4757 tAVRC_COMMAND avrc_cmd = {0}; 4758 BT_HDR* p_msg = NULL; 4759 4760 avrc_cmd.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER; 4761 avrc_cmd.addr_player.status = AVRC_STS_NO_ERROR; 4762 // TODO(sanketa): Improve for database aware clients. 4763 avrc_cmd.addr_player.player_id = id; 4764 4765 tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg); 4766 if (status != AVRC_STS_NO_ERROR) { 4767 BTIF_TRACE_ERROR("%s: failed to build command status %d", __func__, status); 4768 return BT_STATUS_FAIL; 4769 } 4770 4771 rc_transaction_t* p_transaction = NULL; 4772 bt_status_t tran_status = get_transaction(&p_transaction); 4773 4774 if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) { 4775 osi_free(p_msg); 4776 BTIF_TRACE_ERROR("%s: failed to obtain txn details. status: 0x%02x", 4777 __func__, tran_status); 4778 return BT_STATUS_FAIL; 4779 } 4780 4781 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__, 4782 p_transaction->lbl); 4783 BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg); 4784 return BT_STATUS_SUCCESS; 4785 } 4786 4787 /*************************************************************************** 4788 * 4789 * Function get_folder_items_cmd 4790 * 4791 * Description Helper function to browse the content hierarchy of the 4792 * TG device. 4793 * 4794 * Paramters scope: AVRC_SCOPE_NOW_PLAYING (etc) for various browseable 4795 * content 4796 * start_item: First item to fetch (0 to fetch from beganning) 4797 * end_item: Last item to fetch (0xffff to fetch until end) 4798 * 4799 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise 4800 * BT_STATUS_FAIL. 4801 * 4802 **************************************************************************/ 4803 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, 4804 uint8_t scope, uint32_t start_item, 4805 uint32_t end_item) { 4806 /* Check that both avrcp and browse channel are connected. */ 4807 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4808 BTIF_TRACE_DEBUG("%s", __func__); 4809 CHECK_RC_CONNECTED(p_dev); 4810 CHECK_BR_CONNECTED(p_dev); 4811 4812 tAVRC_COMMAND avrc_cmd = {0}; 4813 4814 /* Set the layer specific to point to browse although this should really 4815 * be done by lower layers and looking at the PDU 4816 */ 4817 avrc_cmd.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS; 4818 avrc_cmd.get_items.status = AVRC_STS_NO_ERROR; 4819 avrc_cmd.get_items.scope = scope; 4820 avrc_cmd.get_items.start_item = start_item; 4821 avrc_cmd.get_items.end_item = end_item; 4822 avrc_cmd.get_items.attr_count = 0; /* p_attr_list does not matter hence */ 4823 4824 BT_HDR* p_msg = NULL; 4825 tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg); 4826 if (status != AVRC_STS_NO_ERROR) { 4827 BTIF_TRACE_ERROR("%s failed to build command status %d", __func__, status); 4828 return BT_STATUS_FAIL; 4829 } 4830 4831 rc_transaction_t* p_transaction = NULL; 4832 bt_status_t tran_status = get_transaction(&p_transaction); 4833 if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) { 4834 osi_free(p_msg); 4835 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x", 4836 __func__, tran_status); 4837 return BT_STATUS_FAIL; 4838 } 4839 4840 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__, 4841 p_transaction->lbl); 4842 BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg); 4843 return BT_STATUS_SUCCESS; 4844 } 4845 4846 /*************************************************************************** 4847 * 4848 * Function change_player_app_setting 4849 * 4850 * Description Set current values of Player Attributes 4851 * 4852 * Returns void 4853 * 4854 **************************************************************************/ 4855 static bt_status_t change_player_app_setting(const RawAddress& bd_addr, 4856 uint8_t num_attrib, 4857 uint8_t* attrib_ids, 4858 uint8_t* attrib_vals) { 4859 BTIF_TRACE_DEBUG("%s: num_attrib: %d", __func__, num_attrib); 4860 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4861 CHECK_RC_CONNECTED(p_dev); 4862 4863 tAVRC_COMMAND avrc_cmd = {0}; 4864 avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR; 4865 avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR; 4866 avrc_cmd.set_app_val.num_val = num_attrib; 4867 avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE; 4868 avrc_cmd.set_app_val.p_vals = 4869 (tAVRC_APP_SETTING*)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib); 4870 for (int count = 0; count < num_attrib; count++) { 4871 avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count]; 4872 avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count]; 4873 } 4874 4875 bt_status_t st = build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev); 4876 osi_free_and_reset((void**)&avrc_cmd.set_app_val.p_vals); 4877 return st; 4878 } 4879 4880 /*************************************************************************** 4881 * 4882 * Function play_item_cmd 4883 * 4884 * Description Play the item specified by UID & scope 4885 * 4886 * Returns void 4887 * 4888 **************************************************************************/ 4889 static bt_status_t play_item_cmd(const RawAddress& bd_addr, uint8_t scope, 4890 uint8_t* uid, uint16_t uid_counter) { 4891 BTIF_TRACE_DEBUG("%s: scope %d uid_counter %d", __func__, scope, uid_counter); 4892 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 4893 CHECK_RC_CONNECTED(p_dev); 4894 CHECK_BR_CONNECTED(p_dev); 4895 4896 tAVRC_COMMAND avrc_cmd = {0}; 4897 avrc_cmd.pdu = AVRC_PDU_PLAY_ITEM; 4898 avrc_cmd.play_item.opcode = AVRC_OP_VENDOR; 4899 avrc_cmd.play_item.status = AVRC_STS_NO_ERROR; 4900 avrc_cmd.play_item.scope = scope; 4901 memcpy(avrc_cmd.play_item.uid, uid, AVRC_UID_SIZE); 4902 avrc_cmd.play_item.uid_counter = uid_counter; 4903 4904 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev); 4905 } 4906 4907 /*************************************************************************** 4908 * 4909 * Function get_player_app_setting_attr_text_cmd 4910 * 4911 * Description Get text description for app attribute 4912 * 4913 * Returns void 4914 * 4915 **************************************************************************/ 4916 static bt_status_t get_player_app_setting_attr_text_cmd( 4917 uint8_t* attrs, uint8_t num_attrs, btif_rc_device_cb_t* p_dev) { 4918 BTIF_TRACE_DEBUG("%s: num attrs: %d", __func__, num_attrs); 4919 CHECK_RC_CONNECTED(p_dev); 4920 4921 tAVRC_COMMAND avrc_cmd = {0}; 4922 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT; 4923 avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR; 4924 avrc_cmd.get_app_attr_txt.num_attr = num_attrs; 4925 4926 for (int count = 0; count < num_attrs; count++) { 4927 avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count]; 4928 } 4929 4930 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 4931 } 4932 4933 /*************************************************************************** 4934 * 4935 * Function get_player_app_setting_val_text_cmd 4936 * 4937 * Description Get text description for app attribute values 4938 * 4939 * Returns void 4940 * 4941 **************************************************************************/ 4942 static bt_status_t get_player_app_setting_value_text_cmd( 4943 uint8_t* vals, uint8_t num_vals, btif_rc_device_cb_t* p_dev) { 4944 BTIF_TRACE_DEBUG("%s: num_vals: %d", __func__, num_vals); 4945 CHECK_RC_CONNECTED(p_dev); 4946 4947 tAVRC_COMMAND avrc_cmd = {0}; 4948 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT; 4949 avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR; 4950 avrc_cmd.get_app_val_txt.num_val = num_vals; 4951 4952 for (int count = 0; count < num_vals; count++) { 4953 avrc_cmd.get_app_val_txt.vals[count] = vals[count]; 4954 } 4955 4956 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 4957 } 4958 4959 /*************************************************************************** 4960 * 4961 * Function register_notification_cmd 4962 * 4963 * Description Send Command to register for a Notification ID 4964 * 4965 * Returns void 4966 * 4967 **************************************************************************/ 4968 static bt_status_t register_notification_cmd(uint8_t label, uint8_t event_id, 4969 uint32_t event_value, 4970 btif_rc_device_cb_t* p_dev) { 4971 BTIF_TRACE_DEBUG("%s: event_id: %d event_value %d", __func__, event_id, 4972 event_value); 4973 CHECK_RC_CONNECTED(p_dev); 4974 4975 tAVRC_COMMAND avrc_cmd = {0}; 4976 avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR; 4977 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR; 4978 avrc_cmd.reg_notif.event_id = event_id; 4979 avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 4980 avrc_cmd.reg_notif.param = event_value; 4981 4982 BT_HDR* p_msg = NULL; 4983 tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg); 4984 if (status == AVRC_STS_NO_ERROR) { 4985 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; 4986 BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__, 4987 label); 4988 if (p_msg != NULL) { 4989 BTA_AvVendorCmd(p_dev->rc_handle, label, AVRC_CMD_NOTIF, data_start, 4990 p_msg->len); 4991 status = BT_STATUS_SUCCESS; 4992 } 4993 } else { 4994 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__, 4995 status); 4996 } 4997 osi_free(p_msg); 4998 return (bt_status_t)status; 4999 } 5000 5001 /*************************************************************************** 5002 * 5003 * Function get_element_attribute_cmd 5004 * 5005 * Description Get Element Attribute for attributeIds 5006 * 5007 * Returns void 5008 * 5009 **************************************************************************/ 5010 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, 5011 uint32_t* p_attr_ids, 5012 btif_rc_device_cb_t* p_dev) { 5013 BTIF_TRACE_DEBUG("%s: num_attribute: %d attribute_id: %d", __func__, 5014 num_attribute, p_attr_ids[0]); 5015 CHECK_RC_CONNECTED(p_dev); 5016 5017 tAVRC_COMMAND avrc_cmd = {0}; 5018 avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR; 5019 avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR; 5020 avrc_cmd.get_elem_attrs.num_attr = num_attribute; 5021 avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR; 5022 for (int count = 0; count < num_attribute; count++) { 5023 avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count]; 5024 } 5025 5026 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 5027 } 5028 5029 /*************************************************************************** 5030 * 5031 * Function get_play_status_cmd 5032 * 5033 * Description Get Playing Status of a Device 5034 * 5035 * Returns bt_status_t 5036 * 5037 **************************************************************************/ 5038 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev) { 5039 BTIF_TRACE_DEBUG("%s", __func__); 5040 CHECK_RC_CONNECTED(p_dev); 5041 5042 tAVRC_COMMAND avrc_cmd = {0}; 5043 avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR; 5044 avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS; 5045 avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR; 5046 5047 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev); 5048 } 5049 5050 /*************************************************************************** 5051 * 5052 * Function set_volume_rsp 5053 * 5054 * Description Rsp for SetAbsoluteVolume Command 5055 * 5056 * Returns void 5057 * 5058 **************************************************************************/ 5059 static bt_status_t set_volume_rsp(const RawAddress& bd_addr, uint8_t abs_vol, 5060 uint8_t label) { 5061 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 5062 tAVRC_RESPONSE avrc_rsp; 5063 BT_HDR* p_msg = NULL; 5064 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 5065 5066 CHECK_RC_CONNECTED(p_dev); 5067 5068 BTIF_TRACE_DEBUG("%s: abs_vol: %d", __func__, abs_vol); 5069 5070 avrc_rsp.volume.opcode = AVRC_OP_VENDOR; 5071 avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME; 5072 avrc_rsp.volume.status = AVRC_STS_NO_ERROR; 5073 avrc_rsp.volume.volume = abs_vol; 5074 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); 5075 if (status == AVRC_STS_NO_ERROR) { 5076 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; 5077 BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__, 5078 p_dev->rc_vol_label); 5079 if (p_msg != NULL) { 5080 BTA_AvVendorRsp(p_dev->rc_handle, label, AVRC_RSP_ACCEPT, data_start, 5081 p_msg->len, 0); 5082 status = BT_STATUS_SUCCESS; 5083 } 5084 } else { 5085 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__, 5086 status); 5087 } 5088 osi_free(p_msg); 5089 return (bt_status_t)status; 5090 } 5091 5092 /*************************************************************************** 5093 * 5094 * Function send_register_abs_vol_rsp 5095 * 5096 * Description Rsp for Notification of Absolute Volume 5097 * 5098 * Returns void 5099 * 5100 **************************************************************************/ 5101 static bt_status_t volume_change_notification_rsp( 5102 const RawAddress& bd_addr, btrc_notification_type_t rsp_type, 5103 uint8_t abs_vol, uint8_t label) { 5104 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 5105 tAVRC_RESPONSE avrc_rsp; 5106 BT_HDR* p_msg = NULL; 5107 BTIF_TRACE_DEBUG("%s: rsp_type: %d abs_vol: %d", __func__, rsp_type, abs_vol); 5108 5109 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 5110 5111 CHECK_RC_CONNECTED(p_dev); 5112 5113 avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR; 5114 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION; 5115 avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR; 5116 avrc_rsp.reg_notif.param.volume = abs_vol; 5117 avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE; 5118 5119 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); 5120 if (status == AVRC_STS_NO_ERROR) { 5121 BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__, 5122 label); 5123 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; 5124 BTA_AvVendorRsp(p_dev->rc_handle, label, 5125 (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) 5126 ? AVRC_RSP_INTERIM 5127 : AVRC_RSP_CHANGED, 5128 data_start, p_msg->len, 0); 5129 status = BT_STATUS_SUCCESS; 5130 } else { 5131 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__, 5132 status); 5133 } 5134 osi_free(p_msg); 5135 5136 return (bt_status_t)status; 5137 } 5138 5139 /*************************************************************************** 5140 * 5141 * Function send_groupnavigation_cmd 5142 * 5143 * Description Send Pass-Through command 5144 * 5145 * Returns void 5146 * 5147 **************************************************************************/ 5148 static bt_status_t send_groupnavigation_cmd(const RawAddress& bd_addr, 5149 uint8_t key_code, 5150 uint8_t key_state) { 5151 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 5152 rc_transaction_t* p_transaction = NULL; 5153 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __func__, key_code, 5154 key_state); 5155 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); 5156 5157 CHECK_RC_CONNECTED(p_dev); 5158 5159 if (p_dev->rc_features & BTA_AV_FEAT_RCTG) { 5160 bt_status_t tran_status = get_transaction(&p_transaction); 5161 if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) { 5162 uint8_t buffer[AVRC_PASS_THRU_GROUP_LEN] = {0}; 5163 uint8_t* start = buffer; 5164 UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA); 5165 *(start)++ = 0; 5166 UINT8_TO_BE_STREAM(start, key_code); 5167 BTA_AvRemoteVendorUniqueCmd(p_dev->rc_handle, p_transaction->lbl, 5168 (tBTA_AV_STATE)key_state, buffer, 5169 AVRC_PASS_THRU_GROUP_LEN); 5170 status = BT_STATUS_SUCCESS; 5171 BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA", 5172 __func__); 5173 } else { 5174 status = BT_STATUS_FAIL; 5175 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __func__); 5176 } 5177 } else { 5178 status = BT_STATUS_FAIL; 5179 BTIF_TRACE_DEBUG("%s: feature not supported", __func__); 5180 } 5181 return (bt_status_t)status; 5182 } 5183 5184 /*************************************************************************** 5185 * 5186 * Function send_passthrough_cmd 5187 * 5188 * Description Send Pass-Through command 5189 * 5190 * Returns void 5191 * 5192 **************************************************************************/ 5193 static bt_status_t send_passthrough_cmd(const RawAddress& bd_addr, 5194 uint8_t key_code, uint8_t key_state) { 5195 tAVRC_STS status = BT_STATUS_UNSUPPORTED; 5196 btif_rc_device_cb_t* p_dev = NULL; 5197 BTIF_TRACE_ERROR("%s: calling btif_rc_get_device_by_bda", __func__); 5198 p_dev = btif_rc_get_device_by_bda(bd_addr); 5199 5200 CHECK_RC_CONNECTED(p_dev); 5201 5202 rc_transaction_t* p_transaction = NULL; 5203 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __func__, key_code, 5204 key_state); 5205 if (p_dev->rc_features & BTA_AV_FEAT_RCTG) { 5206 bt_status_t tran_status = get_transaction(&p_transaction); 5207 if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction) { 5208 BTA_AvRemoteCmd(p_dev->rc_handle, p_transaction->lbl, 5209 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state); 5210 status = BT_STATUS_SUCCESS; 5211 BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", 5212 __func__); 5213 } else { 5214 status = BT_STATUS_FAIL; 5215 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __func__); 5216 } 5217 } else { 5218 status = BT_STATUS_FAIL; 5219 BTIF_TRACE_DEBUG("%s: feature not supported", __func__); 5220 } 5221 return (bt_status_t)status; 5222 } 5223 5224 static const btrc_interface_t bt_rc_interface = { 5225 sizeof(bt_rc_interface), 5226 init, 5227 get_play_status_rsp, 5228 NULL, /* list_player_app_attr_rsp */ 5229 NULL, /* list_player_app_value_rsp */ 5230 NULL, /* get_player_app_value_rsp */ 5231 NULL, /* get_player_app_attr_text_rsp */ 5232 NULL, /* get_player_app_value_text_rsp */ 5233 get_element_attr_rsp, 5234 NULL, /* set_player_app_value_rsp */ 5235 register_notification_rsp, 5236 set_volume, 5237 set_addressed_player_rsp, 5238 set_browsed_player_rsp, 5239 get_folder_items_list_rsp, 5240 change_path_rsp, 5241 get_item_attr_rsp, 5242 play_item_rsp, 5243 get_total_num_of_items_rsp, 5244 search_rsp, 5245 add_to_now_playing_rsp, 5246 cleanup, 5247 }; 5248 5249 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = { 5250 sizeof(bt_rc_ctrl_interface), 5251 init_ctrl, 5252 send_passthrough_cmd, 5253 send_groupnavigation_cmd, 5254 change_player_app_setting, 5255 play_item_cmd, 5256 get_playback_state_cmd, 5257 get_now_playing_list_cmd, 5258 get_folder_list_cmd, 5259 get_player_list_cmd, 5260 change_folder_path_cmd, 5261 set_browsed_player_cmd, 5262 set_addressed_player_cmd, 5263 set_volume_rsp, 5264 volume_change_notification_rsp, 5265 cleanup_ctrl, 5266 }; 5267 5268 /******************************************************************************* 5269 * 5270 * Function btif_rc_get_interface 5271 * 5272 * Description Get the AVRCP Target callback interface 5273 * 5274 * Returns btrc_interface_t 5275 * 5276 ******************************************************************************/ 5277 const btrc_interface_t* btif_rc_get_interface(void) { 5278 BTIF_TRACE_EVENT("%s: ", __func__); 5279 return &bt_rc_interface; 5280 } 5281 5282 /******************************************************************************* 5283 * 5284 * Function btif_rc_ctrl_get_interface 5285 * 5286 * Description Get the AVRCP Controller callback interface 5287 * 5288 * Returns btrc_ctrl_interface_t 5289 * 5290 ******************************************************************************/ 5291 const btrc_ctrl_interface_t* btif_rc_ctrl_get_interface(void) { 5292 BTIF_TRACE_EVENT("%s: ", __func__); 5293 return &bt_rc_ctrl_interface; 5294 } 5295 5296 /******************************************************************************* 5297 * Function initialize_transaction 5298 * 5299 * Description Initializes fields of the transaction structure 5300 * 5301 * Returns void 5302 ******************************************************************************/ 5303 static void initialize_transaction(int lbl) { 5304 std::unique_lock<std::recursive_mutex> lock(device.lbllock); 5305 if (lbl < MAX_TRANSACTIONS_PER_SESSION) { 5306 if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) { 5307 clear_cmd_timeout(lbl); 5308 } 5309 device.transaction[lbl].lbl = lbl; 5310 device.transaction[lbl].in_use = false; 5311 device.transaction[lbl].handle = 0; 5312 } 5313 } 5314 5315 /******************************************************************************* 5316 * Function lbl_init 5317 * 5318 * Description Initializes label structures and mutexes. 5319 * 5320 * Returns void 5321 ******************************************************************************/ 5322 void lbl_init() { 5323 memset(&device.transaction, 0, sizeof(device.transaction)); 5324 init_all_transactions(); 5325 } 5326 5327 /******************************************************************************* 5328 * 5329 * Function init_all_transactions 5330 * 5331 * Description Initializes all transactions 5332 * 5333 * Returns void 5334 ******************************************************************************/ 5335 void init_all_transactions() { 5336 uint8_t txn_indx = 0; 5337 for (txn_indx = 0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++) { 5338 initialize_transaction(txn_indx); 5339 } 5340 } 5341 5342 /******************************************************************************* 5343 * 5344 * Function get_transaction_by_lbl 5345 * 5346 * Description Will return a transaction based on the label. If not inuse 5347 * will return an error. 5348 * 5349 * Returns bt_status_t 5350 ******************************************************************************/ 5351 rc_transaction_t* get_transaction_by_lbl(uint8_t lbl) { 5352 rc_transaction_t* transaction = NULL; 5353 std::unique_lock<std::recursive_mutex> lock(device.lbllock); 5354 5355 /* Determine if this is a valid label */ 5356 if (lbl < MAX_TRANSACTIONS_PER_SESSION) { 5357 if (!device.transaction[lbl].in_use) { 5358 transaction = NULL; 5359 } else { 5360 transaction = &(device.transaction[lbl]); 5361 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d", __func__, lbl); 5362 } 5363 } 5364 5365 return transaction; 5366 } 5367 5368 /******************************************************************************* 5369 * 5370 * Function get_transaction 5371 * 5372 * Description Obtains the transaction details. 5373 * 5374 * Returns bt_status_t 5375 ******************************************************************************/ 5376 5377 static bt_status_t get_transaction(rc_transaction_t** ptransaction) { 5378 std::unique_lock<std::recursive_mutex> lock(device.lbllock); 5379 5380 // Check for unused transactions 5381 for (uint8_t i = 0; i < MAX_TRANSACTIONS_PER_SESSION; i++) { 5382 if (!device.transaction[i].in_use) { 5383 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d", __func__, 5384 device.transaction[i].lbl); 5385 device.transaction[i].in_use = true; 5386 *ptransaction = &(device.transaction[i]); 5387 return BT_STATUS_SUCCESS; 5388 } 5389 } 5390 return BT_STATUS_NOMEM; 5391 } 5392 5393 /******************************************************************************* 5394 * 5395 * Function release_transaction 5396 * 5397 * Description Will release a transaction for reuse 5398 * 5399 * Returns bt_status_t 5400 ******************************************************************************/ 5401 void release_transaction(uint8_t lbl) { 5402 BTIF_TRACE_DEBUG("%s %d", __func__, lbl); 5403 rc_transaction_t* transaction = get_transaction_by_lbl(lbl); 5404 5405 /* If the transaction is in use... */ 5406 if (transaction != NULL) { 5407 BTIF_TRACE_DEBUG("%s: lbl: %d", __func__, lbl); 5408 initialize_transaction(lbl); 5409 } 5410 } 5411 5412 /******************************************************************************* 5413 * Function sleep_ms 5414 * 5415 * Description Sleep the calling thread unconditionally for 5416 * |timeout_ms| milliseconds. 5417 * 5418 * Returns void 5419 ******************************************************************************/ 5420 static void sleep_ms(period_ms_t timeout_ms) { 5421 struct timespec delay; 5422 delay.tv_sec = timeout_ms / 1000; 5423 delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000); 5424 5425 OSI_NO_INTR(nanosleep(&delay, &delay)); 5426 } 5427 5428 static bool absolute_volume_disabled() { 5429 char volume_disabled[PROPERTY_VALUE_MAX] = {0}; 5430 osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false"); 5431 if (strncmp(volume_disabled, "true", 4) == 0) { 5432 BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__); 5433 return true; 5434 } 5435 return false; 5436 } 5437