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