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