Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 
     20 /*****************************************************************************
     21  *
     22  *  Filename:      btif_rc.c
     23  *
     24  *  Description:   Bluetooth AVRC implementation
     25  *
     26  *****************************************************************************/
     27 #include <hardware/bluetooth.h>
     28 #include <fcntl.h>
     29 #include "bta_api.h"
     30 #include "bta_av_api.h"
     31 #include "avrc_defs.h"
     32 #include "bd.h"
     33 #include "gki.h"
     34 
     35 #define LOG_TAG "BTIF_RC"
     36 #include "btif_common.h"
     37 #include "btif_util.h"
     38 #include "btif_av.h"
     39 #include "hardware/bt_rc.h"
     40 #include "uinput.h"
     41 
     42 /*****************************************************************************
     43 **  Constants & Macros
     44 ******************************************************************************/
     45 
     46 /* cod value for Headsets */
     47 #define COD_AV_HEADSETS        0x0404
     48 /* for AVRC 1.4 need to change this */
     49 #define MAX_RC_NOTIFICATIONS AVRC_EVT_APP_SETTING_CHANGE
     50 
     51 #define IDX_GET_PLAY_STATUS_RSP   0
     52 #define IDX_LIST_APP_ATTR_RSP     1
     53 #define IDX_LIST_APP_VALUE_RSP    2
     54 #define IDX_GET_CURR_APP_VAL_RSP  3
     55 #define IDX_SET_APP_VAL_RSP       4
     56 #define IDX_GET_APP_ATTR_TXT_RSP  5
     57 #define IDX_GET_APP_VAL_TXT_RSP   6
     58 #define IDX_GET_ELEMENT_ATTR_RSP  7
     59 #define MAX_VOLUME 128
     60 #define MAX_LABEL 16
     61 #define MAX_TRANSACTIONS_PER_SESSION 16
     62 #define MAX_CMD_QUEUE_LEN 8
     63 
     64 #define CHECK_RC_CONNECTED                                                                  \
     65     BTIF_TRACE_DEBUG1("## %s ##", __FUNCTION__);                                            \
     66     if(btif_rc_cb.rc_connected == FALSE)                                                    \
     67     {                                                                                       \
     68         BTIF_TRACE_WARNING1("Function %s() called when RC is not connected", __FUNCTION__); \
     69         return BT_STATUS_NOT_READY;                                                         \
     70     }
     71 
     72 #define FILL_PDU_QUEUE(index, ctype, label, pending)        \
     73 {                                                           \
     74     btif_rc_cb.rc_pdu_info[index].ctype = ctype;            \
     75     btif_rc_cb.rc_pdu_info[index].label = label;            \
     76     btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \
     77 }
     78 
     79 #define SEND_METAMSG_RSP(index, avrc_rsp)                                                      \
     80 {                                                                                              \
     81     if(btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE)                                  \
     82     {                                                                                          \
     83         BTIF_TRACE_WARNING1("%s Not sending response as no PDU was registered", __FUNCTION__); \
     84         return BT_STATUS_UNHANDLED;                                                            \
     85     }                                                                                          \
     86     send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label,                \
     87         btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp);                                        \
     88     btif_rc_cb.rc_pdu_info[index].ctype = 0;                                                   \
     89     btif_rc_cb.rc_pdu_info[index].label = 0;                                                   \
     90     btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE;                                      \
     91 }
     92 
     93 /*****************************************************************************
     94 **  Local type definitions
     95 ******************************************************************************/
     96 typedef struct {
     97     UINT8 bNotify;
     98     UINT8 label;
     99 } btif_rc_reg_notifications_t;
    100 
    101 typedef struct
    102 {
    103     UINT8   label;
    104     UINT8   ctype;
    105     BOOLEAN is_rsp_pending;
    106 } btif_rc_cmd_ctxt_t;
    107 
    108 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
    109 typedef struct {
    110     BOOLEAN                     rc_connected;
    111     UINT8                       rc_handle;
    112     tBTA_AV_FEAT                rc_features;
    113     BD_ADDR                     rc_addr;
    114     UINT16                      rc_pending_play;
    115     btif_rc_cmd_ctxt_t          rc_pdu_info[MAX_CMD_QUEUE_LEN];
    116     btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
    117     unsigned int                rc_volume;
    118     uint8_t                     rc_vol_label;
    119 } btif_rc_cb_t;
    120 
    121 typedef struct {
    122     BOOLEAN in_use;
    123     UINT8 lbl;
    124     UINT8 handle;
    125 } rc_transaction_t;
    126 
    127 typedef struct
    128 {
    129     pthread_mutex_t lbllock;
    130     rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
    131 } rc_device_t;
    132 
    133 
    134 rc_device_t device;
    135 
    136 #define MAX_UINPUT_PATHS 3
    137 static const char* uinput_dev_path[] =
    138                        {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
    139 static int uinput_fd = -1;
    140 
    141 static int  send_event (int fd, uint16_t type, uint16_t code, int32_t value);
    142 static void send_key (int fd, uint16_t key, int pressed);
    143 static int  uinput_driver_check();
    144 static int  uinput_create(char *name);
    145 static int  init_uinput (void);
    146 static void close_uinput (void);
    147 static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev);
    148 
    149 static const struct {
    150     const char *name;
    151     uint8_t avrcp;
    152     uint16_t mapped_id;
    153     uint8_t release_quirk;
    154 } key_map[] = {
    155     { "PLAY",         AVRC_ID_PLAY,     KEY_PLAYCD,       1 },
    156     { "STOP",         AVRC_ID_STOP,     KEY_STOPCD,       0 },
    157     { "PAUSE",        AVRC_ID_PAUSE,    KEY_PAUSECD,      1 },
    158     { "FORWARD",      AVRC_ID_FORWARD,  KEY_NEXTSONG,     0 },
    159     { "BACKWARD",     AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
    160     { "REWIND",       AVRC_ID_REWIND,   KEY_REWIND,       0 },
    161     { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
    162     { NULL,           0,                0,                0 }
    163 };
    164 
    165 /* the rc_black_addr_prefix and rc_white_addr_prefix are used to correct
    166  * IOP issues of absolute volume feature
    167  * We encoutered A2DP headsets/carkits advertising absolute volume but buggy.
    168  * We would like to blacklist those devices.
    169  * But we donot have a full list of the bad devices. So as a temp fix, we
    170  * are blacklisting all the devices except the devices we have well tested,
    171  * the ones in the whitelist.
    172  *
    173  * For now, only the rc_white_addr_prefix is used in the code while
    174  * rc_black_addr_prefix is kept here for future long term solution.
    175  */
    176 static const UINT8 rc_black_addr_prefix[][3] = {
    177     {0x0, 0x18, 0x6B}, // LG HBS-730
    178     {0x0, 0x26, 0x7E}  // VW Passat
    179 };
    180 
    181 static const UINT8 rc_white_addr_prefix[][3] = {
    182     {0x94, 0xCE, 0x2C}, // Sony SBH50
    183     {0x30, 0x17, 0xC8}  // Sony wm600
    184 };
    185 
    186 static void send_reject_response (UINT8 rc_handle, UINT8 label,
    187     UINT8 pdu, UINT8 status);
    188 static UINT8 opcode_from_pdu(UINT8 pdu);
    189 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
    190     tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
    191 static void register_volumechange(UINT8 label);
    192 static void lbl_init();
    193 static void lbl_destroy();
    194 static void init_all_transactions();
    195 static bt_status_t  get_transaction(rc_transaction_t **ptransaction);
    196 static void release_transaction(UINT8 label);
    197 static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
    198 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
    199 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
    200 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
    201 
    202 /*****************************************************************************
    203 **  Static variables
    204 ******************************************************************************/
    205 static btif_rc_cb_t btif_rc_cb;
    206 static btrc_callbacks_t *bt_rc_callbacks = NULL;
    207 
    208 /*****************************************************************************
    209 **  Static functions
    210 ******************************************************************************/
    211 
    212 /*****************************************************************************
    213 **  Externs
    214 ******************************************************************************/
    215 extern BOOLEAN btif_hf_call_terminated_recently();
    216 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
    217 
    218 
    219 /*****************************************************************************
    220 **  Functions
    221 ******************************************************************************/
    222 
    223 /*****************************************************************************
    224 **   Local uinput helper functions
    225 ******************************************************************************/
    226 int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
    227 {
    228     struct uinput_event event;
    229     BTIF_TRACE_DEBUG4("%s type:%u code:%u value:%d", __FUNCTION__,
    230         type, code, value);
    231     memset(&event, 0, sizeof(event));
    232     event.type  = type;
    233     event.code  = code;
    234     event.value = value;
    235 
    236     return write(fd, &event, sizeof(event));
    237 }
    238 
    239 void send_key (int fd, uint16_t key, int pressed)
    240 {
    241     BTIF_TRACE_DEBUG4("%s fd:%d key:%u pressed:%d", __FUNCTION__,
    242         fd, key, pressed);
    243 
    244     if (fd < 0)
    245     {
    246         return;
    247     }
    248 
    249     BTIF_TRACE_DEBUG3("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
    250     send_event(fd, EV_KEY, key, pressed);
    251     send_event(fd, EV_SYN, SYN_REPORT, 0);
    252 }
    253 
    254 /************** uinput related functions **************/
    255 int uinput_driver_check()
    256 {
    257     uint32_t i;
    258     for (i=0; i < MAX_UINPUT_PATHS; i++)
    259     {
    260         if (access(uinput_dev_path[i], O_RDWR) == 0) {
    261            return 0;
    262         }
    263     }
    264     BTIF_TRACE_ERROR1("%s ERROR: uinput device is not in the system", __FUNCTION__);
    265     return -1;
    266 }
    267 
    268 int uinput_create(char *name)
    269 {
    270     struct uinput_dev dev;
    271     int fd, err, x = 0;
    272 
    273     for(x=0; x < MAX_UINPUT_PATHS; x++)
    274     {
    275         fd = open(uinput_dev_path[x], O_RDWR);
    276         if (fd < 0)
    277             continue;
    278         break;
    279     }
    280     if (x == MAX_UINPUT_PATHS) {
    281         BTIF_TRACE_ERROR1("%s ERROR: uinput device open failed", __FUNCTION__);
    282         return -1;
    283     }
    284     memset(&dev, 0, sizeof(dev));
    285     if (name)
    286         strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE);
    287 
    288     dev.id.bustype = BUS_BLUETOOTH;
    289     dev.id.vendor  = 0x0000;
    290     dev.id.product = 0x0000;
    291     dev.id.version = 0x0000;
    292 
    293     if (write(fd, &dev, sizeof(dev)) < 0) {
    294         BTIF_TRACE_ERROR1("%s Unable to write device information", __FUNCTION__);
    295         close(fd);
    296         return -1;
    297     }
    298 
    299     ioctl(fd, UI_SET_EVBIT, EV_KEY);
    300     ioctl(fd, UI_SET_EVBIT, EV_REL);
    301     ioctl(fd, UI_SET_EVBIT, EV_SYN);
    302 
    303     for (x = 0; key_map[x].name != NULL; x++)
    304         ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
    305 
    306     for(x = 0; x < KEY_MAX; x++)
    307         ioctl(fd, UI_SET_KEYBIT, x);
    308 
    309     if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
    310         BTIF_TRACE_ERROR1("%s Unable to create uinput device", __FUNCTION__);
    311         close(fd);
    312         return -1;
    313     }
    314     return fd;
    315 }
    316 
    317 int init_uinput (void)
    318 {
    319     char *name = "AVRCP";
    320 
    321     BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
    322     uinput_fd = uinput_create(name);
    323     if (uinput_fd < 0) {
    324         BTIF_TRACE_ERROR3("%s AVRCP: Failed to initialize uinput for %s (%d)",
    325                           __FUNCTION__, name, uinput_fd);
    326     } else {
    327         BTIF_TRACE_DEBUG3("%s AVRCP: Initialized uinput for %s (fd=%d)",
    328                           __FUNCTION__, name, uinput_fd);
    329     }
    330     return uinput_fd;
    331 }
    332 
    333 void close_uinput (void)
    334 {
    335     BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
    336     if (uinput_fd > 0) {
    337         ioctl(uinput_fd, UI_DEV_DESTROY);
    338 
    339         close(uinput_fd);
    340         uinput_fd = -1;
    341     }
    342 }
    343 
    344 void handle_rc_features()
    345 {
    346     btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
    347     bt_bdaddr_t rc_addr;
    348     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
    349 
    350     if (dev_blacklisted_for_absolute_volume(btif_rc_cb.rc_addr))
    351     {
    352         btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
    353     }
    354 
    355     if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
    356     {
    357         rc_features |= BTRC_FEAT_BROWSE;
    358     }
    359     if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
    360          (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
    361     {
    362         rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
    363     }
    364     if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
    365     {
    366         rc_features |= BTRC_FEAT_METADATA;
    367     }
    368     BTIF_TRACE_DEBUG2("%s: rc_features=0x%x", __FUNCTION__, rc_features);
    369     HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
    370 
    371 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
    372      BTIF_TRACE_DEBUG1("Checking for feature flags in btif_rc_handler with label %d",
    373                         btif_rc_cb.rc_vol_label);
    374      // Register for volume change on connect
    375       if(btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
    376          btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
    377       {
    378          rc_transaction_t *p_transaction=NULL;
    379          bt_status_t status = BT_STATUS_NOT_READY;
    380          if(MAX_LABEL==btif_rc_cb.rc_vol_label)
    381          {
    382             status=get_transaction(&p_transaction);
    383          }
    384          else
    385          {
    386             p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
    387             if(NULL!=p_transaction)
    388             {
    389                BTIF_TRACE_DEBUG1("register_volumechange already in progress for label %d",
    390                                   btif_rc_cb.rc_vol_label);
    391                return;
    392             }
    393             else
    394               status=get_transaction(&p_transaction);
    395          }
    396 
    397          if(BT_STATUS_SUCCESS == status && NULL!=p_transaction)
    398          {
    399             btif_rc_cb.rc_vol_label=p_transaction->lbl;
    400             register_volumechange(btif_rc_cb.rc_vol_label);
    401          }
    402        }
    403 #endif
    404 }
    405 
    406 
    407 /***************************************************************************
    408  *  Function       handle_rc_connect
    409  *
    410  *  - Argument:    tBTA_AV_RC_OPEN  RC open data structure
    411  *
    412  *  - Description: RC connection event handler
    413  *
    414  ***************************************************************************/
    415 void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
    416 {
    417     BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
    418     bt_status_t result = BT_STATUS_SUCCESS;
    419     int i;
    420     char bd_str[18];
    421 
    422     if(p_rc_open->status == BTA_AV_SUCCESS)
    423     {
    424         memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
    425         btif_rc_cb.rc_features = p_rc_open->peer_features;
    426         btif_rc_cb.rc_vol_label=MAX_LABEL;
    427         btif_rc_cb.rc_volume=MAX_VOLUME;
    428 
    429         btif_rc_cb.rc_connected = TRUE;
    430         btif_rc_cb.rc_handle = p_rc_open->rc_handle;
    431 
    432         /* on locally initiated connection we will get remote features as part of connect */
    433         if (btif_rc_cb.rc_features != 0)
    434             handle_rc_features();
    435 
    436         result = uinput_driver_check();
    437         if(result == BT_STATUS_SUCCESS)
    438         {
    439             init_uinput();
    440         }
    441     }
    442     else
    443     {
    444         BTIF_TRACE_ERROR2("%s Connect failed with error code: %d",
    445             __FUNCTION__, p_rc_open->status);
    446         btif_rc_cb.rc_connected = FALSE;
    447     }
    448 }
    449 
    450 /***************************************************************************
    451  *  Function       handle_rc_disconnect
    452  *
    453  *  - Argument:    tBTA_AV_RC_CLOSE     RC close data structure
    454  *
    455  *  - Description: RC disconnection event handler
    456  *
    457  ***************************************************************************/
    458 void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
    459 {
    460     BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
    461 
    462     btif_rc_cb.rc_handle = 0;
    463     btif_rc_cb.rc_connected = FALSE;
    464     memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
    465     btif_rc_cb.rc_features = 0;
    466     btif_rc_cb.rc_vol_label=MAX_LABEL;
    467     btif_rc_cb.rc_volume=MAX_VOLUME;
    468     init_all_transactions();
    469     close_uinput();
    470 }
    471 
    472 /***************************************************************************
    473  *  Function       handle_rc_passthrough_cmd
    474  *
    475  *  - Argument:    tBTA_AV_RC rc_id   remote control command ID
    476  *                 tBTA_AV_STATE key_state status of key press
    477  *
    478  *  - Description: Remote control command handler
    479  *
    480  ***************************************************************************/
    481 void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
    482 {
    483     const char *status;
    484     int pressed, i;
    485 
    486     BTIF_TRACE_DEBUG2("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
    487 
    488     /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
    489     if (p_remote_cmd)
    490     {
    491         /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
    492         if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
    493         {
    494             if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
    495             {
    496                 APPL_TRACE_WARNING1("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
    497                 btif_rc_cb.rc_pending_play = TRUE;
    498             }
    499             return;
    500         }
    501 
    502         if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
    503         {
    504             APPL_TRACE_WARNING1("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
    505             btif_rc_cb.rc_pending_play = FALSE;
    506             return;
    507         }
    508     }
    509     if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
    510         status = "released";
    511         pressed = 0;
    512     } else {
    513         status = "pressed";
    514         pressed = 1;
    515     }
    516 
    517     /* If this is Play/Pause command (press or release)  before processing, check the following
    518      * a voice call has ended recently
    519      * the remote device is not of type headset
    520      * If the above conditions meet, drop the Play/Pause command
    521      * This fix is to interop with certain carkits which sends an automatic  PLAY  or PAUSE
    522      * commands right after call ends
    523      */
    524     if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&&
    525        (btif_hf_call_terminated_recently() == TRUE) &&
    526        (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE))
    527     {
    528         BTIF_TRACE_DEBUG2("%s:Dropping the play/Pause command received right after call end cmd:%d",
    529                            __FUNCTION__,p_remote_cmd->rc_id);
    530         return;
    531     }
    532 
    533     if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
    534         HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
    535         return;
    536     }
    537 
    538     for (i = 0; key_map[i].name != NULL; i++) {
    539         if (p_remote_cmd->rc_id == key_map[i].avrcp) {
    540             BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status);
    541 
    542            /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
    543             * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
    544             * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
    545             * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
    546             * The fix is to generate a release right after the press and drown the 'actual'
    547             * release.
    548             */
    549             if ((key_map[i].release_quirk == 1) && (pressed == 0))
    550             {
    551                 BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now",
    552                                   __FUNCTION__, key_map[i].name);
    553                 return;
    554             }
    555             send_key(uinput_fd, key_map[i].mapped_id, pressed);
    556             if ((key_map[i].release_quirk == 1) && (pressed == 1))
    557             {
    558                 GKI_delay(30); // 30ms
    559                 BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now",
    560                                   __FUNCTION__, key_map[i].name);
    561                 send_key(uinput_fd, key_map[i].mapped_id, 0);
    562             }
    563             break;
    564         }
    565     }
    566 
    567     if (key_map[i].name == NULL)
    568         BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
    569                         p_remote_cmd->rc_id, status);
    570 }
    571 
    572 void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
    573 {
    574     tAVRC_RESPONSE avrc_rsp = {0};
    575     avrc_rsp.rsp.pdu = pavrc_command->pdu;
    576     avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
    577     avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
    578 
    579     avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
    580     avrc_rsp.reg_notif.param.uid_counter = 0;
    581 
    582     send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
    583     send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
    584 
    585 }
    586 
    587 
    588 /***************************************************************************
    589  *  Function       handle_rc_metamsg_cmd
    590  *
    591  *  - Argument:    tBTA_AV_VENDOR Structure containing the received
    592  *                          metamsg command
    593  *
    594  *  - Description: Remote control metamsg command handler (AVRCP 1.3)
    595  *
    596  ***************************************************************************/
    597 void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
    598 {
    599     /* Parse the metamsg command and pass it on to BTL-IFS */
    600     UINT8             scratch_buf[512] = {0};
    601     tAVRC_COMMAND    avrc_command = {0};
    602     tAVRC_STS status;
    603     int param_len;
    604 
    605     BTIF_TRACE_EVENT1("+ %s", __FUNCTION__);
    606 
    607     if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
    608     {
    609         BTIF_TRACE_WARNING1("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
    610         return;
    611     }
    612     if (pmeta_msg->len < 3)
    613     {
    614         BTIF_TRACE_WARNING2("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
    615             pmeta_msg->len);
    616         return;
    617     }
    618 
    619     if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
    620     {
    621 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
    622 {
    623      rc_transaction_t *transaction=NULL;
    624      transaction=get_transaction_by_lbl(pmeta_msg->label);
    625      if(NULL!=transaction)
    626      {
    627         handle_rc_metamsg_rsp(pmeta_msg);
    628      }
    629      else
    630      {
    631          BTIF_TRACE_DEBUG3("%s:Discard vendor dependent rsp. code: %d label:%d.",
    632              __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
    633      }
    634      return;
    635 }
    636 #else
    637 {
    638         BTIF_TRACE_DEBUG3("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
    639             __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
    640         return;
    641 }
    642 #endif
    643       }
    644 
    645     status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
    646     BTIF_TRACE_DEBUG3("Received vendor command.code,PDU and label: %d, %d,%d",pmeta_msg->code,
    647                        avrc_command.cmd.pdu, pmeta_msg->label);
    648 
    649     if (status != AVRC_STS_NO_ERROR)
    650     {
    651         /* return error */
    652         BTIF_TRACE_WARNING2("%s: Error in parsing received metamsg command. status: 0x%02x",
    653             __FUNCTION__, status);
    654         send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
    655     }
    656     else
    657     {
    658         /* if RegisterNotification, add it to our registered queue */
    659 
    660         if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
    661         {
    662             UINT8 event_id = avrc_command.reg_notif.event_id;
    663             param_len = sizeof(tAVRC_REG_NOTIF_CMD);
    664             BTIF_TRACE_EVENT4("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
    665             __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
    666             btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
    667             btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
    668 
    669             if(event_id == AVRC_EVT_UIDS_CHANGE)
    670             {
    671                 handle_uid_changed_notification(pmeta_msg, &avrc_command);
    672                 return;
    673             }
    674 
    675         }
    676 
    677         BTIF_TRACE_EVENT2("%s: Passing received metamsg command to app. pdu: %s",
    678             __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
    679 
    680         /* Since handle_rc_metamsg_cmd() itself is called from
    681             *btif context, no context switching is required. Invoke
    682             * btif_rc_upstreams_evt directly from here. */
    683         btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
    684                                pmeta_msg->label);
    685     }
    686 }
    687 
    688 /***************************************************************************
    689  **
    690  ** Function       btif_rc_handler
    691  **
    692  ** Description    RC event handler
    693  **
    694  ***************************************************************************/
    695 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
    696 {
    697     BTIF_TRACE_DEBUG2 ("%s event:%s", __FUNCTION__, dump_rc_event(event));
    698     switch (event)
    699     {
    700         case BTA_AV_RC_OPEN_EVT:
    701         {
    702             BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_open.peer_features);
    703             handle_rc_connect( &(p_data->rc_open) );
    704         }break;
    705 
    706         case BTA_AV_RC_CLOSE_EVT:
    707         {
    708             handle_rc_disconnect( &(p_data->rc_close) );
    709         }break;
    710 
    711         case BTA_AV_REMOTE_CMD_EVT:
    712         {
    713             BTIF_TRACE_DEBUG2("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id,
    714                                p_data->remote_cmd.key_state);
    715             handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
    716         }
    717         break;
    718         case BTA_AV_RC_FEAT_EVT:
    719         {
    720             BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_feat.peer_features);
    721             btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
    722             handle_rc_features();
    723         }
    724         break;
    725         case BTA_AV_META_MSG_EVT:
    726         {
    727             BTIF_TRACE_DEBUG2("BTA_AV_META_MSG_EVT  code:%d label:%d", p_data->meta_msg.code,
    728                 p_data->meta_msg.label);
    729             BTIF_TRACE_DEBUG3("  company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id,
    730                 p_data->meta_msg.len, p_data->meta_msg.rc_handle);
    731             /* handle the metamsg command */
    732             handle_rc_metamsg_cmd(&(p_data->meta_msg));
    733         }
    734         break;
    735         default:
    736             BTIF_TRACE_DEBUG1("Unhandled RC event : 0x%x", event);
    737     }
    738 }
    739 
    740 /***************************************************************************
    741  **
    742  ** Function       btif_rc_get_connected_peer
    743  **
    744  ** Description    Fetches the connected headset's BD_ADDR if any
    745  **
    746  ***************************************************************************/
    747 BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
    748 {
    749     if (btif_rc_cb.rc_connected == TRUE) {
    750         bdcpy(peer_addr, btif_rc_cb.rc_addr);
    751         return TRUE;
    752     }
    753     return FALSE;
    754 }
    755 
    756 /***************************************************************************
    757  **
    758  ** Function       btif_rc_check_handle_pending_play
    759  **
    760  ** Description    Clears the queued PLAY command. if bSend is TRUE, forwards to app
    761  **
    762  ***************************************************************************/
    763 
    764 /* clear the queued PLAY command. if bSend is TRUE, forward to app */
    765 void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
    766 {
    767     BTIF_TRACE_DEBUG2("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
    768     if (btif_rc_cb.rc_pending_play)
    769     {
    770         if (bSendToApp)
    771         {
    772             tBTA_AV_REMOTE_CMD remote_cmd;
    773             APPL_TRACE_DEBUG1("%s: Sending queued PLAYED event to app", __FUNCTION__);
    774 
    775             memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
    776             remote_cmd.rc_handle  = btif_rc_cb.rc_handle;
    777             remote_cmd.rc_id      = AVRC_ID_PLAY;
    778             remote_cmd.hdr.ctype  = AVRC_CMD_CTRL;
    779             remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
    780 
    781             /* delay sending to app, else there is a timing issue in the framework,
    782              ** which causes the audio to be on th device's speaker. Delay between
    783              ** OPEN & RC_PLAYs
    784             */
    785             GKI_delay (200);
    786             /* send to app - both PRESSED & RELEASED */
    787             remote_cmd.key_state  = AVRC_STATE_PRESS;
    788             handle_rc_passthrough_cmd( &remote_cmd );
    789 
    790             GKI_delay (100);
    791 
    792             remote_cmd.key_state  = AVRC_STATE_RELEASE;
    793             handle_rc_passthrough_cmd( &remote_cmd );
    794         }
    795         btif_rc_cb.rc_pending_play = FALSE;
    796     }
    797 }
    798 
    799 /* Generic reject response */
    800 static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
    801 {
    802     UINT8 ctype = AVRC_RSP_REJ;
    803     tAVRC_RESPONSE avrc_rsp;
    804     BT_HDR *p_msg = NULL;
    805     memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
    806 
    807     avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
    808     avrc_rsp.rsp.pdu    = pdu;
    809     avrc_rsp.rsp.status = status;
    810 
    811     if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
    812     {
    813         BTIF_TRACE_DEBUG4("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
    814             __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
    815         BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
    816     }
    817 }
    818 
    819 /***************************************************************************
    820  *  Function       send_metamsg_rsp
    821  *
    822  *  - Argument:
    823  *                  rc_handle     RC handle corresponding to the connected RC
    824  *                  label            Label of the RC response
    825  *                  code            Response type
    826  *                  pmetamsg_resp    Vendor response
    827  *
    828  *  - Description: Remote control metamsg response handler (AVRCP 1.3)
    829  *
    830  ***************************************************************************/
    831 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
    832     tAVRC_RESPONSE *pmetamsg_resp)
    833 {
    834     UINT8 ctype;
    835     tAVRC_STS status;
    836 
    837     if (!pmetamsg_resp)
    838     {
    839         BTIF_TRACE_WARNING1("%s: Invalid response received from application", __FUNCTION__);
    840         return;
    841     }
    842 
    843     BTIF_TRACE_EVENT5("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
    844         rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
    845 
    846     if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
    847     {
    848         ctype = AVRC_RSP_REJ;
    849     }
    850     else
    851     {
    852         if ( code < AVRC_RSP_NOT_IMPL)
    853         {
    854             if (code == AVRC_CMD_NOTIF)
    855             {
    856                ctype = AVRC_RSP_INTERIM;
    857             }
    858             else if (code == AVRC_CMD_STATUS)
    859             {
    860                ctype = AVRC_RSP_IMPL_STBL;
    861             }
    862             else
    863             {
    864                ctype = AVRC_RSP_ACCEPT;
    865             }
    866         }
    867         else
    868         {
    869             ctype = code;
    870         }
    871     }
    872     /* if response is for register_notification, make sure the rc has
    873     actually registered for this */
    874     if((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
    875     {
    876         BOOLEAN bSent = FALSE;
    877         UINT8   event_id = pmetamsg_resp->reg_notif.event_id;
    878         BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
    879 
    880         /* de-register this notification for a CHANGED response */
    881         btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
    882         BTIF_TRACE_DEBUG4("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
    883              btif_rc_cb.rc_handle, event_id, bNotify);
    884         if (bNotify)
    885         {
    886             BT_HDR *p_msg = NULL;
    887             tAVRC_STS status;
    888 
    889             if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
    890                 pmetamsg_resp, &p_msg)) )
    891             {
    892                 BTIF_TRACE_DEBUG3("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
    893                      __FUNCTION__, btif_rc_cb.rc_handle, event_id);
    894                 bSent = TRUE;
    895                 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
    896                     ctype, p_msg);
    897             }
    898             else
    899             {
    900                 BTIF_TRACE_WARNING2("%s failed to build metamsg response. status: 0x%02x",
    901                     __FUNCTION__, status);
    902             }
    903 
    904         }
    905 
    906         if (!bSent)
    907         {
    908             BTIF_TRACE_DEBUG2("%s: Notification not sent, as there are no RC connections or the \
    909                 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
    910         }
    911     }
    912     else
    913     {
    914         /* All other commands go here */
    915 
    916         BT_HDR *p_msg = NULL;
    917         tAVRC_STS status;
    918 
    919         status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
    920 
    921         if (status == AVRC_STS_NO_ERROR)
    922         {
    923             BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
    924         }
    925         else
    926         {
    927             BTIF_TRACE_ERROR2("%s: failed to build metamsg response. status: 0x%02x",
    928                 __FUNCTION__, status);
    929         }
    930     }
    931 }
    932 
    933 static UINT8 opcode_from_pdu(UINT8 pdu)
    934 {
    935     UINT8 opcode = 0;
    936 
    937     switch (pdu)
    938     {
    939     case AVRC_PDU_NEXT_GROUP:
    940     case AVRC_PDU_PREV_GROUP: /* pass thru */
    941         opcode  = AVRC_OP_PASS_THRU;
    942         break;
    943 
    944     default: /* vendor */
    945         opcode  = AVRC_OP_VENDOR;
    946         break;
    947     }
    948 
    949     return opcode;
    950 }
    951 
    952 /*******************************************************************************
    953 **
    954 ** Function         btif_rc_upstreams_evt
    955 **
    956 ** Description      Executes AVRC UPSTREAMS events in btif context.
    957 **
    958 ** Returns          void
    959 **
    960 *******************************************************************************/
    961 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
    962 {
    963     BTIF_TRACE_EVENT5("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
    964         dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
    965 
    966     switch (event)
    967     {
    968         case AVRC_PDU_GET_PLAY_STATUS:
    969         {
    970             FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
    971             HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
    972         }
    973         break;
    974         case AVRC_PDU_LIST_PLAYER_APP_ATTR:
    975         case AVRC_PDU_LIST_PLAYER_APP_VALUES:
    976         case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
    977         case AVRC_PDU_SET_PLAYER_APP_VALUE:
    978         case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
    979         case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
    980         {
    981             /* TODO: Add support for Application Settings */
    982             send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
    983         }
    984         break;
    985         case AVRC_PDU_GET_ELEMENT_ATTR:
    986         {
    987             btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
    988             UINT8 num_attr;
    989              memset(&element_attrs, 0, sizeof(element_attrs));
    990             if (pavrc_cmd->get_elem_attrs.num_attr == 0)
    991             {
    992                 /* CT requests for all attributes */
    993                 int attr_cnt;
    994                 num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
    995                 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
    996                 {
    997                     element_attrs[attr_cnt] = attr_cnt + 1;
    998                 }
    999             }
   1000             else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
   1001             {
   1002                 /* 0xff indicates, no attributes requested - reject */
   1003                 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
   1004                     AVRC_STS_BAD_PARAM);
   1005                 return;
   1006             }
   1007             else
   1008             {
   1009                 num_attr = pavrc_cmd->get_elem_attrs.num_attr;
   1010                 memcpy(element_attrs, pavrc_cmd->get_elem_attrs.attrs, sizeof(UINT32)
   1011                     *pavrc_cmd->get_elem_attrs.num_attr);
   1012             }
   1013             FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
   1014             HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
   1015         }
   1016         break;
   1017         case AVRC_PDU_REGISTER_NOTIFICATION:
   1018         {
   1019             if(pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
   1020                 pavrc_cmd->reg_notif.param == 0)
   1021             {
   1022                 BTIF_TRACE_WARNING1("%s Device registering position changed with illegal param 0.",
   1023                     __FUNCTION__);
   1024                 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
   1025                 /* de-register this notification for a rejected response */
   1026                 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
   1027                 return;
   1028             }
   1029             HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
   1030                 pavrc_cmd->reg_notif.param);
   1031         }
   1032         break;
   1033         case AVRC_PDU_INFORM_DISPLAY_CHARSET:
   1034         {
   1035             tAVRC_RESPONSE avrc_rsp;
   1036             BTIF_TRACE_EVENT1("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
   1037             if(btif_rc_cb.rc_connected == TRUE)
   1038             {
   1039                 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
   1040                 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
   1041                 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
   1042                 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
   1043                 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
   1044             }
   1045         }
   1046         break;
   1047         default:
   1048         {
   1049         send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
   1050             (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
   1051         return;
   1052         }
   1053         break;
   1054     }
   1055 
   1056 }
   1057 
   1058 
   1059 /*******************************************************************************
   1060 **
   1061 ** Function         btif_rc_upstreams_rsp_evt
   1062 **
   1063 ** Description      Executes AVRC UPSTREAMS response events in btif context.
   1064 **
   1065 ** Returns          void
   1066 **
   1067 *******************************************************************************/
   1068 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
   1069 {
   1070     BTIF_TRACE_EVENT5("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
   1071         dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
   1072 
   1073 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
   1074     switch (event)
   1075     {
   1076         case AVRC_PDU_REGISTER_NOTIFICATION:
   1077         {
   1078              if(AVRC_RSP_CHANGED==ctype)
   1079                  btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
   1080              HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
   1081         }
   1082         break;
   1083 
   1084         case AVRC_PDU_SET_ABSOLUTE_VOLUME:
   1085         {
   1086             BTIF_TRACE_DEBUG2("Set absolute volume change event received: volume %d,ctype %d",
   1087                 pavrc_resp->volume.volume,ctype);
   1088             if(AVRC_RSP_ACCEPT==ctype)
   1089                 btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
   1090             HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
   1091         }
   1092         break;
   1093 
   1094         default:
   1095             return;
   1096     }
   1097 #endif
   1098 }
   1099 
   1100 /************************************************************************************
   1101 **  AVRCP API Functions
   1102 ************************************************************************************/
   1103 
   1104 /*******************************************************************************
   1105 **
   1106 ** Function         init
   1107 **
   1108 ** Description      Initializes the AVRC interface
   1109 **
   1110 ** Returns          bt_status_t
   1111 **
   1112 *******************************************************************************/
   1113 static bt_status_t init(btrc_callbacks_t* callbacks )
   1114 {
   1115     BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__);
   1116     bt_status_t result = BT_STATUS_SUCCESS;
   1117 
   1118     if (bt_rc_callbacks)
   1119         return BT_STATUS_DONE;
   1120 
   1121     bt_rc_callbacks = callbacks;
   1122     memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
   1123     btif_rc_cb.rc_vol_label=MAX_LABEL;
   1124     btif_rc_cb.rc_volume=MAX_VOLUME;
   1125     lbl_init();
   1126 
   1127     return result;
   1128 }
   1129 
   1130 /***************************************************************************
   1131 **
   1132 ** Function         get_play_status_rsp
   1133 **
   1134 ** Description      Returns the current play status.
   1135 **                      This method is called in response to
   1136 **                      GetPlayStatus request.
   1137 **
   1138 ** Returns          bt_status_t
   1139 **
   1140 ***************************************************************************/
   1141 static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
   1142     uint32_t song_pos)
   1143 {
   1144     tAVRC_RESPONSE avrc_rsp;
   1145     UINT32 i;
   1146     CHECK_RC_CONNECTED
   1147     memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
   1148     avrc_rsp.get_play_status.song_len = song_len;
   1149     avrc_rsp.get_play_status.song_pos = song_pos;
   1150     avrc_rsp.get_play_status.play_status = play_status;
   1151 
   1152     avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
   1153     avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
   1154     avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
   1155     /* Send the response */
   1156     SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
   1157     return BT_STATUS_SUCCESS;
   1158 }
   1159 
   1160 /***************************************************************************
   1161 **
   1162 ** Function         get_element_attr_rsp
   1163 **
   1164 ** Description      Returns the current songs' element attributes
   1165 **                      in text.
   1166 **
   1167 ** Returns          bt_status_t
   1168 **
   1169 ***************************************************************************/
   1170 static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
   1171 {
   1172     tAVRC_RESPONSE avrc_rsp;
   1173     UINT32 i;
   1174     uint8_t j;
   1175     tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
   1176     CHECK_RC_CONNECTED
   1177     memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
   1178 
   1179     if (num_attr == 0)
   1180     {
   1181         avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
   1182     }
   1183     else
   1184     {
   1185         for (i=0; i<num_attr; i++) {
   1186             element_attrs[i].attr_id = p_attrs[i].attr_id;
   1187             element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
   1188             element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
   1189             element_attrs[i].name.p_str = p_attrs[i].text;
   1190             BTIF_TRACE_DEBUG5("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
   1191                 __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
   1192                 element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
   1193                 element_attrs[i].name.p_str);
   1194         }
   1195         avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
   1196     }
   1197     avrc_rsp.get_elem_attrs.num_attr = num_attr;
   1198     avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
   1199     avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
   1200     avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
   1201     /* Send the response */
   1202     SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
   1203     return BT_STATUS_SUCCESS;
   1204 }
   1205 
   1206 /***************************************************************************
   1207 **
   1208 ** Function         register_notification_rsp
   1209 **
   1210 ** Description      Response to the register notification request.
   1211 **                      in text.
   1212 **
   1213 ** Returns          bt_status_t
   1214 **
   1215 ***************************************************************************/
   1216 static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
   1217     btrc_notification_type_t type, btrc_register_notification_t *p_param)
   1218 {
   1219     tAVRC_RESPONSE avrc_rsp;
   1220     CHECK_RC_CONNECTED
   1221     BTIF_TRACE_EVENT2("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
   1222     memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
   1223     avrc_rsp.reg_notif.event_id = event_id;
   1224 
   1225     switch(event_id)
   1226     {
   1227         case BTRC_EVT_PLAY_STATUS_CHANGED:
   1228             avrc_rsp.reg_notif.param.play_status = p_param->play_status;
   1229             break;
   1230         case BTRC_EVT_TRACK_CHANGE:
   1231             memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
   1232             break;
   1233         case BTRC_EVT_PLAY_POS_CHANGED:
   1234             avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
   1235             break;
   1236         default:
   1237             BTIF_TRACE_WARNING2("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
   1238             return BT_STATUS_UNHANDLED;
   1239     }
   1240 
   1241     avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
   1242     avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
   1243     avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
   1244 
   1245     /* Send the response. */
   1246     send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
   1247         ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
   1248     return BT_STATUS_SUCCESS;
   1249 }
   1250 
   1251 /***************************************************************************
   1252 **
   1253 ** Function         set_volume
   1254 **
   1255 ** Description      Send current volume setting to remote side.
   1256 **                  Support limited to SetAbsoluteVolume
   1257 **                  This can be enhanced to support Relative Volume (AVRCP 1.0).
   1258 **                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
   1259 **                  as opposed to absolute volume level
   1260 ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
   1261 **
   1262 ** Returns          bt_status_t
   1263 **
   1264 ***************************************************************************/
   1265 static bt_status_t set_volume(uint8_t volume)
   1266 {
   1267     BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
   1268     CHECK_RC_CONNECTED
   1269     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
   1270     rc_transaction_t *p_transaction=NULL;
   1271 
   1272     if(btif_rc_cb.rc_volume==volume)
   1273     {
   1274         status=BT_STATUS_DONE;
   1275         BTIF_TRACE_ERROR2("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
   1276         return status;
   1277     }
   1278 
   1279     if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
   1280         (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
   1281     {
   1282         tAVRC_COMMAND avrc_cmd = {0};
   1283         BT_HDR *p_msg = NULL;
   1284 
   1285         BTIF_TRACE_DEBUG2("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
   1286         avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
   1287         avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
   1288         avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
   1289         avrc_cmd.volume.volume = volume;
   1290 
   1291         if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
   1292         {
   1293             bt_status_t tran_status=get_transaction(&p_transaction);
   1294             if(BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
   1295             {
   1296                 BTIF_TRACE_DEBUG2("%s msgreq being sent out with label %d",
   1297                                    __FUNCTION__,p_transaction->lbl);
   1298                 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
   1299                 status =  BT_STATUS_SUCCESS;
   1300             }
   1301             else
   1302             {
   1303                 if(NULL!=p_msg)
   1304                    GKI_freebuf(p_msg);
   1305                 BTIF_TRACE_ERROR2("%s: failed to obtain transaction details. status: 0x%02x",
   1306                                     __FUNCTION__, tran_status);
   1307                 status = BT_STATUS_FAIL;
   1308             }
   1309         }
   1310         else
   1311         {
   1312             BTIF_TRACE_ERROR2("%s: failed to build absolute volume command. status: 0x%02x",
   1313                                 __FUNCTION__, status);
   1314             status = BT_STATUS_FAIL;
   1315         }
   1316     }
   1317     else
   1318         status=BT_STATUS_NOT_READY;
   1319     return status;
   1320 }
   1321 
   1322 
   1323 /***************************************************************************
   1324 **
   1325 ** Function         register_volumechange
   1326 **
   1327 ** Description     Register for volume change notification from remote side.
   1328 **
   1329 ** Returns          void
   1330 **
   1331 ***************************************************************************/
   1332 
   1333 static void register_volumechange (UINT8 lbl)
   1334 {
   1335     tAVRC_COMMAND avrc_cmd = {0};
   1336     BT_HDR *p_msg = NULL;
   1337     tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
   1338     UINT16 rv = 0;
   1339     bt_status_t tran_status;
   1340     rc_transaction_t *p_transaction=NULL;
   1341 
   1342     BTIF_TRACE_DEBUG2("%s called with label:%d",__FUNCTION__,lbl);
   1343 
   1344     avrc_cmd.cmd.opcode=0x00;
   1345     avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
   1346     avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
   1347     avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
   1348 
   1349     BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
   1350     if(AVRC_STS_NO_ERROR==BldResp && p_msg)
   1351     {
   1352          p_transaction=get_transaction_by_lbl(lbl);
   1353          if(NULL!=p_transaction)
   1354          {
   1355              BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_NOTIF, p_msg);
   1356              BTIF_TRACE_DEBUG1("%s:BTA_AvMetaCmd called",__FUNCTION__);
   1357          }
   1358          else
   1359          {
   1360             if(NULL!=p_msg)
   1361                GKI_freebuf(p_msg);
   1362             BTIF_TRACE_ERROR2("%s transaction not obtained with label: %d",__FUNCTION__,lbl);
   1363          }
   1364     }
   1365     else
   1366         BTIF_TRACE_ERROR2("%s failed to build command:%d",__FUNCTION__,BldResp);
   1367 }
   1368 
   1369 
   1370 /***************************************************************************
   1371 **
   1372 ** Function         handle_rc_metamsg_rsp
   1373 **
   1374 ** Description      Handle RC metamessage response
   1375 **
   1376 ** Returns          void
   1377 **
   1378 ***************************************************************************/
   1379 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
   1380 {
   1381     tAVRC_RESPONSE    avrc_response = {0};
   1382     UINT8             scratch_buf[512] = {0};
   1383     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
   1384 
   1385     if(AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
   1386       || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
   1387       || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
   1388     {
   1389         status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
   1390         BTIF_TRACE_DEBUG6("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
   1391           __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
   1392           status, pmeta_msg->label);
   1393 
   1394         if (status != AVRC_STS_NO_ERROR)
   1395         {
   1396             if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
   1397                 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
   1398                 && btif_rc_cb.rc_vol_label==pmeta_msg->label)
   1399             {
   1400                 btif_rc_cb.rc_vol_label=MAX_LABEL;
   1401                 release_transaction(btif_rc_cb.rc_vol_label);
   1402             }
   1403             else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
   1404             {
   1405                 release_transaction(pmeta_msg->label);
   1406             }
   1407             return;
   1408         }
   1409         else if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
   1410             && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
   1411             && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
   1412             {
   1413                 // Just discard the message, if the device sends back with an incorrect label
   1414                 BTIF_TRACE_DEBUG3("%s:Discarding register notfn in rsp.code: %d and label %d",
   1415                 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
   1416                 return;
   1417             }
   1418     }
   1419     else
   1420     {
   1421         BTIF_TRACE_DEBUG3("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
   1422         __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
   1423         return;
   1424     }
   1425 
   1426     if(AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
   1427         && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
   1428         && AVRC_RSP_CHANGED==pmeta_msg->code)
   1429      {
   1430          /* re-register for volume change notification */
   1431          // Do not re-register for rejected case, as it might get into endless loop
   1432          register_volumechange(btif_rc_cb.rc_vol_label);
   1433      }
   1434      else if(AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
   1435      {
   1436           /* free up the label here */
   1437           release_transaction(pmeta_msg->label);
   1438      }
   1439 
   1440      BTIF_TRACE_EVENT2("%s: Passing received metamsg response to app. pdu: %s",
   1441              __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
   1442      btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
   1443                                 pmeta_msg->label);
   1444 }
   1445 
   1446 
   1447 /***************************************************************************
   1448 **
   1449 ** Function         cleanup
   1450 **
   1451 ** Description      Closes the AVRC interface
   1452 **
   1453 ** Returns          void
   1454 **
   1455 ***************************************************************************/
   1456 static void cleanup()
   1457 {
   1458     BTIF_TRACE_EVENT1("## %s ##", __FUNCTION__);
   1459     close_uinput();
   1460     if (bt_rc_callbacks)
   1461     {
   1462         bt_rc_callbacks = NULL;
   1463     }
   1464     memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
   1465     lbl_destroy();
   1466 }
   1467 
   1468 
   1469 static const btrc_interface_t bt_rc_interface = {
   1470     sizeof(bt_rc_interface),
   1471     init,
   1472     get_play_status_rsp,
   1473     NULL, /* list_player_app_attr_rsp */
   1474     NULL, /* list_player_app_value_rsp */
   1475     NULL, /* get_player_app_value_rsp */
   1476     NULL, /* get_player_app_attr_text_rsp */
   1477     NULL, /* get_player_app_value_text_rsp */
   1478     get_element_attr_rsp,
   1479     NULL, /* set_player_app_value_rsp */
   1480     register_notification_rsp,
   1481     set_volume,
   1482     cleanup,
   1483 };
   1484 
   1485 /*******************************************************************************
   1486 **
   1487 ** Function         btif_rc_get_interface
   1488 **
   1489 ** Description      Get the AVRCP callback interface
   1490 **
   1491 ** Returns          btav_interface_t
   1492 **
   1493 *******************************************************************************/
   1494 const btrc_interface_t *btif_rc_get_interface(void)
   1495 {
   1496     BTIF_TRACE_EVENT1("%s", __FUNCTION__);
   1497     return &bt_rc_interface;
   1498 }
   1499 
   1500 /*******************************************************************************
   1501 **      Function         initialize_transaction
   1502 **
   1503 **      Description    Initializes fields of the transaction structure
   1504 **
   1505 **      Returns          void
   1506 *******************************************************************************/
   1507 static void initialize_transaction(int lbl)
   1508 {
   1509     pthread_mutex_lock(&device.lbllock);
   1510     if(lbl < MAX_TRANSACTIONS_PER_SESSION)
   1511     {
   1512        device.transaction[lbl].lbl = lbl;
   1513        device.transaction[lbl].in_use=FALSE;
   1514        device.transaction[lbl].handle=0;
   1515     }
   1516     pthread_mutex_unlock(&device.lbllock);
   1517 }
   1518 
   1519 /*******************************************************************************
   1520 **      Function         lbl_init
   1521 **
   1522 **      Description    Initializes label structures and mutexes.
   1523 **
   1524 **      Returns         void
   1525 *******************************************************************************/
   1526 void lbl_init()
   1527 {
   1528     memset(&device,0,sizeof(rc_device_t));
   1529     pthread_mutexattr_t attr;
   1530     pthread_mutexattr_init(&attr);
   1531     pthread_mutex_init(&(device.lbllock), &attr);
   1532     pthread_mutexattr_destroy(&attr);
   1533     init_all_transactions();
   1534 }
   1535 
   1536 /*******************************************************************************
   1537 **
   1538 ** Function         init_all_transactions
   1539 **
   1540 ** Description    Initializes all transactions
   1541 **
   1542 ** Returns          void
   1543 *******************************************************************************/
   1544 void init_all_transactions()
   1545 {
   1546     UINT8 txn_indx=0;
   1547     for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
   1548     {
   1549         initialize_transaction(txn_indx);
   1550     }
   1551 }
   1552 
   1553 /*******************************************************************************
   1554 **
   1555 ** Function         get_transaction_by_lbl
   1556 **
   1557 ** Description    Will return a transaction based on the label. If not inuse
   1558 **                     will return an error.
   1559 **
   1560 ** Returns          bt_status_t
   1561 *******************************************************************************/
   1562 rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
   1563 {
   1564     rc_transaction_t *transaction = NULL;
   1565     pthread_mutex_lock(&device.lbllock);
   1566 
   1567     /* Determine if this is a valid label */
   1568     if (lbl < MAX_TRANSACTIONS_PER_SESSION)
   1569     {
   1570         if (FALSE==device.transaction[lbl].in_use)
   1571         {
   1572             transaction = NULL;
   1573         }
   1574         else
   1575         {
   1576             transaction = &(device.transaction[lbl]);
   1577             BTIF_TRACE_DEBUG2("%s: Got transaction.label: %d",__FUNCTION__,lbl);
   1578         }
   1579     }
   1580 
   1581     pthread_mutex_unlock(&device.lbllock);
   1582     return transaction;
   1583 }
   1584 
   1585 /*******************************************************************************
   1586 **
   1587 ** Function         get_transaction
   1588 **
   1589 ** Description    Obtains the transaction details.
   1590 **
   1591 ** Returns          bt_status_t
   1592 *******************************************************************************/
   1593 
   1594 bt_status_t  get_transaction(rc_transaction_t **ptransaction)
   1595 {
   1596     bt_status_t result = BT_STATUS_NOMEM;
   1597     UINT8 i=0;
   1598     pthread_mutex_lock(&device.lbllock);
   1599 
   1600     // Check for unused transactions
   1601     for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
   1602     {
   1603         if (FALSE==device.transaction[i].in_use)
   1604         {
   1605             BTIF_TRACE_DEBUG2("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
   1606             device.transaction[i].in_use = TRUE;
   1607             *ptransaction = &(device.transaction[i]);
   1608             result = BT_STATUS_SUCCESS;
   1609             break;
   1610         }
   1611     }
   1612 
   1613     pthread_mutex_unlock(&device.lbllock);
   1614     return result;
   1615 }
   1616 
   1617 
   1618 /*******************************************************************************
   1619 **
   1620 ** Function         release_transaction
   1621 **
   1622 ** Description    Will release a transaction for reuse
   1623 **
   1624 ** Returns          bt_status_t
   1625 *******************************************************************************/
   1626 void release_transaction(UINT8 lbl)
   1627 {
   1628     rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
   1629 
   1630     /* If the transaction is in use... */
   1631     if (transaction != NULL)
   1632     {
   1633         BTIF_TRACE_DEBUG2("%s: lbl: %d", __FUNCTION__, lbl);
   1634         initialize_transaction(lbl);
   1635     }
   1636 }
   1637 
   1638 /*******************************************************************************
   1639 **
   1640 ** Function         lbl_destroy
   1641 **
   1642 ** Description    Cleanup of the mutex
   1643 **
   1644 ** Returns          void
   1645 *******************************************************************************/
   1646 void lbl_destroy()
   1647 {
   1648     pthread_mutex_destroy(&(device.lbllock));
   1649 }
   1650 
   1651 /*******************************************************************************
   1652 **      Function       dev_blacklisted_for_absolute_volume
   1653 **
   1654 **      Description    Blacklist Devices that donot handle absolute volume well
   1655 **                     We are blacklisting all the devices that are not in whitelist
   1656 **
   1657 **      Returns        True if the device is in the list
   1658 *******************************************************************************/
   1659 static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev)
   1660 {
   1661     int i;
   1662     int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]);
   1663     for (i = 0; i < whitelist_size; i++) {
   1664         if (rc_white_addr_prefix[i][0] == peer_dev[0] &&
   1665             rc_white_addr_prefix[i][1] == peer_dev[1] &&
   1666             rc_white_addr_prefix[i][2] == peer_dev[2]) {
   1667             BTIF_TRACE_DEBUG3("whitelist absolute volume for %02x:%02x:%02x",
   1668                                 peer_dev[0], peer_dev[1], peer_dev[2]);
   1669             return FALSE;
   1670         }
   1671     }
   1672     BTIF_TRACE_WARNING3("blacklist absolute volume for %02x:%02x:%02x",
   1673                         peer_dev[0], peer_dev[1], peer_dev[2]);
   1674     return TRUE;
   1675 }
   1676