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