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