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