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