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  *  Filename:      btif_hh.c
     22  *
     23  *  Description:   HID Host Profile Bluetooth Interface
     24  *
     25  *
     26  ***********************************************************************************/
     27 #include <hardware/bluetooth.h>
     28 #include <hardware/bt_hh.h>
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <errno.h>
     32 #include <string.h>
     33 
     34 #define LOG_TAG "BTIF_HH"
     35 
     36 #include "bta_api.h"
     37 #include "bta_hh_api.h"
     38 #include "bd.h"
     39 #include "btif_storage.h"
     40 
     41 #include "btif_common.h"
     42 #include "btif_util.h"
     43 #include "btif_hh.h"
     44 #include "gki.h"
     45 #include "l2c_api.h"
     46 
     47 
     48 #define BTIF_HH_APP_ID_MI       0x01
     49 #define BTIF_HH_APP_ID_KB       0x02
     50 
     51 #define COD_HID_KEYBOARD        0x0540
     52 #define COD_HID_POINTING        0x0580
     53 #define COD_HID_COMBO           0x05C0
     54 #define COD_HID_MAJOR           0x0500
     55 
     56 #define KEYSTATE_FILEPATH "/data/misc/bluedroid/bt_hh_ks" //keep this in sync with HID host jni
     57 
     58 #define HID_REPORT_CAPSLOCK   0x39
     59 #define HID_REPORT_NUMLOCK    0x53
     60 #define HID_REPORT_SCROLLLOCK 0x47
     61 
     62 //For Apple Magic Mouse
     63 #define MAGICMOUSE_VENDOR_ID 0x05ac
     64 #define MAGICMOUSE_PRODUCT_ID 0x030d
     65 
     66 #define LOGITECH_KB_MX5500_VENDOR_ID  0x046D
     67 #define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B
     68 
     69 extern const int BT_UID;
     70 extern const int BT_GID;
     71 static int btif_hh_prev_keyevents=0; //The previous key events
     72 static int btif_hh_keylockstates=0; //The current key state of each key
     73 
     74 #define BTIF_HH_ID_1        0
     75 #define BTIF_HH_DEV_DISCONNECTED 3
     76 
     77 #define BTIF_TIMEOUT_VUP_SECS   3
     78 
     79 
     80 #ifndef BTUI_HH_SECURITY
     81 #define BTUI_HH_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
     82 #endif
     83 
     84 #ifndef BTUI_HH_MOUSE_SECURITY
     85 #define BTUI_HH_MOUSE_SECURITY (BTA_SEC_NONE)
     86 #endif
     87 
     88 /* HH request events */
     89 typedef enum
     90 {
     91     BTIF_HH_CONNECT_REQ_EVT = 0,
     92     BTIF_HH_DISCONNECT_REQ_EVT,
     93     BTIF_HH_VUP_REQ_EVT
     94 } btif_hh_req_evt_t;
     95 
     96 
     97 /************************************************************************************
     98 **  Constants & Macros
     99 ************************************************************************************/
    100 #define BTIF_HH_SERVICES    (BTA_HID_SERVICE_MASK)
    101 
    102 
    103 
    104 /************************************************************************************
    105 **  Local type definitions
    106 ************************************************************************************/
    107 
    108 typedef struct hid_kb_list
    109 {
    110     UINT16 product_id;
    111     UINT16 version_id;
    112     char*  kb_name;
    113 } tHID_KB_LIST;
    114 
    115 /************************************************************************************
    116 **  Static variables
    117 ************************************************************************************/
    118 btif_hh_cb_t btif_hh_cb;
    119 
    120 static bthh_callbacks_t *bt_hh_callbacks = NULL;
    121 
    122 /* List of HID keyboards for which the NUMLOCK state needs to be
    123  * turned ON by default. Add devices to this list to apply the
    124  * NUMLOCK state toggle on fpr first connect.*/
    125 static tHID_KB_LIST hid_kb_numlock_on_list[] =
    126 {
    127     {LOGITECH_KB_MX5500_PRODUCT_ID,
    128     LOGITECH_KB_MX5500_VENDOR_ID,
    129     "Logitech MX5500 Keyboard"}
    130 };
    131 
    132 
    133 #define CHECK_BTHH_INIT() if (bt_hh_callbacks == NULL)\
    134     {\
    135         BTIF_TRACE_WARNING1("BTHH: %s: BTHH not initialized", __FUNCTION__);\
    136         return BT_STATUS_NOT_READY;\
    137     }\
    138     else\
    139     {\
    140         BTIF_TRACE_EVENT1("BTHH: %s", __FUNCTION__);\
    141     }
    142 
    143 
    144 
    145 /************************************************************************************
    146 **  Static functions
    147 ************************************************************************************/
    148 
    149 /************************************************************************************
    150 **  Externs
    151 ************************************************************************************/
    152 extern void bta_hh_co_destroy(int fd);
    153 extern void bta_hh_co_write(int fd, UINT8* rpt, UINT16 len);
    154 extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *bd_addr);
    155 extern void bta_hh_co_send_hid_info(btif_hh_device_t *p_dev, char *dev_name, UINT16 vendor_id,
    156                                     UINT16 product_id, UINT16 version, UINT8 ctry_code,
    157                                     int dscp_len, UINT8 *p_dscp);
    158 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
    159 extern void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr);
    160 extern BOOLEAN check_cod_hid(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
    161 extern int  scru_ascii_2_hex(char *p_ascii, int len, UINT8 *p_hex);
    162 
    163 /*****************************************************************************
    164 **  Local Function prototypes
    165 *****************************************************************************/
    166 static void set_keylockstate(int keymask, BOOLEAN isSet);
    167 static void toggle_os_keylockstates(int fd, int changedkeystates);
    168 static void sync_lockstate_on_connect(btif_hh_device_t *p_dev);
    169 //static void hh_update_keyboard_lockstates(btif_hh_device_t *p_dev);
    170 void btif_hh_tmr_hdlr(TIMER_LIST_ENT *tle);
    171 
    172 
    173 /************************************************************************************
    174 **  Functions
    175 ************************************************************************************/
    176 
    177 static int get_keylockstates()
    178 {
    179     return btif_hh_keylockstates;
    180 }
    181 
    182 static void set_keylockstate(int keymask, BOOLEAN isSet)
    183 {
    184     if(isSet)
    185         btif_hh_keylockstates |= keymask;
    186 }
    187 
    188 /*******************************************************************************
    189 **
    190 ** Function         toggle_os_keylockstates
    191 **
    192 ** Description      Function to toggle the keyboard lock states managed by the linux.
    193 **                  This function is used in by two call paths
    194 **                  (1) if the lock state change occurred from an onscreen keyboard,
    195 **                  this function is called to update the lock state maintained
    196                     for the HID keyboard(s)
    197 **                  (2) if a HID keyboard is disconnected and reconnected,
    198 **                  this function is called to update the lock state maintained
    199                     for the HID keyboard(s)
    200 ** Returns          void
    201 *******************************************************************************/
    202 
    203 static void toggle_os_keylockstates(int fd, int changedlockstates)
    204 {
    205     BTIF_TRACE_EVENT3("%s: fd = %d, changedlockstates = 0x%x",
    206         __FUNCTION__, fd, changedlockstates);
    207     UINT8 hidreport[9];
    208     int reportIndex;
    209     memset(hidreport,0,9);
    210     hidreport[0]=1;
    211     reportIndex=4;
    212 
    213     if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) {
    214         BTIF_TRACE_DEBUG1("%s Setting CAPSLOCK", __FUNCTION__);
    215         hidreport[reportIndex++] = (UINT8)HID_REPORT_CAPSLOCK;
    216     }
    217 
    218     if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK)  {
    219         BTIF_TRACE_DEBUG1("%s Setting NUMLOCK", __FUNCTION__);
    220         hidreport[reportIndex++] = (UINT8)HID_REPORT_NUMLOCK;
    221     }
    222 
    223     if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) {
    224         BTIF_TRACE_DEBUG1("%s Setting SCROLLLOCK", __FUNCTION__);
    225         hidreport[reportIndex++] = (UINT8) HID_REPORT_SCROLLLOCK;
    226     }
    227 
    228      BTIF_TRACE_DEBUG4("Writing hidreport #1 to os: "\
    229         "%s:  %x %x %x", __FUNCTION__,
    230          hidreport[0], hidreport[1], hidreport[2]);
    231     BTIF_TRACE_DEBUG4("%s:  %x %x %x", __FUNCTION__,
    232          hidreport[3], hidreport[4], hidreport[5]);
    233     BTIF_TRACE_DEBUG4("%s:  %x %x %x", __FUNCTION__,
    234          hidreport[6], hidreport[7], hidreport[8]);
    235     bta_hh_co_write(fd , hidreport, sizeof(hidreport));
    236     usleep(200000);
    237     memset(hidreport,0,9);
    238     hidreport[0]=1;
    239     BTIF_TRACE_DEBUG4("Writing hidreport #2 to os: "\
    240        "%s:  %x %x %x", __FUNCTION__,
    241          hidreport[0], hidreport[1], hidreport[2]);
    242     BTIF_TRACE_DEBUG4("%s:  %x %x %x", __FUNCTION__,
    243          hidreport[3], hidreport[4], hidreport[5]);
    244     BTIF_TRACE_DEBUG4("%s:  %x %x %x ", __FUNCTION__,
    245          hidreport[6], hidreport[7], hidreport[8]);
    246     bta_hh_co_write(fd , hidreport, sizeof(hidreport));
    247 }
    248 
    249 /*******************************************************************************
    250 **
    251 ** Function         update_keyboard_lockstates
    252 **
    253 ** Description      Sends a report to the keyboard to set the lock states of keys
    254 **
    255 *******************************************************************************/
    256 static void update_keyboard_lockstates(btif_hh_device_t *p_dev)
    257 {
    258     UINT8 len = 2;  /* reportid + 1 byte report*/
    259     BD_ADDR* bda;
    260 
    261     /* Set report for other keyboards */
    262     BTIF_TRACE_EVENT3("%s: setting report on dev_handle %d to 0x%x",
    263          __FUNCTION__, p_dev->dev_handle, btif_hh_keylockstates);
    264 
    265     if (p_dev->p_buf != NULL) {
    266         GKI_freebuf(p_dev->p_buf);
    267     }
    268     /* Get SetReport buffer */
    269     p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET +
    270         sizeof(BT_HDR)));
    271     if (p_dev->p_buf != NULL) {
    272         p_dev->p_buf->len = len;
    273         p_dev->p_buf->offset = BTA_HH_MIN_OFFSET;
    274         p_dev->p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
    275 
    276         /* LED status updated by data event */
    277         UINT8 *pbuf_data  = (UINT8 *)(p_dev->p_buf + 1)
    278             + p_dev->p_buf->offset;
    279         pbuf_data[0]=0x01; /*report id */
    280         pbuf_data[1]=btif_hh_keylockstates; /*keystate*/
    281         bda = (BD_ADDR*) (&p_dev->bd_addr);
    282         BTA_HhSendData(p_dev->dev_handle, *bda,
    283             p_dev->p_buf);
    284     }
    285 }
    286 
    287 /*******************************************************************************
    288 **
    289 ** Function         sync_lockstate_on_connect
    290 **
    291 ** Description      Function to update the keyboard lock states managed by the OS
    292 **                  when a HID keyboard is connected or disconnected and reconnected
    293 ** Returns          void
    294 *******************************************************************************/
    295 static void sync_lockstate_on_connect(btif_hh_device_t *p_dev)
    296 {
    297     int keylockstates;
    298 
    299     BTIF_TRACE_EVENT1("%s: Syncing keyboard lock states after "\
    300         "reconnect...",__FUNCTION__);
    301     /*If the device is connected, update keyboard state */
    302     update_keyboard_lockstates(p_dev);
    303 
    304     /*Check if the lockstate of caps,scroll,num is set.
    305      If so, send a report to the kernel
    306     so the lockstate is in sync */
    307     keylockstates = get_keylockstates();
    308     if (keylockstates)
    309     {
    310         BTIF_TRACE_DEBUG2("%s: Sending hid report to kernel "\
    311             "indicating lock key state 0x%x",__FUNCTION__,
    312             keylockstates);
    313         usleep(200000);
    314         toggle_os_keylockstates(p_dev->fd, keylockstates);
    315     }
    316     else
    317     {
    318         BTIF_TRACE_DEBUG2("%s: NOT sending hid report to kernel "\
    319             "indicating lock key state 0x%x",__FUNCTION__,
    320             keylockstates);
    321     }
    322 }
    323 
    324 /*******************************************************************************
    325 **
    326 ** Function         btif_hh_find_dev_by_handle
    327 **
    328 ** Description      Return the device pointer of the specified device handle
    329 **
    330 ** Returns          Device entry pointer in the device table
    331 *******************************************************************************/
    332 static btif_hh_device_t *btif_hh_find_dev_by_handle(UINT8 handle)
    333 {
    334     UINT32 i;
    335     // LOGV("%s: handle = %d", __FUNCTION__, handle);
    336     for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    337         if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN &&
    338             btif_hh_cb.devices[i].dev_handle == handle)
    339         {
    340             return &btif_hh_cb.devices[i];
    341         }
    342     }
    343     return NULL;
    344 }
    345 
    346 
    347 /*******************************************************************************
    348 **
    349 ** Function         btif_hh_find_connected_dev_by_handle
    350 **
    351 ** Description      Return the connected device pointer of the specified device handle
    352 **
    353 ** Returns          Device entry pointer in the device table
    354 *******************************************************************************/
    355 btif_hh_device_t *btif_hh_find_connected_dev_by_handle(UINT8 handle)
    356 {
    357     UINT32 i;
    358     for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    359         if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
    360             btif_hh_cb.devices[i].dev_handle == handle)
    361         {
    362             return &btif_hh_cb.devices[i];
    363         }
    364     }
    365     return NULL;
    366 }
    367 
    368 /*******************************************************************************
    369 **
    370 ** Function         btif_hh_find_dev_by_bda
    371 **
    372 ** Description      Return the device pointer of the specified bt_bdaddr_t.
    373 **
    374 ** Returns          Device entry pointer in the device table
    375 *******************************************************************************/
    376 static btif_hh_device_t *btif_hh_find_dev_by_bda(bt_bdaddr_t *bd_addr)
    377 {
    378     UINT32 i;
    379     for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    380         if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN &&
    381             memcmp(&(btif_hh_cb.devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0)
    382         {
    383             return &btif_hh_cb.devices[i];
    384         }
    385     }
    386     return NULL;
    387 }
    388 
    389 /*******************************************************************************
    390 **
    391 ** Function         btif_hh_find_connected_dev_by_bda
    392 **
    393 ** Description      Return the connected device pointer of the specified bt_bdaddr_t.
    394 **
    395 ** Returns          Device entry pointer in the device table
    396 *******************************************************************************/
    397 static btif_hh_device_t *btif_hh_find_connected_dev_by_bda(bt_bdaddr_t *bd_addr)
    398 {
    399     UINT32 i;
    400     for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    401         if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
    402             memcmp(&(btif_hh_cb.devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0)
    403         {
    404             return &btif_hh_cb.devices[i];
    405         }
    406     }
    407     return NULL;
    408 }
    409 
    410 /*******************************************************************************
    411 **
    412 ** Function      btif_hh_stop_vup_timer
    413 **
    414 ** Description  stop vitual unplug timer
    415 **
    416 ** Returns      void
    417 *******************************************************************************/
    418 void btif_hh_stop_vup_timer(bt_bdaddr_t *bd_addr)
    419 {
    420     btif_hh_device_t *p_dev  = btif_hh_find_connected_dev_by_bda(bd_addr);
    421     if(p_dev != NULL)
    422     {
    423         if (p_dev->vup_timer_active)
    424         {
    425             BTIF_TRACE_DEBUG0("stop VUP timer ");
    426             btu_stop_timer(&p_dev->vup_timer);
    427         }
    428         p_dev->vup_timer_active = FALSE;
    429     }
    430 }
    431 /*******************************************************************************
    432 **
    433 ** Function      btif_hh_start_vup_timer
    434 **
    435 ** Description  start virtual unplug timer
    436 **
    437 ** Returns      void
    438 *******************************************************************************/
    439 void btif_hh_start_vup_timer(bt_bdaddr_t *bd_addr)
    440 {
    441     btif_hh_device_t *p_dev  = btif_hh_find_connected_dev_by_bda(bd_addr);
    442 
    443     if (p_dev->vup_timer_active == FALSE)
    444     {
    445         BTIF_TRACE_DEBUG0("Start VUP timer ");
    446         memset(&p_dev->vup_timer, 0, sizeof(TIMER_LIST_ENT));
    447         p_dev->vup_timer.param = (UINT32)btif_hh_tmr_hdlr;
    448         btu_start_timer(&p_dev->vup_timer, BTU_TTYPE_USER_FUNC,
    449                         BTIF_TIMEOUT_VUP_SECS);
    450     }
    451     else
    452     {
    453         BTIF_TRACE_DEBUG0("Restart VUP timer ");
    454         btu_stop_timer(&p_dev->vup_timer);
    455         btu_start_timer(&p_dev->vup_timer, BTU_TTYPE_USER_FUNC,
    456                         BTIF_TIMEOUT_VUP_SECS);
    457     }
    458         p_dev->vup_timer_active = TRUE;
    459 
    460 }
    461 
    462 /*******************************************************************************
    463 **
    464 ** Function         btif_hh_add_added_dev
    465 **
    466 ** Description      Add a new device to the added device list.
    467 **
    468 ** Returns          TRUE if add successfully, otherwise FALSE.
    469 *******************************************************************************/
    470 BOOLEAN btif_hh_add_added_dev(bt_bdaddr_t bda, tBTA_HH_ATTR_MASK attr_mask)
    471 {
    472     int i;
    473     for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    474         if (memcmp(&(btif_hh_cb.added_devices[i].bd_addr), &bda, BD_ADDR_LEN) == 0) {
    475             BTIF_TRACE_WARNING6(" Device %02X:%02X:%02X:%02X:%02X:%02X already added",
    476                   bda.address[0], bda.address[1], bda.address[2], bda.address[3], bda.address[4], bda.address[5]);
    477             return FALSE;
    478         }
    479     }
    480     for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    481         if (btif_hh_cb.added_devices[i].bd_addr.address[0] == 0 &&
    482             btif_hh_cb.added_devices[i].bd_addr.address[1] == 0 &&
    483             btif_hh_cb.added_devices[i].bd_addr.address[2] == 0 &&
    484             btif_hh_cb.added_devices[i].bd_addr.address[3] == 0 &&
    485             btif_hh_cb.added_devices[i].bd_addr.address[4] == 0 &&
    486             btif_hh_cb.added_devices[i].bd_addr.address[5] == 0)
    487         {
    488             BTIF_TRACE_WARNING6(" Added device %02X:%02X:%02X:%02X:%02X:%02X",
    489                   bda.address[0], bda.address[1], bda.address[2], bda.address[3], bda.address[4], bda.address[5]);
    490             memcpy(&(btif_hh_cb.added_devices[i].bd_addr), &bda, BD_ADDR_LEN);
    491             btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
    492             btif_hh_cb.added_devices[i].attr_mask  = attr_mask;
    493             return TRUE;
    494         }
    495     }
    496 
    497     BTIF_TRACE_WARNING1("%s: Error, out of space to add device",__FUNCTION__);
    498     return FALSE;
    499 }
    500 
    501 /*******************************************************************************
    502  **
    503  ** Function         btif_hh_remove_device
    504  **
    505  ** Description      Remove an added device from the stack.
    506  **
    507  ** Returns          void
    508  *******************************************************************************/
    509 void btif_hh_remove_device(bt_bdaddr_t bd_addr)
    510 {
    511     int                    i;
    512     btif_hh_device_t       *p_dev;
    513     btif_hh_added_device_t *p_added_dev;
    514 
    515     ALOGI("%s: bda = %02x:%02x:%02x:%02x:%02x:%02x", __FUNCTION__,
    516          bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
    517 
    518     for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    519         p_added_dev = &btif_hh_cb.added_devices[i];
    520         if (memcmp(&(p_added_dev->bd_addr),&bd_addr, 6) == 0) {
    521             BTA_HhRemoveDev(p_added_dev->dev_handle);
    522             btif_storage_remove_hid_info(&(p_added_dev->bd_addr));
    523             memset(&(p_added_dev->bd_addr), 0, 6);
    524             p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    525             break;
    526         }
    527     }
    528 
    529     p_dev = btif_hh_find_dev_by_bda(&bd_addr);
    530     if (p_dev == NULL) {
    531         BTIF_TRACE_WARNING6(" Oops, can't find device [%02x:%02x:%02x:%02x:%02x:%02x]",
    532              bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
    533         return;
    534     }
    535 
    536     /* need to notify up-layer device is disconnected to avoid state out of sync with up-layer */
    537     HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), BTHH_CONN_STATE_DISCONNECTED);
    538 
    539     p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
    540     p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    541     if (btif_hh_cb.device_num > 0) {
    542         btif_hh_cb.device_num--;
    543     }
    544     else {
    545         BTIF_TRACE_WARNING1("%s: device_num = 0", __FUNCTION__);
    546     }
    547     if (p_dev->p_buf != NULL) {
    548         GKI_freebuf(p_dev->p_buf);
    549         p_dev->p_buf = NULL;
    550     }
    551 
    552     p_dev->hh_keep_polling = 0;
    553     p_dev->hh_poll_thread_id = -1;
    554     BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd);
    555     if (p_dev->fd >= 0) {
    556         bta_hh_co_destroy(p_dev->fd);
    557         p_dev->fd = -1;
    558     }
    559 }
    560 
    561 
    562 BOOLEAN btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest , tBTA_HH_DEV_DSCP_INFO* src)
    563 {
    564     dest->descriptor.dl_len = 0;
    565     if (src->descriptor.dl_len >0)
    566     {
    567         dest->descriptor.dsc_list = (UINT8 *) GKI_getbuf(src->descriptor.dl_len);
    568         if (dest->descriptor.dsc_list == NULL)
    569         {
    570             BTIF_TRACE_WARNING1("%s: Failed to allocate DSCP for CB", __FUNCTION__);
    571             return FALSE;
    572         }
    573     }
    574     memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list, src->descriptor.dl_len);
    575     dest->descriptor.dl_len = src->descriptor.dl_len;
    576     dest->vendor_id  = src->vendor_id;
    577     dest->product_id = src->product_id;
    578     dest->version    = src->version;
    579     dest->ctry_code  = src->ctry_code;
    580     return TRUE;
    581 }
    582 
    583 
    584 /*******************************************************************************
    585 **
    586 ** Function         btif_hh_virtual_unplug
    587 **
    588 ** Description      Virtual unplug initiated from the BTIF thread context
    589 **                  Special handling for HID mouse-
    590 **
    591 ** Returns          void
    592 **
    593 *******************************************************************************/
    594 
    595 bt_status_t btif_hh_virtual_unplug(bt_bdaddr_t *bd_addr)
    596 {
    597     BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
    598     btif_hh_device_t *p_dev;
    599     char bd_str[18];
    600     sprintf(bd_str, "%02X:%02X:%02X:%02X:%02X:%02X",
    601             bd_addr->address[0],  bd_addr->address[1],  bd_addr->address[2],  bd_addr->address[3],
    602             bd_addr->address[4], bd_addr->address[5]);
    603     p_dev = btif_hh_find_dev_by_bda(bd_addr);
    604     if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED)
    605         && (p_dev->attr_mask & HID_VIRTUAL_CABLE))
    606     {
    607         BTIF_TRACE_DEBUG1("%s Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __FUNCTION__);
    608         /* start the timer */
    609         btif_hh_start_vup_timer(bd_addr);
    610         p_dev->local_vup = TRUE;
    611         BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG);
    612         return BT_STATUS_SUCCESS;
    613     }
    614     else
    615     {
    616         BTIF_TRACE_ERROR2("%s: Error, device %s not opened.", __FUNCTION__, bd_str);
    617         return BT_STATUS_FAIL;
    618     }
    619 }
    620 
    621 /*******************************************************************************
    622 **
    623 ** Function         btif_hh_connect
    624 **
    625 ** Description      connection initiated from the BTIF thread context
    626 **
    627 ** Returns          int status
    628 **
    629 *******************************************************************************/
    630 
    631 bt_status_t btif_hh_connect(bt_bdaddr_t *bd_addr)
    632 {
    633     btif_hh_device_t *dev;
    634     btif_hh_added_device_t *added_dev = NULL;
    635     char bda_str[20];
    636     int i;
    637     BD_ADDR *bda = (BD_ADDR*)bd_addr;
    638     tBTA_HH_CONN conn;
    639     CHECK_BTHH_INIT();
    640     dev = btif_hh_find_dev_by_bda(bd_addr);
    641     BTIF_TRACE_DEBUG0("Connect _hh");
    642     sprintf(bda_str, "%02X:%02X:%02X:%02X:%02X:%02X",
    643             (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
    644     if (dev == NULL && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
    645         // No space for more HID device now.
    646          BTIF_TRACE_WARNING2("%s: Error, exceeded the maximum supported HID device number %d",
    647              __FUNCTION__, BTIF_HH_MAX_HID);
    648         return BT_STATUS_FAIL;
    649     }
    650 
    651     for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    652         if (memcmp(&(btif_hh_cb.added_devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0) {
    653             added_dev = &btif_hh_cb.added_devices[i];
    654              BTIF_TRACE_WARNING3("%s: Device %s already added, attr_mask = 0x%x",
    655                  __FUNCTION__, bda_str, added_dev->attr_mask);
    656         }
    657     }
    658 
    659     if (added_dev != NULL) {
    660         if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
    661             // No space for more HID device now.
    662             BTIF_TRACE_ERROR2("%s: Error, device %s added but addition failed", __FUNCTION__, bda_str);
    663             memset(&(added_dev->bd_addr), 0, 6);
    664             added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    665             return BT_STATUS_FAIL;
    666         }
    667     }
    668 
    669     if (added_dev == NULL ||
    670         (added_dev->attr_mask & HID_NORMALLY_CONNECTABLE) != 0 ||
    671         (added_dev->attr_mask & HID_RECONN_INIT) == 0)
    672     {
    673         tBTA_SEC sec_mask = BTUI_HH_SECURITY;
    674         btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
    675         BD_ADDR *bda = (BD_ADDR*)bd_addr;
    676         BTA_HhOpen(*bda, BTA_HH_PROTO_RPT_MODE, sec_mask);
    677     }
    678     else
    679     {
    680         // This device shall be connected from the host side.
    681         BTIF_TRACE_ERROR2("%s: Error, device %s can only be reconnected from device side",
    682              __FUNCTION__, bda_str);
    683         return BT_STATUS_FAIL;
    684     }
    685 
    686     HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, BTHH_CONN_STATE_CONNECTING);
    687     return BT_STATUS_SUCCESS;
    688 }
    689 
    690 /*******************************************************************************
    691 **
    692 ** Function         btif_hh_disconnect
    693 **
    694 ** Description      disconnection initiated from the BTIF thread context
    695 **
    696 ** Returns          void
    697 **
    698 *******************************************************************************/
    699 
    700 void btif_hh_disconnect(bt_bdaddr_t *bd_addr)
    701 {
    702     BD_ADDR *bda = (BD_ADDR*)bd_addr;
    703     btif_hh_device_t *p_dev;
    704     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
    705     if (p_dev != NULL)
    706     {
    707         BTA_HhClose(p_dev->dev_handle);
    708     }
    709     else
    710         BTIF_TRACE_DEBUG1("%s-- Error: device not connected:",__FUNCTION__);
    711 }
    712 
    713 /*******************************************************************************
    714 **
    715 ** Function         btif_btif_hh_setreport
    716 **
    717 ** Description      setreport initiated from the BTIF thread context
    718 **
    719 ** Returns          void
    720 **
    721 *******************************************************************************/
    722 
    723 void btif_hh_setreport(btif_hh_device_t *p_dev, bthh_report_type_t r_type, UINT16 size,
    724                             UINT8* report)
    725 {
    726     UINT8  hexbuf[20];
    727     UINT16 len = size;
    728     int i = 0;
    729     if (p_dev->p_buf != NULL) {
    730         GKI_freebuf(p_dev->p_buf);
    731     }
    732     p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR)));
    733     if (p_dev->p_buf == NULL) {
    734         APPL_TRACE_ERROR2("%s: Error, failed to allocate RPT buffer, len = %d", __FUNCTION__, len);
    735         return;
    736     }
    737 
    738     p_dev->p_buf->len = len;
    739     p_dev->p_buf->offset = BTA_HH_MIN_OFFSET;
    740 
    741     //Build a SetReport data buffer
    742     memset(hexbuf, 0, 20);
    743     for(i=0; i<len; i++)
    744         hexbuf[i] = report[i];
    745 
    746     UINT8* pbuf_data;
    747     pbuf_data = (UINT8*) (p_dev->p_buf + 1) + p_dev->p_buf->offset;
    748     memcpy(pbuf_data, hexbuf, len);
    749     BTA_HhSetReport(p_dev->dev_handle, r_type, p_dev->p_buf);
    750 
    751 }
    752 
    753 /*****************************************************************************
    754 **   Section name (Group of functions)
    755 *****************************************************************************/
    756 
    757 /*****************************************************************************
    758 **
    759 **   btif hh api functions (no context switch)
    760 **
    761 *****************************************************************************/
    762 
    763 
    764 /*******************************************************************************
    765 **
    766 ** Function         btif_hh_upstreams_evt
    767 **
    768 ** Description      Executes HH UPSTREAMS events in btif context
    769 **
    770 ** Returns          void
    771 **
    772 *******************************************************************************/
    773 static void btif_hh_upstreams_evt(UINT16 event, char* p_param)
    774 {
    775     tBTA_HH *p_data = (tBTA_HH *)p_param;
    776     bdstr_t bdstr;
    777     btif_hh_device_t *p_dev = NULL;
    778     int i;
    779     int len, tmplen;
    780 
    781     BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_hh_event(event));
    782 
    783     switch (event)
    784     {
    785         case BTA_HH_ENABLE_EVT:
    786             BTIF_TRACE_DEBUG2("%s: BTA_HH_ENABLE_EVT: status =%d",__FUNCTION__, p_data->status);
    787             if (p_data->status == BTA_HH_OK) {
    788                 btif_hh_cb.status = BTIF_HH_ENABLED;
    789                 BTIF_TRACE_DEBUG1("%s--Loading added devices",__FUNCTION__);
    790                 /* Add hid descriptors for already bonded hid devices*/
    791                 btif_storage_load_bonded_hid_info();
    792             }
    793             else {
    794                 btif_hh_cb.status = BTIF_HH_DISABLED;
    795                 BTIF_TRACE_WARNING1("BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d", p_data->status);
    796             }
    797             break;
    798 
    799         case BTA_HH_DISABLE_EVT:
    800             btif_hh_cb.status = BTIF_HH_DISABLED;
    801             if (p_data->status == BTA_HH_OK) {
    802                 int i;
    803                 //Clear the control block
    804                 memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
    805                 for (i = 0; i < BTIF_HH_MAX_HID; i++){
    806                     btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
    807                 }
    808             }
    809             else
    810                 BTIF_TRACE_WARNING1("BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d", p_data->status);
    811             break;
    812 
    813         case BTA_HH_OPEN_EVT:
    814             BTIF_TRACE_WARNING3("%s: BTA_HH_OPN_EVT: handle=%d, status =%d",__FUNCTION__, p_data->conn.handle, p_data->conn.status);
    815             if (p_data->conn.status == BTA_HH_OK) {
    816                 p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
    817                 if (p_dev == NULL) {
    818                     BTIF_TRACE_WARNING1("BTA_HH_OPEN_EVT: Error, cannot find device with handle %d", p_data->conn.handle);
    819                     btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
    820                     // The connect request must come from device side and exceeded the connected
    821                                    // HID device number.
    822                     BTA_HhClose(p_data->conn.handle);
    823                     HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED);
    824                 }
    825                 else if (p_dev->fd < 0) {
    826                     BTIF_TRACE_WARNING0("BTA_HH_OPEN_EVT: Error, failed to find the uhid driver...");
    827                     memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN);
    828                     //remove the connection  and then try again to reconnect from the mouse side to recover
    829                     btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
    830                     BTA_HhClose(p_data->conn.handle);
    831                 }
    832                 else {
    833                     BTIF_TRACE_WARNING1("BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle ... %d",p_data->conn.handle);
    834                     memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN);
    835                     btif_hh_cb.status = BTIF_HH_DEV_CONNECTED;
    836                     // Send set_idle if the peer_device is a keyboard
    837                     if (check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_KEYBOARD )||
    838                                 check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_COMBO))
    839                         BTA_HhSetIdle(p_data->conn.handle, 0);
    840                     btif_hh_cb.p_curr_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
    841                     BTA_HhGetDscpInfo(p_data->conn.handle);
    842                     p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
    843                     HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status);
    844                 }
    845             }
    846             else {
    847                 bt_bdaddr_t *bdaddr = (bt_bdaddr_t*)p_data->conn.bda;
    848                 HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED);
    849                 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
    850             }
    851             break;
    852         case BTA_HH_CLOSE_EVT:
    853             BTIF_TRACE_DEBUG2("BTA_HH_CLOSE_EVT: status = %d, handle = %d",
    854             p_data->dev_status.status, p_data->dev_status.handle);
    855             p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
    856             if (p_dev != NULL) {
    857                 BTIF_TRACE_DEBUG2("%s: uhid fd = %d", __FUNCTION__, p_dev->fd);
    858                 if (p_dev->fd >= 0){
    859                     UINT8 hidreport[9];
    860                     memset(hidreport,0,9);
    861                     hidreport[0]=1;
    862                     bta_hh_co_write(p_dev->fd , hidreport, sizeof(hidreport));
    863                 }
    864                 if(p_dev->vup_timer_active)
    865                 {
    866                     btif_hh_stop_vup_timer(&(p_dev->bd_addr));
    867                 }
    868                 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
    869                 p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
    870                 HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status);
    871                 BTIF_TRACE_DEBUG2("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd);
    872                 bta_hh_co_destroy(p_dev->fd);
    873                 p_dev->fd = -1;
    874             }
    875             else {
    876                 BTIF_TRACE_WARNING1("Error: cannot find device with handle %d", p_data->dev_status.handle);
    877             }
    878             break;
    879         case BTA_HH_GET_RPT_EVT:
    880             BTIF_TRACE_DEBUG2("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
    881                  p_data->hs_data.status, p_data->hs_data.handle);
    882             p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
    883             HAL_CBACK(bt_hh_callbacks, get_report_cb,(bt_bdaddr_t*) &(p_dev->bd_addr), (bthh_status_t) p_data->hs_data.status,
    884                 (uint8_t*) p_data->hs_data.rsp_data.p_rpt_data, BT_HDR_SIZE);
    885             break;
    886 
    887         case BTA_HH_SET_RPT_EVT:
    888             BTIF_TRACE_DEBUG2("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
    889             p_data->dev_status.status, p_data->dev_status.handle);
    890             p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
    891             if (p_dev != NULL && p_dev->p_buf != NULL) {
    892                 BTIF_TRACE_DEBUG0("Freeing buffer..." );
    893                 GKI_freebuf(p_dev->p_buf);
    894                 p_dev->p_buf = NULL;
    895             }
    896             break;
    897 
    898         case BTA_HH_GET_PROTO_EVT:
    899             p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
    900             BTIF_TRACE_WARNING4("BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s",
    901                  p_data->hs_data.status, p_data->hs_data.handle,
    902                  p_data->hs_data.rsp_data.proto_mode,
    903                  (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) ? "Report Mode" :
    904                  (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE) ? "Boot Mode" : "Unsupported");
    905             HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,(bt_bdaddr_t*) &(p_dev->bd_addr), (bthh_status_t)p_data->hs_data.status,
    906                              (bthh_protocol_mode_t) p_data->hs_data.rsp_data.proto_mode);
    907             break;
    908 
    909         case BTA_HH_SET_PROTO_EVT:
    910             BTIF_TRACE_DEBUG2("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d",
    911                  p_data->dev_status.status, p_data->dev_status.handle);
    912             break;
    913 
    914         case BTA_HH_GET_IDLE_EVT:
    915             BTIF_TRACE_DEBUG3("BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d",
    916                  p_data->hs_data.handle, p_data->hs_data.status,
    917                  p_data->hs_data.rsp_data.idle_rate);
    918             break;
    919 
    920         case BTA_HH_SET_IDLE_EVT:
    921             BTIF_TRACE_DEBUG2("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d",
    922             p_data->dev_status.status, p_data->dev_status.handle);
    923             break;
    924 
    925         case BTA_HH_GET_DSCP_EVT:
    926             BTIF_TRACE_WARNING2("BTA_HH_GET_DSCP_EVT: status = %d, handle = %d",
    927                 p_data->dev_status.status, p_data->dev_status.handle);
    928                 len = p_data->dscp_info.descriptor.dl_len;
    929                 BTIF_TRACE_DEBUG1("BTA_HH_GET_DSCP_EVT: len = %d", len);
    930             p_dev = btif_hh_cb.p_curr_dev;
    931             if (p_dev == NULL) {
    932                 BTIF_TRACE_ERROR0("BTA_HH_GET_DSCP_EVT: No HID device is currently connected");
    933                 return;
    934             }
    935             if (p_dev->fd < 0) {
    936                 ALOGE("BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
    937                 return;
    938             }
    939             {
    940                 char *cached_name = NULL;
    941                 bt_bdname_t bdname;
    942                 bt_property_t prop_name;
    943                 BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
    944                                            sizeof(bt_bdname_t), &bdname);
    945                 if (btif_storage_get_remote_device_property(
    946                     &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS)
    947                 {
    948                     cached_name = (char *)bdname.name;
    949                 }
    950                 else
    951                 {
    952                     cached_name = "Bluetooth HID";
    953                 }
    954 
    955                 BTIF_TRACE_WARNING2("%s: name = %s", __FUNCTION__, cached_name);
    956                 bta_hh_co_send_hid_info(p_dev, cached_name,
    957                     p_data->dscp_info.vendor_id, p_data->dscp_info.product_id,
    958                     p_data->dscp_info.version,   p_data->dscp_info.ctry_code,
    959                     len, p_data->dscp_info.descriptor.dsc_list);
    960                 if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
    961                     BD_ADDR bda;
    962                     bdcpy(bda, p_dev->bd_addr.address);
    963                     tBTA_HH_DEV_DSCP_INFO dscp_info;
    964                     bt_status_t ret;
    965                     bdcpy(bda, p_dev->bd_addr.address);
    966                     btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
    967                     BTIF_TRACE_DEBUG6("BTA_HH_GET_DSCP_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x",
    968                               p_dev->bd_addr.address[0], p_dev->bd_addr.address[1],
    969                               p_dev->bd_addr.address[2],p_dev->bd_addr.address[3],
    970                               p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]);
    971                     BTA_HhAddDev(bda, p_dev->attr_mask,p_dev->sub_class,p_dev->app_id, dscp_info);
    972                     // write hid info to nvram
    973                     ret = btif_storage_add_hid_device_info(&(p_dev->bd_addr), p_dev->attr_mask,p_dev->sub_class,p_dev->app_id,
    974                                                         p_data->dscp_info.vendor_id, p_data->dscp_info.product_id,
    975                                                         p_data->dscp_info.version,   p_data->dscp_info.ctry_code,
    976                                                         len, p_data->dscp_info.descriptor.dsc_list);
    977 
    978                     ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
    979                     BTIF_TRACE_WARNING0("BTA_HH_GET_DSCP_EVT: Called add device");
    980 
    981                     //Free buffer created for dscp_info;
    982                     if (dscp_info.descriptor.dl_len >0 && dscp_info.descriptor.dsc_list != NULL)
    983                     {
    984                       GKI_freebuf(dscp_info.descriptor.dsc_list);
    985                       dscp_info.descriptor.dsc_list = NULL;
    986                       dscp_info.descriptor.dl_len=0;
    987                     }
    988                 }
    989                 else {
    990                     //Device already added.
    991                     BTIF_TRACE_WARNING1("%s: Device already added ",__FUNCTION__);
    992                 }
    993                 /*Sync HID Keyboard lockstates */
    994                 tmplen = sizeof(hid_kb_numlock_on_list)
    995                             / sizeof(tHID_KB_LIST);
    996                 for(i = 0; i< tmplen; i++)
    997                 {
    998                     if(p_data->dscp_info.vendor_id
    999                         == hid_kb_numlock_on_list[i].version_id &&
   1000                         p_data->dscp_info.product_id
   1001                         == hid_kb_numlock_on_list[i].product_id)
   1002                     {
   1003                         BTIF_TRACE_DEBUG3("%s() idx[%d] Enabling "\
   1004                             "NUMLOCK for device :: %s", __FUNCTION__,
   1005                             i, hid_kb_numlock_on_list[i].kb_name);
   1006                         /* Enable NUMLOCK by default so that numeric
   1007                             keys work from first keyboard connect */
   1008                         set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK,
   1009                                         TRUE);
   1010                         sync_lockstate_on_connect(p_dev);
   1011                         /* End Sync HID Keyboard lockstates */
   1012                         break;
   1013                     }
   1014                 }
   1015             }
   1016             break;
   1017 
   1018         case BTA_HH_ADD_DEV_EVT:
   1019             BTIF_TRACE_WARNING2("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",p_data->dev_info.status, p_data->dev_info.handle);
   1020             int i;
   1021             for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
   1022                 if (memcmp(btif_hh_cb.added_devices[i].bd_addr.address, p_data->dev_info.bda, 6) == 0) {
   1023                     if (p_data->dev_info.status == BTA_HH_OK) {
   1024                         btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
   1025                     }
   1026                     else {
   1027                         memset(btif_hh_cb.added_devices[i].bd_addr.address, 0, 6);
   1028                         btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
   1029                     }
   1030                     break;
   1031                 }
   1032             }
   1033             break;
   1034         case BTA_HH_RMV_DEV_EVT:
   1035                 BTIF_TRACE_DEBUG2("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d",
   1036                      p_data->dev_info.status, p_data->dev_info.handle);
   1037                 BTIF_TRACE_DEBUG6("BTA_HH_RMV_DEV_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x",
   1038                      p_data->dev_info.bda[0], p_data->dev_info.bda[1], p_data->dev_info.bda[2],
   1039                      p_data->dev_info.bda[3], p_data->dev_info.bda[4], p_data->dev_info.bda[5]);
   1040                 break;
   1041 
   1042 
   1043         case BTA_HH_VC_UNPLUG_EVT:
   1044                 BTIF_TRACE_DEBUG2("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d",
   1045                      p_data->dev_status.status, p_data->dev_status.handle);
   1046                 p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
   1047                 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
   1048                 if (p_dev != NULL) {
   1049                     BTIF_TRACE_DEBUG6("BTA_HH_VC_UNPLUG_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x",
   1050                          p_dev->bd_addr.address[0], p_dev->bd_addr.address[1],
   1051                          p_dev->bd_addr.address[2],p_dev->bd_addr.address[3],
   1052                          p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]);
   1053                     /* Stop the VUP timer */
   1054                     if(p_dev->vup_timer_active)
   1055                     {
   1056                         btif_hh_stop_vup_timer(&(p_dev->bd_addr));
   1057                     }
   1058                     p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
   1059                     BTIF_TRACE_DEBUG1("%s---Sending connection state change", __FUNCTION__);
   1060                     HAL_CBACK(bt_hh_callbacks, connection_state_cb,&(p_dev->bd_addr), p_dev->dev_status);
   1061                     BTIF_TRACE_DEBUG1("%s---Removing HID bond", __FUNCTION__);
   1062                     /* If it is locally initiated VUP or remote device has its major COD as
   1063                     Peripheral removed the bond.*/
   1064                     if (p_dev->local_vup  || check_cod_hid(&(p_dev->bd_addr), COD_HID_MAJOR))
   1065                     {
   1066                         p_dev->local_vup = FALSE;
   1067                         BTA_DmRemoveDevice((UINT8 *)p_dev->bd_addr.address);
   1068                     }
   1069                     else
   1070                         btif_hh_remove_device(p_dev->bd_addr);
   1071                     HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb,&(p_dev->bd_addr),
   1072                                     p_data->dev_status.status);
   1073                 }
   1074                 break;
   1075 
   1076         case BTA_HH_API_ERR_EVT  :
   1077                 ALOGI("BTA_HH API_ERR");
   1078                 break;
   1079 
   1080 
   1081 
   1082             default:
   1083                 BTIF_TRACE_WARNING2("%s: Unhandled event: %d", __FUNCTION__, event);
   1084                 break;
   1085         }
   1086 }
   1087 
   1088 /*******************************************************************************
   1089 **
   1090 ** Function         bte_hh_evt
   1091 **
   1092 ** Description      Switches context from BTE to BTIF for all HH events
   1093 **
   1094 ** Returns          void
   1095 **
   1096 *******************************************************************************/
   1097 
   1098 static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH *p_data)
   1099 {
   1100     bt_status_t status;
   1101     int param_len = 0;
   1102 
   1103     if (BTA_HH_ENABLE_EVT == event)
   1104         param_len = sizeof(tBTA_HH_STATUS);
   1105     else if (BTA_HH_OPEN_EVT == event)
   1106         param_len = sizeof(tBTA_HH_CONN);
   1107     else if (BTA_HH_DISABLE_EVT == event)
   1108         param_len = sizeof(tBTA_HH_STATUS);
   1109     else if (BTA_HH_CLOSE_EVT == event)
   1110         param_len = sizeof(tBTA_HH_CBDATA);
   1111     else if (BTA_HH_GET_DSCP_EVT == event)
   1112         param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
   1113     else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event)|| (BTA_HH_GET_IDLE_EVT == event))
   1114         param_len = sizeof(tBTA_HH_HSDATA);
   1115     else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) || (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
   1116         param_len = sizeof(tBTA_HH_CBDATA);
   1117     else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event) )
   1118         param_len = sizeof(tBTA_HH_DEV_INFO);
   1119     else if (BTA_HH_API_ERR_EVT == event)
   1120         param_len = 0;
   1121     /* switch context to btif task context (copy full union size for convenience) */
   1122     status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
   1123 
   1124     /* catch any failed context transfers */
   1125     ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
   1126 }
   1127 
   1128 /*******************************************************************************
   1129 **
   1130 ** Function         btif_hh_handle_evt
   1131 **
   1132 ** Description      Switches context for immediate callback
   1133 **
   1134 ** Returns          void
   1135 **
   1136 *******************************************************************************/
   1137 
   1138 static void btif_hh_handle_evt(UINT16 event, char *p_param)
   1139 {
   1140     bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)p_param;
   1141     BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event);
   1142     int ret;
   1143     switch(event)
   1144     {
   1145         case BTIF_HH_CONNECT_REQ_EVT:
   1146         {
   1147             ret = btif_hh_connect(bd_addr);
   1148             if(ret == BT_STATUS_SUCCESS)
   1149             {
   1150                 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_CONNECTING);
   1151             }
   1152             else
   1153                 HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_DISCONNECTED);
   1154         }
   1155         break;
   1156 
   1157         case BTIF_HH_DISCONNECT_REQ_EVT:
   1158         {
   1159             BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event);
   1160             btif_hh_disconnect(bd_addr);
   1161             HAL_CBACK(bt_hh_callbacks, connection_state_cb,bd_addr,BTHH_CONN_STATE_DISCONNECTING);
   1162         }
   1163         break;
   1164 
   1165         case BTIF_HH_VUP_REQ_EVT:
   1166         {
   1167             BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event);
   1168             ret = btif_hh_virtual_unplug(bd_addr);
   1169         }
   1170         break;
   1171 
   1172         default:
   1173         {
   1174             BTIF_TRACE_WARNING2("%s : Unknown event 0x%x", __FUNCTION__, event);
   1175         }
   1176         break;
   1177     }
   1178 }
   1179 
   1180 /*******************************************************************************
   1181 **
   1182 ** Function      btif_hh_tmr_hdlr
   1183 **
   1184 ** Description   Process timer timeout
   1185 **
   1186 ** Returns      void
   1187 *******************************************************************************/
   1188 void btif_hh_tmr_hdlr(TIMER_LIST_ENT *tle)
   1189 {
   1190     btif_hh_device_t *p_dev;
   1191     UINT8               i,j;
   1192     tBTA_HH_EVT event;
   1193     tBTA_HH p_data;
   1194     int param_len = 0;
   1195     memset(&p_data, 0, sizeof(tBTA_HH));
   1196 
   1197     BTIF_TRACE_DEBUG2("%s timer_in_use=%d",  __FUNCTION__, tle->in_use );
   1198 
   1199     for (i = 0; i < BTIF_HH_MAX_HID; i++) {
   1200         if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED)
   1201         {
   1202 
   1203             p_dev = &btif_hh_cb.devices[i];
   1204 
   1205             if (p_dev->vup_timer_active)
   1206             {
   1207                 p_dev->vup_timer_active = FALSE;
   1208                 event = BTA_HH_VC_UNPLUG_EVT;
   1209                 p_data.dev_status.status = BTHH_ERR;
   1210                 p_data.dev_status.handle = p_dev->dev_handle;
   1211                 param_len = sizeof(tBTA_HH_CBDATA);
   1212 
   1213                 /* switch context to btif task context */
   1214                 btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (void*)&p_data,
   1215                             param_len, NULL);
   1216             }
   1217         }
   1218     }
   1219 }
   1220 
   1221 /*******************************************************************************
   1222 **
   1223 ** Function         btif_hh_init
   1224 **
   1225 ** Description     initializes the hh interface
   1226 **
   1227 ** Returns         bt_status_t
   1228 **
   1229 *******************************************************************************/
   1230 static bt_status_t init( bthh_callbacks_t* callbacks )
   1231 {
   1232     UINT32 i;
   1233     BTIF_TRACE_EVENT1("%s", __FUNCTION__);
   1234 
   1235     bt_hh_callbacks = callbacks;
   1236     memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
   1237     for (i = 0; i < BTIF_HH_MAX_HID; i++){
   1238         btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
   1239     }
   1240     /* Invoke the enable service API to the core to set the appropriate service_id */
   1241     btif_enable_service(BTA_HID_SERVICE_ID);
   1242     return BT_STATUS_SUCCESS;
   1243 }
   1244 
   1245 /*******************************************************************************
   1246 **
   1247 ** Function        connect
   1248 **
   1249 ** Description     connect to hid device
   1250 **
   1251 ** Returns         bt_status_t
   1252 **
   1253 *******************************************************************************/
   1254 static bt_status_t connect( bt_bdaddr_t *bd_addr)
   1255 {
   1256     if(btif_hh_cb.status != BTIF_HH_DEV_CONNECTING)
   1257     {
   1258         btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
   1259                                  (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
   1260         return BT_STATUS_SUCCESS;
   1261     }
   1262     else
   1263         return BT_STATUS_BUSY;
   1264 }
   1265 
   1266 /*******************************************************************************
   1267 **
   1268 ** Function         disconnect
   1269 **
   1270 ** Description      disconnect from hid device
   1271 **
   1272 ** Returns         bt_status_t
   1273 **
   1274 *******************************************************************************/
   1275 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
   1276 {
   1277     CHECK_BTHH_INIT();
   1278     btif_hh_device_t *p_dev;
   1279 
   1280     if (btif_hh_cb.status == BTIF_HH_DISABLED)
   1281     {
   1282         BTIF_TRACE_WARNING2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1283         return BT_STATUS_FAIL;
   1284     }
   1285     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1286     if (p_dev != NULL)
   1287     {
   1288         return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
   1289                      (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
   1290     }
   1291     else
   1292     {
   1293         BTIF_TRACE_WARNING1("%s: Error, device  not opened.", __FUNCTION__);
   1294         return BT_STATUS_FAIL;
   1295     }
   1296 }
   1297 
   1298 /*******************************************************************************
   1299 **
   1300 ** Function         virtual_unplug
   1301 **
   1302 ** Description      Virtual UnPlug (VUP) the specified HID device.
   1303 **
   1304 ** Returns         bt_status_t
   1305 **
   1306 *******************************************************************************/
   1307 static bt_status_t virtual_unplug (bt_bdaddr_t *bd_addr)
   1308 {
   1309     CHECK_BTHH_INIT();
   1310     btif_hh_device_t *p_dev;
   1311     char bd_str[18];
   1312     sprintf(bd_str, "%02X:%02X:%02X:%02X:%02X:%02X",
   1313             bd_addr->address[0],  bd_addr->address[1],  bd_addr->address[2],  bd_addr->address[3],
   1314             bd_addr->address[4], bd_addr->address[5]);
   1315     if (btif_hh_cb.status == BTIF_HH_DISABLED)
   1316     {
   1317         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1318         return BT_STATUS_FAIL;
   1319     }
   1320     p_dev = btif_hh_find_dev_by_bda(bd_addr);
   1321     if (!p_dev)
   1322     {
   1323         BTIF_TRACE_ERROR2("%s: Error, device %s not opened.", __FUNCTION__, bd_str);
   1324         return BT_STATUS_FAIL;
   1325     }
   1326     btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT,
   1327                                  (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
   1328     return BT_STATUS_SUCCESS;
   1329 }
   1330 
   1331 
   1332 /*******************************************************************************
   1333 **
   1334 ** Function         set_info
   1335 **
   1336 ** Description      Set the HID device descriptor for the specified HID device.
   1337 **
   1338 ** Returns         bt_status_t
   1339 **
   1340 *******************************************************************************/
   1341 static bt_status_t set_info (bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info )
   1342 {
   1343     CHECK_BTHH_INIT();
   1344     tBTA_HH_DEV_DSCP_INFO dscp_info;
   1345     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1346 
   1347     BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1348          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1349     BTIF_TRACE_DEBUG6("%s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
   1350          "product_id = 0x%04x, version= 0x%04x",
   1351          __FUNCTION__, hid_info.sub_class,
   1352          hid_info.app_id, hid_info.vendor_id, hid_info.product_id,
   1353          hid_info.version);
   1354 
   1355     if (btif_hh_cb.status == BTIF_HH_DISABLED)
   1356     {
   1357         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1358         return BT_STATUS_FAIL;
   1359     }
   1360 
   1361     dscp_info.vendor_id  = hid_info.vendor_id;
   1362     dscp_info.product_id = hid_info.product_id;
   1363     dscp_info.version    = hid_info.version;
   1364     dscp_info.ctry_code  = hid_info.ctry_code;
   1365 
   1366     dscp_info.descriptor.dl_len = hid_info.dl_len;
   1367     dscp_info.descriptor.dsc_list = (UINT8 *) GKI_getbuf(dscp_info.descriptor.dl_len);
   1368     if (dscp_info.descriptor.dsc_list == NULL)
   1369     {
   1370         ALOGE("%s: Failed to allocate DSCP for CB", __FUNCTION__);
   1371         return BT_STATUS_FAIL;
   1372     }
   1373     memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
   1374 
   1375     if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask))
   1376     {
   1377         BTA_HhAddDev(*bda, hid_info.attr_mask, hid_info.sub_class,
   1378                      hid_info.app_id, dscp_info);
   1379     }
   1380 
   1381     GKI_freebuf(dscp_info.descriptor.dsc_list);
   1382 
   1383     return BT_STATUS_SUCCESS;
   1384 }
   1385 /*******************************************************************************
   1386 **
   1387 ** Function         get_idle_time
   1388 **
   1389 ** Description      Get the HID idle time
   1390 **
   1391 ** Returns         bt_status_t
   1392 **
   1393 *******************************************************************************/
   1394 static bt_status_t get_idle_time(bt_bdaddr_t *bd_addr)
   1395 {
   1396     CHECK_BTHH_INIT();
   1397     btif_hh_device_t *p_dev;
   1398     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1399 
   1400     BTIF_TRACE_DEBUG6(" addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1401          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1402 
   1403     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1404         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1405         return BT_STATUS_FAIL;
   1406     }
   1407 
   1408     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1409     if (p_dev != NULL) {
   1410         //BTA_HhGetIdle(p_dev->dev_handle);
   1411     }
   1412     else {
   1413         return BT_STATUS_FAIL;
   1414     }
   1415     return BT_STATUS_SUCCESS;
   1416 }
   1417 
   1418 /*******************************************************************************
   1419 **
   1420 ** Function         set_idle_time
   1421 **
   1422 ** Description      Set the HID idle time
   1423 **
   1424 ** Returns         bt_status_t
   1425 **
   1426 *******************************************************************************/
   1427 static bt_status_t set_idle_time (bt_bdaddr_t *bd_addr, uint8_t idle_time)
   1428 {
   1429     CHECK_BTHH_INIT();
   1430     btif_hh_device_t *p_dev;
   1431     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1432 
   1433     BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1434          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1435 
   1436     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1437         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1438         return BT_STATUS_FAIL;
   1439     }
   1440 
   1441     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1442     if (p_dev == NULL) {
   1443         BTIF_TRACE_WARNING6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1444              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1445         return BT_STATUS_FAIL;
   1446     }
   1447     else {
   1448         //BTA_HhSetIdle(p_dev->dev_handle, idle_time);
   1449     }
   1450     return BT_STATUS_SUCCESS;
   1451 }
   1452 
   1453 /*******************************************************************************
   1454 **
   1455 ** Function         get_protocol
   1456 **
   1457 ** Description      Get the HID proto mode.
   1458 **
   1459 ** Returns         bt_status_t
   1460 **
   1461 *******************************************************************************/
   1462 static bt_status_t get_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode)
   1463 {
   1464     CHECK_BTHH_INIT();
   1465     btif_hh_device_t *p_dev;
   1466     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1467 
   1468     BTIF_TRACE_DEBUG6(" addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1469          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1470 
   1471     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1472         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1473         return BT_STATUS_FAIL;
   1474     }
   1475 
   1476     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1477     if (p_dev != NULL) {
   1478         BTA_HhGetProtoMode(p_dev->dev_handle);
   1479     }
   1480     else {
   1481         return BT_STATUS_FAIL;
   1482     }
   1483     return BT_STATUS_SUCCESS;
   1484 }
   1485 
   1486 /*******************************************************************************
   1487 **
   1488 ** Function         set_protocol
   1489 **
   1490 ** Description      Set the HID proto mode.
   1491 **
   1492 ** Returns         bt_status_t
   1493 **
   1494 *******************************************************************************/
   1495 static bt_status_t set_protocol (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode)
   1496 {
   1497     CHECK_BTHH_INIT();
   1498     btif_hh_device_t *p_dev;
   1499     UINT8 proto_mode = protocolMode;
   1500     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1501 
   1502     BTIF_TRACE_DEBUG2("%s:proto_mode = %d", __FUNCTION__,protocolMode);
   1503 
   1504     BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1505          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1506 
   1507     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1508         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1509         return BT_STATUS_FAIL;
   1510     }
   1511 
   1512     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1513     if (p_dev == NULL) {
   1514         BTIF_TRACE_WARNING6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1515              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1516         return BT_STATUS_FAIL;
   1517     }
   1518     else if (protocolMode != BTA_HH_PROTO_RPT_MODE && protocolMode != BTA_HH_PROTO_BOOT_MODE) {
   1519         BTIF_TRACE_WARNING2("s: Error, device proto_mode = %d.", __FUNCTION__, proto_mode);
   1520         return BT_STATUS_FAIL;
   1521     }
   1522     else {
   1523         BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
   1524     }
   1525 
   1526 
   1527     return BT_STATUS_SUCCESS;
   1528 }
   1529 
   1530 /*******************************************************************************
   1531 **
   1532 ** Function         get_report
   1533 **
   1534 ** Description      Send a GET_REPORT to HID device.
   1535 **
   1536 ** Returns         bt_status_t
   1537 **
   1538 *******************************************************************************/
   1539 static bt_status_t get_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, uint8_t reportId, int bufferSize)
   1540 {
   1541     CHECK_BTHH_INIT();
   1542     btif_hh_device_t *p_dev;
   1543     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1544 
   1545     BTIF_TRACE_DEBUG4("%s:proto_mode = %dr_type = %d, rpt_id = %d, buf_size = %d", __FUNCTION__,
   1546           reportType, reportId, bufferSize);
   1547 
   1548     BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1549          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1550 
   1551     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1552         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1553         return BT_STATUS_FAIL;
   1554     }
   1555 
   1556 
   1557     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1558     if (p_dev == NULL) {
   1559         BTIF_TRACE_ERROR6("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1560              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1561         return BT_STATUS_FAIL;
   1562     }
   1563     else if ( ((int) reportType) <= BTA_HH_RPTT_RESRV || ((int) reportType) > BTA_HH_RPTT_FEATURE) {
   1564         BTIF_TRACE_ERROR6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1565              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1566         return BT_STATUS_FAIL;
   1567     }
   1568     else {
   1569         BTA_HhGetReport(p_dev->dev_handle, reportType,
   1570                         reportId, bufferSize);
   1571     }
   1572 
   1573     return BT_STATUS_SUCCESS;
   1574 }
   1575 
   1576 /*******************************************************************************
   1577 **
   1578 ** Function         set_report
   1579 **
   1580 ** Description      Send a SET_REPORT to HID device.
   1581 **
   1582 ** Returns         bt_status_t
   1583 **
   1584 *******************************************************************************/
   1585 static bt_status_t set_report (bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, char* report)
   1586 {
   1587     CHECK_BTHH_INIT();
   1588     btif_hh_device_t *p_dev;
   1589     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1590 
   1591     BTIF_TRACE_DEBUG2("%s:reportType = %d", __FUNCTION__,reportType);
   1592 
   1593     BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1594          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1595 
   1596 
   1597     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1598         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1599         return BT_STATUS_FAIL;
   1600     }
   1601 
   1602     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1603     if (p_dev == NULL) {
   1604         BTIF_TRACE_ERROR6("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1605              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1606         return BT_STATUS_FAIL;
   1607     }
   1608     else if ( ( (int) reportType) <= BTA_HH_RPTT_RESRV || ( (int) reportType) > BTA_HH_RPTT_FEATURE) {
   1609         BTIF_TRACE_ERROR6(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1610              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1611         return BT_STATUS_FAIL;
   1612     }
   1613     else {
   1614         int    hex_bytes_filled;
   1615         UINT8  hexbuf[200];
   1616         UINT16 len = (strlen(report) + 1) / 2;
   1617 
   1618         if (p_dev->p_buf != NULL) {
   1619             GKI_freebuf(p_dev->p_buf);
   1620         }
   1621         p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR)));
   1622         if (p_dev->p_buf == NULL) {
   1623             BTIF_TRACE_ERROR2("%s: Error, failed to allocate RPT buffer, len = %d", __FUNCTION__, len);
   1624             return BT_STATUS_FAIL;
   1625         }
   1626 
   1627         p_dev->p_buf->len = len;
   1628         p_dev->p_buf->offset = BTA_HH_MIN_OFFSET;
   1629 
   1630         /* Build a SetReport data buffer */
   1631         memset(hexbuf, 0, 200);
   1632         //TODO
   1633         hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
   1634         ALOGI("Hex bytes filled, hex value: %d", hex_bytes_filled);
   1635 
   1636         if (hex_bytes_filled) {
   1637             UINT8* pbuf_data;
   1638             pbuf_data = (UINT8*) (p_dev->p_buf + 1) + p_dev->p_buf->offset;
   1639             memcpy(pbuf_data, hexbuf, hex_bytes_filled);
   1640             BTA_HhSetReport(p_dev->dev_handle, reportType, p_dev->p_buf);
   1641         }
   1642         return BT_STATUS_SUCCESS;
   1643     }
   1644 
   1645 
   1646 }
   1647 
   1648 /*******************************************************************************
   1649 **
   1650 ** Function         send_data
   1651 **
   1652 ** Description      Send a SEND_DATA to HID device.
   1653 **
   1654 ** Returns         bt_status_t
   1655 **
   1656 *******************************************************************************/
   1657 static bt_status_t send_data (bt_bdaddr_t *bd_addr, char* data)
   1658 {
   1659     CHECK_BTHH_INIT();
   1660     btif_hh_device_t *p_dev;
   1661     BD_ADDR* bda = (BD_ADDR*) bd_addr;
   1662 
   1663     BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
   1664 
   1665     BTIF_TRACE_DEBUG6("addr = %02X:%02X:%02X:%02X:%02X:%02X",
   1666          (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1667 
   1668     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1669         BTIF_TRACE_ERROR2("%s: Error, HH status = %d", __FUNCTION__, btif_hh_cb.status);
   1670         return BT_STATUS_FAIL;
   1671     }
   1672 
   1673     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
   1674     if (p_dev == NULL) {
   1675         BTIF_TRACE_ERROR6("%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
   1676              (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
   1677         return BT_STATUS_FAIL;
   1678     }
   1679 
   1680     else {
   1681         int    hex_bytes_filled;
   1682         UINT8  hexbuf[200];
   1683         UINT16 len = (strlen(data) + 1) / 2;
   1684 
   1685         if (p_dev->p_buf != NULL) {
   1686             GKI_freebuf(p_dev->p_buf);
   1687         }
   1688         p_dev->p_buf = GKI_getbuf((UINT16) (len + BTA_HH_MIN_OFFSET + sizeof(BT_HDR)));
   1689         if (p_dev->p_buf == NULL) {
   1690             BTIF_TRACE_ERROR2("%s: Error, failed to allocate RPT buffer, len = %d", __FUNCTION__, len);
   1691             return BT_STATUS_FAIL;
   1692         }
   1693 
   1694         p_dev->p_buf->len = len;
   1695         p_dev->p_buf->offset = BTA_HH_MIN_OFFSET;
   1696 
   1697         /* Build a SetReport data buffer */
   1698         memset(hexbuf, 0, 200);
   1699         hex_bytes_filled = ascii_2_hex(data, len, hexbuf);
   1700         BTIF_TRACE_ERROR2("Hex bytes filled, hex value: %d, %d", hex_bytes_filled, len);
   1701 
   1702         if (hex_bytes_filled) {
   1703             UINT8* pbuf_data;
   1704             pbuf_data = (UINT8*) (p_dev->p_buf + 1) + p_dev->p_buf->offset;
   1705             memcpy(pbuf_data, hexbuf, hex_bytes_filled);
   1706             p_dev->p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
   1707             BTA_HhSendData(p_dev->dev_handle, *bda, p_dev->p_buf);
   1708             return BT_STATUS_SUCCESS;
   1709         }
   1710 
   1711     }
   1712     return BT_STATUS_FAIL;
   1713 }
   1714 
   1715 
   1716 /*******************************************************************************
   1717 **
   1718 ** Function         cleanup
   1719 **
   1720 ** Description      Closes the HH interface
   1721 **
   1722 ** Returns          bt_status_t
   1723 **
   1724 *******************************************************************************/
   1725 static void  cleanup( void )
   1726 {
   1727     BTIF_TRACE_EVENT1("%s", __FUNCTION__);
   1728     btif_hh_device_t *p_dev;
   1729     int i;
   1730     if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1731         BTIF_TRACE_WARNING2("%s: HH disabling or disabled already, status = %d", __FUNCTION__, btif_hh_cb.status);
   1732         return;
   1733     }
   1734     btif_hh_cb.status = BTIF_HH_DISABLING;
   1735     for (i = 0; i < BTIF_HH_MAX_HID; i++) {
   1736          p_dev = &btif_hh_cb.devices[i];
   1737          if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
   1738              BTIF_TRACE_DEBUG2("%s: Closing uhid fd = %d", __FUNCTION__, p_dev->fd);
   1739              bta_hh_co_destroy(p_dev->fd);
   1740              p_dev->fd = -1;
   1741              p_dev->hh_keep_polling = 0;
   1742              p_dev->hh_poll_thread_id = -1;
   1743          }
   1744      }
   1745 
   1746     if (bt_hh_callbacks)
   1747     {
   1748         btif_disable_service(BTA_HID_SERVICE_ID);
   1749         bt_hh_callbacks = NULL;
   1750     }
   1751 
   1752 }
   1753 
   1754 static const bthh_interface_t bthhInterface = {
   1755     sizeof(bthhInterface),
   1756     init,
   1757     connect,
   1758     disconnect,
   1759     virtual_unplug,
   1760     set_info,
   1761     get_protocol,
   1762     set_protocol,
   1763 //    get_idle_time,
   1764 //    set_idle_time,
   1765     get_report,
   1766     set_report,
   1767     send_data,
   1768     cleanup,
   1769 };
   1770 
   1771 /*******************************************************************************
   1772 **
   1773 ** Function         btif_hh_execute_service
   1774 **
   1775 ** Description      Initializes/Shuts down the service
   1776 **
   1777 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
   1778 **
   1779 *******************************************************************************/
   1780 bt_status_t btif_hh_execute_service(BOOLEAN b_enable)
   1781 {
   1782      if (b_enable)
   1783      {
   1784           /* Enable and register with BTA-HH */
   1785           BTA_HhEnable(BTA_SEC_NONE, bte_hh_evt);
   1786      }
   1787      else {
   1788          /* Disable HH */
   1789          BTA_HhDisable();
   1790      }
   1791      return BT_STATUS_SUCCESS;
   1792 }
   1793 
   1794 /*******************************************************************************
   1795 **
   1796 ** Function         btif_hh_get_interface
   1797 **
   1798 ** Description      Get the hh callback interface
   1799 **
   1800 ** Returns          bthh_interface_t
   1801 **
   1802 *******************************************************************************/
   1803 const bthh_interface_t *btif_hh_get_interface()
   1804 {
   1805     BTIF_TRACE_EVENT1("%s", __FUNCTION__);
   1806     return &bthhInterface;
   1807 }
   1808