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