Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 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   memset(dest, 0, sizeof(tBTA_HH_DEV_DSCP_INFO));
    507   dest->descriptor.dl_len = 0;
    508   if (src->descriptor.dl_len > 0) {
    509     dest->descriptor.dsc_list = (uint8_t*)osi_malloc(src->descriptor.dl_len);
    510   }
    511   memcpy(dest->descriptor.dsc_list, src->descriptor.dsc_list,
    512          src->descriptor.dl_len);
    513   dest->descriptor.dl_len = src->descriptor.dl_len;
    514   dest->vendor_id = src->vendor_id;
    515   dest->product_id = src->product_id;
    516   dest->version = src->version;
    517   dest->ctry_code = src->ctry_code;
    518   dest->ssr_max_latency = src->ssr_max_latency;
    519   dest->ssr_min_tout = src->ssr_min_tout;
    520   return true;
    521 }
    522 
    523 /*******************************************************************************
    524  *
    525  * Function         btif_hh_virtual_unplug
    526  *
    527  * Description      Virtual unplug initiated from the BTIF thread context
    528  *                  Special handling for HID mouse-
    529  *
    530  * Returns          void
    531  *
    532  ******************************************************************************/
    533 
    534 bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) {
    535   BTIF_TRACE_DEBUG("%s", __func__);
    536   btif_hh_device_t* p_dev;
    537   p_dev = btif_hh_find_dev_by_bda(*bd_addr);
    538   if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) &&
    539       (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
    540     BTIF_TRACE_DEBUG("%s Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __func__);
    541     /* start the timer */
    542     btif_hh_start_vup_timer(bd_addr);
    543     p_dev->local_vup = true;
    544     BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG);
    545     return BT_STATUS_SUCCESS;
    546   } else {
    547     BTIF_TRACE_ERROR("%s: Error, device %s not opened, status = %d", __func__,
    548                      bd_addr->ToString().c_str(), btif_hh_cb.status);
    549     if ((btif_hh_cb.pending_conn_address == *bd_addr) &&
    550        (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) {
    551           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
    552           btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
    553     }
    554     return BT_STATUS_FAIL;
    555   }
    556 }
    557 
    558 /*******************************************************************************
    559  *
    560  * Function         btif_hh_connect
    561  *
    562  * Description      connection initiated from the BTIF thread context
    563  *
    564  * Returns          int status
    565  *
    566  ******************************************************************************/
    567 
    568 bt_status_t btif_hh_connect(const RawAddress* bd_addr) {
    569   btif_hh_added_device_t* added_dev = NULL;
    570   CHECK_BTHH_INIT();
    571   BTIF_TRACE_EVENT("BTHH: %s", __func__);
    572   btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*bd_addr);
    573   if (!dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
    574     // No space for more HID device now.
    575     BTIF_TRACE_WARNING(
    576         "%s: Error, exceeded the maximum supported HID device number %d",
    577         __func__, BTIF_HH_MAX_HID);
    578     return BT_STATUS_FAIL;
    579   }
    580 
    581   for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
    582     if (btif_hh_cb.added_devices[i].bd_addr == *bd_addr) {
    583       added_dev = &btif_hh_cb.added_devices[i];
    584       LOG(WARNING) << __func__ << ": Device " << *bd_addr
    585                    << " already added, attr_mask = 0x" << std::hex
    586                    << added_dev->attr_mask;
    587     }
    588   }
    589 
    590   if (added_dev != NULL) {
    591     if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
    592       // No space for more HID device now.
    593       LOG(ERROR) << __func__ << ": Error, device " << *bd_addr
    594                  << " added but addition failed";
    595       added_dev->bd_addr = RawAddress::kEmpty;
    596       added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    597       return BT_STATUS_FAIL;
    598     }
    599   }
    600 
    601   /* Not checking the NORMALLY_Connectible flags from sdp record, and anyways
    602    sending this
    603    request from host, for subsequent user initiated connection. If the remote is
    604    not in
    605    pagescan mode, we will do 2 retries to connect before giving up */
    606   tBTA_SEC sec_mask = BTUI_HH_SECURITY;
    607   btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
    608   btif_hh_cb.pending_conn_address = *bd_addr;
    609   BTA_HhOpen(*bd_addr, BTA_HH_PROTO_RPT_MODE, sec_mask);
    610 
    611   // TODO(jpawlowski); make cback accept const and remove tmp!
    612   auto tmp = *bd_addr;
    613   HAL_CBACK(bt_hh_callbacks, connection_state_cb, &tmp,
    614             BTHH_CONN_STATE_CONNECTING);
    615   return BT_STATUS_SUCCESS;
    616 }
    617 
    618 /*******************************************************************************
    619  *
    620  * Function         btif_hh_disconnect
    621  *
    622  * Description      disconnection initiated from the BTIF thread context
    623  *
    624  * Returns          void
    625  *
    626  ******************************************************************************/
    627 
    628 void btif_hh_disconnect(RawAddress* bd_addr) {
    629   btif_hh_device_t* p_dev;
    630   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
    631   if (p_dev != NULL) {
    632     BTA_HhClose(p_dev->dev_handle);
    633   } else
    634     BTIF_TRACE_DEBUG("%s-- Error: device not connected:", __func__);
    635 }
    636 
    637 /*******************************************************************************
    638  *
    639  * Function         btif_btif_hh_setreport
    640  *
    641  * Description      setreport initiated from the BTIF thread context
    642  *
    643  * Returns          void
    644  *
    645  ******************************************************************************/
    646 void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
    647                        uint16_t size, uint8_t* report) {
    648   BT_HDR* p_buf = create_pbuf(size, report);
    649   if (p_buf == NULL) {
    650     APPL_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, size = %d",
    651                      __func__, size);
    652     return;
    653   }
    654   BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
    655 }
    656 
    657 /*******************************************************************************
    658  *
    659  * Function         btif_hh_service_registration
    660  *
    661  * Description      Registers or derigisters the hid host service
    662  *
    663  * Returns          none
    664  *
    665  ******************************************************************************/
    666 void btif_hh_service_registration(bool enable) {
    667   BTIF_TRACE_API("%s", __func__);
    668 
    669   BTIF_TRACE_API("enable = %d", enable);
    670   if (bt_hh_callbacks == NULL) {
    671     // The HID Host service was never initialized (it is either disabled or not
    672     // available in this build). We should proceed directly to changing the HID
    673     // Device service state (if needed).
    674     if (!enable) {
    675       btif_hd_service_registration();
    676     }
    677   } else if (enable) {
    678     BTA_HhEnable(BTA_SEC_ENCRYPT, bte_hh_evt);
    679   } else {
    680     btif_hh_cb.service_dereg_active = TRUE;
    681     BTA_HhDisable();
    682   }
    683 }
    684 
    685 /*****************************************************************************
    686  *   Section name (Group of functions)
    687  ****************************************************************************/
    688 
    689 /*****************************************************************************
    690  *
    691  *   btif hh api functions (no context switch)
    692  *
    693  ****************************************************************************/
    694 
    695 /*******************************************************************************
    696  *
    697  * Function         btif_hh_upstreams_evt
    698  *
    699  * Description      Executes HH UPSTREAMS events in btif context
    700  *
    701  * Returns          void
    702  *
    703  ******************************************************************************/
    704 static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
    705   tBTA_HH* p_data = (tBTA_HH*)p_param;
    706   btif_hh_device_t* p_dev = NULL;
    707   int i;
    708   int len, tmplen;
    709 
    710   BTIF_TRACE_DEBUG("%s: event=%s dereg = %d", __func__, dump_hh_event(event),
    711                    btif_hh_cb.service_dereg_active);
    712 
    713   switch (event) {
    714     case BTA_HH_ENABLE_EVT:
    715       BTIF_TRACE_DEBUG("%s: BTA_HH_ENABLE_EVT: status =%d", __func__,
    716                        p_data->status);
    717       if (p_data->status == BTA_HH_OK) {
    718         btif_hh_cb.status = BTIF_HH_ENABLED;
    719         BTIF_TRACE_DEBUG("%s--Loading added devices", __func__);
    720         /* Add hid descriptors for already bonded hid devices*/
    721         btif_storage_load_bonded_hid_info();
    722       } else {
    723         btif_hh_cb.status = BTIF_HH_DISABLED;
    724         BTIF_TRACE_WARNING(
    725             "BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d",
    726             p_data->status);
    727       }
    728       break;
    729 
    730     case BTA_HH_DISABLE_EVT:
    731       btif_hh_cb.status = BTIF_HH_DISABLED;
    732       if (btif_hh_cb.service_dereg_active) {
    733         BTIF_TRACE_DEBUG("BTA_HH_DISABLE_EVT: enabling HID Device service");
    734         btif_hd_service_registration();
    735         btif_hh_cb.service_dereg_active = FALSE;
    736       }
    737       if (p_data->status == BTA_HH_OK) {
    738         int i;
    739         // Clear the control block
    740         for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    741           alarm_free(btif_hh_cb.devices[i].vup_timer);
    742         }
    743         memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
    744         for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    745           btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
    746         }
    747       } else
    748         BTIF_TRACE_WARNING(
    749             "BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d",
    750             p_data->status);
    751       break;
    752 
    753     case BTA_HH_OPEN_EVT:
    754       BTIF_TRACE_WARNING("%s: BTA_HH_OPN_EVT: handle=%d, status =%d", __func__,
    755                          p_data->conn.handle, p_data->conn.status);
    756       btif_hh_cb.pending_conn_address = RawAddress::kEmpty;
    757       if (p_data->conn.status == BTA_HH_OK) {
    758         p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
    759         if (p_dev == NULL) {
    760           BTIF_TRACE_WARNING(
    761               "BTA_HH_OPEN_EVT: Error, cannot find device with handle %d",
    762               p_data->conn.handle);
    763           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
    764           // The connect request must come from device side and exceeded the
    765           // connected
    766           // HID device number.
    767           BTA_HhClose(p_data->conn.handle);
    768           HAL_CBACK(bt_hh_callbacks, connection_state_cb,
    769                     (RawAddress*)&p_data->conn.bda,
    770                     BTHH_CONN_STATE_DISCONNECTED);
    771         } else if (p_dev->fd < 0) {
    772           BTIF_TRACE_WARNING(
    773               "BTA_HH_OPEN_EVT: Error, failed to find the uhid driver...");
    774           p_dev->bd_addr = p_data->conn.bda;
    775           // remove the connection  and then try again to reconnect from the
    776           // mouse side to recover
    777           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
    778           BTA_HhClose(p_data->conn.handle);
    779         } else {
    780           BTIF_TRACE_WARNING(
    781               "BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle "
    782               "... %d",
    783               p_data->conn.handle);
    784           p_dev->bd_addr = p_data->conn.bda;
    785           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_CONNECTED;
    786           // Send set_idle if the peer_device is a keyboard
    787           if (check_cod(&p_data->conn.bda, COD_HID_KEYBOARD) ||
    788               check_cod(&p_data->conn.bda, COD_HID_COMBO))
    789             BTA_HhSetIdle(p_data->conn.handle, 0);
    790           btif_hh_cb.p_curr_dev =
    791               btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
    792           BTA_HhGetDscpInfo(p_data->conn.handle);
    793           p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
    794           HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
    795                     p_dev->dev_status);
    796         }
    797       } else {
    798         RawAddress* bdaddr = &p_data->conn.bda;
    799         btif_dm_hh_open_failed(bdaddr);
    800         p_dev = btif_hh_find_dev_by_bda(*bdaddr);
    801         if (p_dev != NULL) {
    802           btif_hh_stop_vup_timer(&(p_dev->bd_addr));
    803           if (p_dev->fd >= 0) {
    804             bta_hh_co_destroy(p_dev->fd);
    805             p_dev->fd = -1;
    806           }
    807           p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
    808         }
    809         HAL_CBACK(bt_hh_callbacks, connection_state_cb,
    810                   (RawAddress*)&p_data->conn.bda, BTHH_CONN_STATE_DISCONNECTED);
    811         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
    812       }
    813       break;
    814 
    815     case BTA_HH_CLOSE_EVT:
    816       BTIF_TRACE_DEBUG("BTA_HH_CLOSE_EVT: status = %d, handle = %d",
    817                        p_data->dev_status.status, p_data->dev_status.handle);
    818       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
    819       if (p_dev != NULL) {
    820         BTIF_TRACE_DEBUG("%s: uhid fd=%d local_vup=%d", __func__, p_dev->fd,
    821                          p_dev->local_vup);
    822         btif_hh_stop_vup_timer(&(p_dev->bd_addr));
    823         /* If this is a locally initiated VUP, remove the bond as ACL got
    824          *  disconnected while VUP being processed.
    825          */
    826         if (p_dev->local_vup) {
    827           p_dev->local_vup = false;
    828           BTA_DmRemoveDevice(p_dev->bd_addr);
    829         }
    830 
    831         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
    832         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
    833 
    834         if (p_dev->fd >= 0) {
    835           bta_hh_co_destroy(p_dev->fd);
    836           p_dev->fd = -1;
    837         }
    838         HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
    839                   p_dev->dev_status);
    840       } else {
    841         BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
    842                            p_data->dev_status.handle);
    843       }
    844       break;
    845 
    846     case BTA_HH_GET_RPT_EVT: {
    847       BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
    848       uint8_t* data = NULL;
    849       uint16_t len = 0;
    850 
    851       BTIF_TRACE_DEBUG("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
    852                        p_data->hs_data.status, p_data->hs_data.handle);
    853       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
    854       if (p_dev) {
    855         /* p_rpt_data is NULL in HANDSHAKE response case */
    856         if (hdr) {
    857           data = (uint8_t*)(hdr + 1) + hdr->offset;
    858           len = hdr->len;
    859           HAL_CBACK(bt_hh_callbacks, get_report_cb,
    860                     (RawAddress*)&(p_dev->bd_addr),
    861                     (bthh_status_t)p_data->hs_data.status, data, len);
    862         } else {
    863           HAL_CBACK(bt_hh_callbacks, handshake_cb,
    864                     (RawAddress*)&(p_dev->bd_addr),
    865                     (bthh_status_t)p_data->hs_data.status);
    866         }
    867       } else {
    868         BTIF_TRACE_WARNING("Error: cannot find device with handle %d",
    869                            p_data->hs_data.handle);
    870       }
    871       break;
    872     }
    873 
    874     case BTA_HH_SET_RPT_EVT:
    875       BTIF_TRACE_DEBUG("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
    876                        p_data->dev_status.status, p_data->dev_status.handle);
    877       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
    878       if (p_dev != NULL) {
    879         HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
    880                   (bthh_status_t)p_data->hs_data.status);
    881       }
    882       break;
    883 
    884     case BTA_HH_GET_PROTO_EVT:
    885       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
    886       BTIF_TRACE_WARNING(
    887           "BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s",
    888           p_data->hs_data.status, p_data->hs_data.handle,
    889           p_data->hs_data.rsp_data.proto_mode,
    890           (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE)
    891               ? "Report Mode"
    892               : (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_BOOT_MODE)
    893                     ? "Boot Mode"
    894                     : "Unsupported");
    895       if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) {
    896         HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,
    897                   (RawAddress*)&(p_dev->bd_addr),
    898                   (bthh_status_t)p_data->hs_data.status,
    899                   (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode);
    900       } else {
    901         HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
    902                   (bthh_status_t)p_data->hs_data.status);
    903       }
    904       break;
    905 
    906     case BTA_HH_SET_PROTO_EVT:
    907       BTIF_TRACE_DEBUG("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d",
    908                        p_data->dev_status.status, p_data->dev_status.handle);
    909       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
    910       if (p_dev) {
    911         HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
    912                   (bthh_status_t)p_data->hs_data.status);
    913       }
    914       break;
    915 
    916     case BTA_HH_GET_IDLE_EVT:
    917       BTIF_TRACE_DEBUG(
    918           "BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d",
    919           p_data->hs_data.handle, p_data->hs_data.status,
    920           p_data->hs_data.rsp_data.idle_rate);
    921       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
    922       HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
    923                 (bthh_status_t)p_data->hs_data.status,
    924                 p_data->hs_data.rsp_data.idle_rate);
    925       break;
    926 
    927     case BTA_HH_SET_IDLE_EVT:
    928       BTIF_TRACE_DEBUG("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d",
    929                        p_data->dev_status.status, p_data->dev_status.handle);
    930       break;
    931 
    932     case BTA_HH_GET_DSCP_EVT:
    933       len = p_data->dscp_info.descriptor.dl_len;
    934       BTIF_TRACE_DEBUG("BTA_HH_GET_DSCP_EVT: len = %d", len);
    935       p_dev = btif_hh_cb.p_curr_dev;
    936       if (p_dev == NULL) {
    937         BTIF_TRACE_ERROR(
    938             "BTA_HH_GET_DSCP_EVT: No HID device is currently connected");
    939         return;
    940       }
    941       if (p_dev->fd < 0) {
    942         LOG_ERROR(
    943             LOG_TAG,
    944             "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver...");
    945         return;
    946       }
    947       {
    948         const char* cached_name = NULL;
    949         bt_bdname_t bdname;
    950         bt_property_t prop_name;
    951         BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
    952                                    sizeof(bt_bdname_t), &bdname);
    953         if (btif_storage_get_remote_device_property(
    954                 &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS) {
    955           cached_name = (char*)bdname.name;
    956         } else {
    957           cached_name = "Bluetooth HID";
    958         }
    959 
    960         BTIF_TRACE_WARNING("%s: name = %s", __func__, cached_name);
    961         bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id,
    962                                 p_data->dscp_info.product_id,
    963                                 p_data->dscp_info.version,
    964                                 p_data->dscp_info.ctry_code, len,
    965                                 p_data->dscp_info.descriptor.dsc_list);
    966         if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
    967           tBTA_HH_DEV_DSCP_INFO dscp_info;
    968           bt_status_t ret;
    969           btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
    970           VLOG(1) << "BTA_HH_GET_DSCP_EVT:bda = " << p_dev->bd_addr;
    971           BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class,
    972                        p_dev->app_id, dscp_info);
    973           // write hid info to nvram
    974           ret = btif_storage_add_hid_device_info(
    975               &(p_dev->bd_addr), p_dev->attr_mask, p_dev->sub_class,
    976               p_dev->app_id, p_data->dscp_info.vendor_id,
    977               p_data->dscp_info.product_id, p_data->dscp_info.version,
    978               p_data->dscp_info.ctry_code, p_data->dscp_info.ssr_max_latency,
    979               p_data->dscp_info.ssr_min_tout, len,
    980               p_data->dscp_info.descriptor.dsc_list);
    981 
    982           ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret);
    983           BTIF_TRACE_WARNING("BTA_HH_GET_DSCP_EVT: Called add device");
    984 
    985           // Free buffer created for dscp_info;
    986           if (dscp_info.descriptor.dl_len > 0 &&
    987               dscp_info.descriptor.dsc_list != NULL) {
    988             osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
    989             dscp_info.descriptor.dl_len = 0;
    990           }
    991         } else {
    992           // Device already added.
    993           BTIF_TRACE_WARNING("%s: Device already added ", __func__);
    994         }
    995         /*Sync HID Keyboard lockstates */
    996         tmplen = sizeof(hid_kb_numlock_on_list) / sizeof(tHID_KB_LIST);
    997         for (i = 0; i < tmplen; i++) {
    998           if (p_data->dscp_info.vendor_id ==
    999                   hid_kb_numlock_on_list[i].version_id &&
   1000               p_data->dscp_info.product_id ==
   1001                   hid_kb_numlock_on_list[i].product_id) {
   1002             BTIF_TRACE_DEBUG(
   1003                 "%s() idx[%d] Enabling "
   1004                 "NUMLOCK for device :: %s",
   1005                 __func__, i, hid_kb_numlock_on_list[i].kb_name);
   1006             /* Enable NUMLOCK by default so that numeric
   1007                 keys work from first keyboard connect */
   1008             set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, true);
   1009             sync_lockstate_on_connect(p_dev);
   1010             /* End Sync HID Keyboard lockstates */
   1011             break;
   1012           }
   1013         }
   1014       }
   1015       break;
   1016 
   1017     case BTA_HH_ADD_DEV_EVT:
   1018       BTIF_TRACE_WARNING("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d",
   1019                          p_data->dev_info.status, p_data->dev_info.handle);
   1020       int i;
   1021       for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
   1022         if (btif_hh_cb.added_devices[i].bd_addr == p_data->dev_info.bda) {
   1023           if (p_data->dev_info.status == BTA_HH_OK) {
   1024             btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
   1025           } else {
   1026             btif_hh_cb.added_devices[i].bd_addr = RawAddress::kEmpty;
   1027             btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
   1028           }
   1029           break;
   1030         }
   1031       }
   1032       break;
   1033     case BTA_HH_RMV_DEV_EVT:
   1034       BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d",
   1035                        p_data->dev_info.status, p_data->dev_info.handle);
   1036       VLOG(1) << "BTA_HH_RMV_DEV_EVT:bda = " << p_data->dev_info.bda;
   1037       break;
   1038 
   1039     case BTA_HH_VC_UNPLUG_EVT:
   1040       BTIF_TRACE_DEBUG("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d",
   1041                        p_data->dev_status.status, p_data->dev_status.handle);
   1042       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
   1043       btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
   1044       if (p_dev != NULL) {
   1045         VLOG(1) << "BTA_HH_VC_UNPLUG_EVT:bda = " << p_dev->bd_addr;
   1046 
   1047         /* Stop the VUP timer */
   1048         btif_hh_stop_vup_timer(&(p_dev->bd_addr));
   1049         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
   1050         BTIF_TRACE_DEBUG("%s---Sending connection state change", __func__);
   1051         HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
   1052                   p_dev->dev_status);
   1053         BTIF_TRACE_DEBUG("%s---Removing HID bond", __func__);
   1054         /* If it is locally initiated VUP or remote device has its major COD as
   1055         Peripheral removed the bond.*/
   1056         if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) {
   1057           p_dev->local_vup = false;
   1058           BTA_DmRemoveDevice(p_dev->bd_addr);
   1059         } else
   1060           btif_hh_remove_device(p_dev->bd_addr);
   1061         HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, &(p_dev->bd_addr),
   1062                   (bthh_status_t)p_data->dev_status.status);
   1063       }
   1064       break;
   1065 
   1066     case BTA_HH_API_ERR_EVT:
   1067       LOG_INFO(LOG_TAG, "BTA_HH API_ERR");
   1068       break;
   1069 
   1070     default:
   1071       BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
   1072       break;
   1073   }
   1074 }
   1075 
   1076 /*******************************************************************************
   1077  *
   1078  * Function         bte_hh_evt
   1079  *
   1080  * Description      Switches context from BTE to BTIF for all HH events
   1081  *
   1082  * Returns          void
   1083  *
   1084  ******************************************************************************/
   1085 
   1086 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
   1087   bt_status_t status;
   1088   int param_len = 0;
   1089 
   1090   if (BTA_HH_ENABLE_EVT == event)
   1091     param_len = sizeof(tBTA_HH_STATUS);
   1092   else if (BTA_HH_OPEN_EVT == event)
   1093     param_len = sizeof(tBTA_HH_CONN);
   1094   else if (BTA_HH_DISABLE_EVT == event)
   1095     param_len = sizeof(tBTA_HH_STATUS);
   1096   else if (BTA_HH_CLOSE_EVT == event)
   1097     param_len = sizeof(tBTA_HH_CBDATA);
   1098   else if (BTA_HH_GET_DSCP_EVT == event)
   1099     param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
   1100   else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
   1101            (BTA_HH_GET_IDLE_EVT == event))
   1102     param_len = sizeof(tBTA_HH_HSDATA);
   1103   else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
   1104            (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
   1105     param_len = sizeof(tBTA_HH_CBDATA);
   1106   else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
   1107     param_len = sizeof(tBTA_HH_DEV_INFO);
   1108   else if (BTA_HH_API_ERR_EVT == event)
   1109     param_len = 0;
   1110   /* switch context to btif task context (copy full union size for convenience)
   1111    */
   1112   status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
   1113                                  (char*)p_data, param_len, NULL);
   1114 
   1115   /* catch any failed context transfers */
   1116   ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
   1117 }
   1118 
   1119 /*******************************************************************************
   1120  *
   1121  * Function         btif_hh_handle_evt
   1122  *
   1123  * Description      Switches context for immediate callback
   1124  *
   1125  * Returns          void
   1126  *
   1127  ******************************************************************************/
   1128 
   1129 static void btif_hh_handle_evt(uint16_t event, char* p_param) {
   1130   RawAddress* bd_addr = (RawAddress*)p_param;
   1131   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
   1132   int ret;
   1133   switch (event) {
   1134     case BTIF_HH_CONNECT_REQ_EVT: {
   1135       ret = btif_hh_connect(bd_addr);
   1136       if (ret == BT_STATUS_SUCCESS) {
   1137         HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
   1138                   BTHH_CONN_STATE_CONNECTING);
   1139       } else
   1140         HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
   1141                   BTHH_CONN_STATE_DISCONNECTED);
   1142     } break;
   1143 
   1144     case BTIF_HH_DISCONNECT_REQ_EVT: {
   1145       BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
   1146       btif_hh_disconnect(bd_addr);
   1147       HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
   1148                 BTHH_CONN_STATE_DISCONNECTING);
   1149     } break;
   1150 
   1151     case BTIF_HH_VUP_REQ_EVT: {
   1152       BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
   1153       ret = btif_hh_virtual_unplug(bd_addr);
   1154     } break;
   1155 
   1156     default: {
   1157       BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
   1158     } break;
   1159   }
   1160 }
   1161 
   1162 /*******************************************************************************
   1163  *
   1164  * Function      btif_hh_timer_timeout
   1165  *
   1166  * Description   Process timer timeout
   1167  *
   1168  * Returns      void
   1169  ******************************************************************************/
   1170 void btif_hh_timer_timeout(void* data) {
   1171   btif_hh_device_t* p_dev = (btif_hh_device_t*)data;
   1172   tBTA_HH_EVT event = BTA_HH_VC_UNPLUG_EVT;
   1173   tBTA_HH p_data;
   1174   int param_len = sizeof(tBTA_HH_CBDATA);
   1175 
   1176   BTIF_TRACE_DEBUG("%s", __func__);
   1177   if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) return;
   1178 
   1179   memset(&p_data, 0, sizeof(tBTA_HH));
   1180   p_data.dev_status.status = BTHH_ERR;
   1181   p_data.dev_status.handle = p_dev->dev_handle;
   1182 
   1183   /* switch context to btif task context */
   1184   btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event, (char*)&p_data,
   1185                         param_len, NULL);
   1186 }
   1187 
   1188 /*******************************************************************************
   1189  *
   1190  * Function         btif_hh_init
   1191  *
   1192  * Description     initializes the hh interface
   1193  *
   1194  * Returns         bt_status_t
   1195  *
   1196  ******************************************************************************/
   1197 static bt_status_t init(bthh_callbacks_t* callbacks) {
   1198   uint32_t i;
   1199   BTIF_TRACE_EVENT("%s", __func__);
   1200 
   1201   bt_hh_callbacks = callbacks;
   1202   memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
   1203   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
   1204     btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
   1205   }
   1206   /* Invoke the enable service API to the core to set the appropriate service_id
   1207    */
   1208   btif_enable_service(BTA_HID_SERVICE_ID);
   1209   return BT_STATUS_SUCCESS;
   1210 }
   1211 
   1212 /*******************************************************************************
   1213  *
   1214  * Function        connect
   1215  *
   1216  * Description     connect to hid device
   1217  *
   1218  * Returns         bt_status_t
   1219  *
   1220  ******************************************************************************/
   1221 static bt_status_t connect(RawAddress* bd_addr) {
   1222   if (btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) {
   1223     btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
   1224                           (char*)bd_addr, sizeof(RawAddress), NULL);
   1225     return BT_STATUS_SUCCESS;
   1226   } else
   1227     return BT_STATUS_BUSY;
   1228 }
   1229 
   1230 /*******************************************************************************
   1231  *
   1232  * Function         disconnect
   1233  *
   1234  * Description      disconnect from hid device
   1235  *
   1236  * Returns         bt_status_t
   1237  *
   1238  ******************************************************************************/
   1239 static bt_status_t disconnect(RawAddress* bd_addr) {
   1240   CHECK_BTHH_INIT();
   1241   BTIF_TRACE_EVENT("BTHH: %s", __func__);
   1242   btif_hh_device_t* p_dev;
   1243 
   1244   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1245     BTIF_TRACE_WARNING("%s: Error, HH status = %d", __func__,
   1246                        btif_hh_cb.status);
   1247     return BT_STATUS_FAIL;
   1248   }
   1249   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1250   if (p_dev != NULL) {
   1251     return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
   1252                                  (char*)bd_addr, sizeof(RawAddress), NULL);
   1253   } else {
   1254     BTIF_TRACE_WARNING("%s: Error, device  not opened.", __func__);
   1255     return BT_STATUS_FAIL;
   1256   }
   1257 }
   1258 
   1259 /*******************************************************************************
   1260  *
   1261  * Function         virtual_unplug
   1262  *
   1263  * Description      Virtual UnPlug (VUP) the specified HID device.
   1264  *
   1265  * Returns         bt_status_t
   1266  *
   1267  ******************************************************************************/
   1268 static bt_status_t virtual_unplug(RawAddress* bd_addr) {
   1269   CHECK_BTHH_INIT();
   1270   BTIF_TRACE_EVENT("BTHH: %s", __func__);
   1271   btif_hh_device_t* p_dev;
   1272   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1273     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1274     return BT_STATUS_FAIL;
   1275   }
   1276   p_dev = btif_hh_find_dev_by_bda(*bd_addr);
   1277   if (!p_dev) {
   1278     BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __func__,
   1279                      bd_addr->ToString().c_str());
   1280     return BT_STATUS_FAIL;
   1281   }
   1282   btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, (char*)bd_addr,
   1283                         sizeof(RawAddress), NULL);
   1284   return BT_STATUS_SUCCESS;
   1285 }
   1286 
   1287 /*******************************************************************************
   1288 **
   1289 ** Function         get_idle_time
   1290 **
   1291 ** Description      Get the HID idle time
   1292 **
   1293 ** Returns         bt_status_t
   1294 **
   1295 *******************************************************************************/
   1296 static bt_status_t get_idle_time(RawAddress* bd_addr) {
   1297   CHECK_BTHH_INIT();
   1298 
   1299   BTIF_TRACE_DEBUG("%s: addr = %s", __func__, bd_addr->ToString().c_str());
   1300 
   1301   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1302     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1303     return BT_STATUS_FAIL;
   1304   }
   1305 
   1306   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1307   if (p_dev == NULL) return BT_STATUS_FAIL;
   1308 
   1309   BTA_HhGetIdle(p_dev->dev_handle);
   1310   return BT_STATUS_SUCCESS;
   1311 }
   1312 
   1313 /*******************************************************************************
   1314 **
   1315 ** Function         set_idle_time
   1316 **
   1317 ** Description      Set the HID idle time
   1318 **
   1319 ** Returns         bt_status_t
   1320 **
   1321 *******************************************************************************/
   1322 static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) {
   1323   CHECK_BTHH_INIT();
   1324 
   1325   BTIF_TRACE_DEBUG("%s: addr = %s, idle time = %d", __func__,
   1326                    bd_addr->ToString().c_str(), idle_time);
   1327 
   1328   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1329     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1330     return BT_STATUS_FAIL;
   1331   }
   1332 
   1333   btif_hh_device_t* p_dev = p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1334   if (p_dev == NULL) {
   1335     BTIF_TRACE_WARNING("%s: addr = %s not opened", __func__,
   1336                        bd_addr->ToString().c_str());
   1337     return BT_STATUS_FAIL;
   1338   }
   1339 
   1340   BTA_HhSetIdle(p_dev->dev_handle, idle_time);
   1341   return BT_STATUS_SUCCESS;
   1342 }
   1343 
   1344 /*******************************************************************************
   1345  *
   1346  * Function         set_info
   1347  *
   1348  * Description      Set the HID device descriptor for the specified HID device.
   1349  *
   1350  * Returns         bt_status_t
   1351  *
   1352  ******************************************************************************/
   1353 static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) {
   1354   CHECK_BTHH_INIT();
   1355   tBTA_HH_DEV_DSCP_INFO dscp_info;
   1356 
   1357   VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
   1358   BTIF_TRACE_DEBUG(
   1359       "BTHH: %s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
   1360       "product_id = 0x%04x, version= 0x%04x",
   1361       __func__, hid_info.sub_class, hid_info.app_id, hid_info.vendor_id,
   1362       hid_info.product_id, hid_info.version);
   1363 
   1364   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1365     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1366     return BT_STATUS_FAIL;
   1367   }
   1368 
   1369   memset(&dscp_info, 0, sizeof(dscp_info));
   1370   dscp_info.vendor_id = hid_info.vendor_id;
   1371   dscp_info.product_id = hid_info.product_id;
   1372   dscp_info.version = hid_info.version;
   1373   dscp_info.ctry_code = hid_info.ctry_code;
   1374 
   1375   dscp_info.descriptor.dl_len = hid_info.dl_len;
   1376   dscp_info.descriptor.dsc_list =
   1377       (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len);
   1378   memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
   1379 
   1380   if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) {
   1381     BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class,
   1382                  hid_info.app_id, dscp_info);
   1383   }
   1384 
   1385   osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
   1386 
   1387   return BT_STATUS_SUCCESS;
   1388 }
   1389 
   1390 /*******************************************************************************
   1391  *
   1392  * Function         get_protocol
   1393  *
   1394  * Description      Get the HID proto mode.
   1395  *
   1396  * Returns         bt_status_t
   1397  *
   1398  ******************************************************************************/
   1399 static bt_status_t get_protocol(RawAddress* bd_addr,
   1400                                 UNUSED_ATTR bthh_protocol_mode_t protocolMode) {
   1401   CHECK_BTHH_INIT();
   1402 
   1403   VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
   1404 
   1405   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1406     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1407     return BT_STATUS_FAIL;
   1408   }
   1409 
   1410   btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1411   if (!p_dev) return BT_STATUS_FAIL;
   1412 
   1413   BTA_HhGetProtoMode(p_dev->dev_handle);
   1414   return BT_STATUS_SUCCESS;
   1415 }
   1416 
   1417 /*******************************************************************************
   1418  *
   1419  * Function         set_protocol
   1420  *
   1421  * Description      Set the HID proto mode.
   1422  *
   1423  * Returns         bt_status_t
   1424  *
   1425  ******************************************************************************/
   1426 static bt_status_t set_protocol(RawAddress* bd_addr,
   1427                                 bthh_protocol_mode_t protocolMode) {
   1428   CHECK_BTHH_INIT();
   1429   btif_hh_device_t* p_dev;
   1430   uint8_t proto_mode = protocolMode;
   1431 
   1432   VLOG(1) << __func__ << " BTHH: proto_mod=" << protocolMode
   1433           << " addr = " << *bd_addr;
   1434 
   1435   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1436     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1437     return BT_STATUS_FAIL;
   1438   }
   1439 
   1440   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1441   if (p_dev == NULL) {
   1442     LOG(WARNING) << " Error, device" << *bd_addr << " not opened";
   1443     return BT_STATUS_FAIL;
   1444   } else if (protocolMode != BTA_HH_PROTO_RPT_MODE &&
   1445              protocolMode != BTA_HH_PROTO_BOOT_MODE) {
   1446     BTIF_TRACE_WARNING("%s: Error, device proto_mode = %d.", __func__,
   1447                        proto_mode);
   1448     return BT_STATUS_FAIL;
   1449   } else {
   1450     BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode);
   1451   }
   1452 
   1453   return BT_STATUS_SUCCESS;
   1454 }
   1455 
   1456 /*******************************************************************************
   1457  *
   1458  * Function         get_report
   1459  *
   1460  * Description      Send a GET_REPORT to HID device.
   1461  *
   1462  * Returns         bt_status_t
   1463  *
   1464  ******************************************************************************/
   1465 static bt_status_t get_report(RawAddress* bd_addr,
   1466                               bthh_report_type_t reportType, uint8_t reportId,
   1467                               int bufferSize) {
   1468   CHECK_BTHH_INIT();
   1469   btif_hh_device_t* p_dev;
   1470 
   1471   VLOG(1) << __func__ << " BTHH: r_type = " << reportType
   1472           << ", rpt_id = " << reportId << ", buf_size = " << bufferSize
   1473           << " addr = " << *bd_addr;
   1474 
   1475   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1476     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1477     return BT_STATUS_FAIL;
   1478   }
   1479 
   1480   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1481   if (p_dev == NULL) {
   1482     LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
   1483     return BT_STATUS_FAIL;
   1484   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
   1485              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
   1486     LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
   1487     return BT_STATUS_FAIL;
   1488   } else {
   1489     BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize);
   1490   }
   1491 
   1492   return BT_STATUS_SUCCESS;
   1493 }
   1494 
   1495 /*******************************************************************************
   1496  *
   1497  * Function         set_report
   1498  *
   1499  * Description      Send a SET_REPORT to HID device.
   1500  *
   1501  * Returns         bt_status_t
   1502  *
   1503  ******************************************************************************/
   1504 static bt_status_t set_report(RawAddress* bd_addr,
   1505                               bthh_report_type_t reportType, char* report) {
   1506   CHECK_BTHH_INIT();
   1507   btif_hh_device_t* p_dev;
   1508 
   1509   VLOG(1) << __func__ << " BTHH: reportType=" << reportType
   1510           << " addr=" << *bd_addr;
   1511 
   1512   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1513     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1514     return BT_STATUS_FAIL;
   1515   }
   1516 
   1517   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1518   if (p_dev == NULL) {
   1519     LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
   1520     return BT_STATUS_FAIL;
   1521   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
   1522              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
   1523     LOG(ERROR) << " Error, report type=" << +reportType << " not supported";
   1524     return BT_STATUS_FAIL;
   1525   } else {
   1526     int hex_bytes_filled;
   1527     size_t len = (strlen(report) + 1) / 2;
   1528     uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
   1529 
   1530     /* Build a SetReport data buffer */
   1531     // TODO
   1532     hex_bytes_filled = ascii_2_hex(report, len, hexbuf);
   1533     LOG_INFO(LOG_TAG, "Hex bytes filled, hex value: %d", hex_bytes_filled);
   1534     if (hex_bytes_filled) {
   1535       BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
   1536       if (p_buf == NULL) {
   1537         BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
   1538                          __func__, hex_bytes_filled);
   1539         osi_free(hexbuf);
   1540         return BT_STATUS_FAIL;
   1541       }
   1542       BTA_HhSetReport(p_dev->dev_handle, reportType, p_buf);
   1543       osi_free(hexbuf);
   1544       return BT_STATUS_SUCCESS;
   1545     }
   1546     osi_free(hexbuf);
   1547     return BT_STATUS_FAIL;
   1548   }
   1549 }
   1550 
   1551 /*******************************************************************************
   1552  *
   1553  * Function         send_data
   1554  *
   1555  * Description      Send a SEND_DATA to HID device.
   1556  *
   1557  * Returns         bt_status_t
   1558  *
   1559  ******************************************************************************/
   1560 static bt_status_t send_data(RawAddress* bd_addr, char* data) {
   1561   CHECK_BTHH_INIT();
   1562   btif_hh_device_t* p_dev;
   1563 
   1564   VLOG(1) << __func__ << " addr=" << *bd_addr;
   1565 
   1566   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1567     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
   1568     return BT_STATUS_FAIL;
   1569   }
   1570 
   1571   p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   1572   if (p_dev == NULL) {
   1573     LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
   1574     return BT_STATUS_FAIL;
   1575   }
   1576 
   1577   else {
   1578     int hex_bytes_filled;
   1579     size_t len = (strlen(data) + 1) / 2;
   1580     uint8_t* hexbuf = (uint8_t*)osi_calloc(len);
   1581 
   1582     /* Build a SendData data buffer */
   1583     hex_bytes_filled = ascii_2_hex(data, len, hexbuf);
   1584     BTIF_TRACE_ERROR("Hex bytes filled, hex value: %d, %d", hex_bytes_filled,
   1585                      len);
   1586 
   1587     if (hex_bytes_filled) {
   1588       BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf);
   1589       if (p_buf == NULL) {
   1590         BTIF_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, len = %d",
   1591                          __func__, hex_bytes_filled);
   1592         osi_free(hexbuf);
   1593         return BT_STATUS_FAIL;
   1594       }
   1595       p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
   1596       BTA_HhSendData(p_dev->dev_handle, *bd_addr, p_buf);
   1597       osi_free(hexbuf);
   1598       return BT_STATUS_SUCCESS;
   1599     }
   1600     osi_free(hexbuf);
   1601     return BT_STATUS_FAIL;
   1602   }
   1603 }
   1604 
   1605 /*******************************************************************************
   1606  *
   1607  * Function         cleanup
   1608  *
   1609  * Description      Closes the HH interface
   1610  *
   1611  * Returns          bt_status_t
   1612  *
   1613  ******************************************************************************/
   1614 static void cleanup(void) {
   1615   BTIF_TRACE_EVENT("%s", __func__);
   1616   btif_hh_device_t* p_dev;
   1617   int i;
   1618   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
   1619     BTIF_TRACE_WARNING("%s: HH disabling or disabled already, status = %d",
   1620                        __func__, btif_hh_cb.status);
   1621     return;
   1622   }
   1623   if (bt_hh_callbacks) {
   1624     btif_hh_cb.status = BTIF_HH_DISABLING;
   1625     /* update flag, not to enable hid device service now as BT is switching off
   1626      */
   1627     btif_hh_cb.service_dereg_active = FALSE;
   1628     btif_disable_service(BTA_HID_SERVICE_ID);
   1629     bt_hh_callbacks = NULL;
   1630   }
   1631   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
   1632     p_dev = &btif_hh_cb.devices[i];
   1633     if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
   1634       BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __func__, p_dev->fd);
   1635       if (p_dev->fd >= 0) {
   1636         bta_hh_co_destroy(p_dev->fd);
   1637         p_dev->fd = -1;
   1638       }
   1639       p_dev->hh_keep_polling = 0;
   1640       p_dev->hh_poll_thread_id = -1;
   1641     }
   1642   }
   1643 
   1644 }
   1645 
   1646 static const bthh_interface_t bthhInterface = {
   1647     sizeof(bthhInterface),
   1648     init,
   1649     connect,
   1650     disconnect,
   1651     virtual_unplug,
   1652     set_info,
   1653     get_protocol,
   1654     set_protocol,
   1655     get_idle_time,
   1656     set_idle_time,
   1657     get_report,
   1658     set_report,
   1659     send_data,
   1660     cleanup,
   1661 };
   1662 
   1663 /*******************************************************************************
   1664  *
   1665  * Function         btif_hh_execute_service
   1666  *
   1667  * Description      Initializes/Shuts down the service
   1668  *
   1669  * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
   1670  *
   1671  ******************************************************************************/
   1672 bt_status_t btif_hh_execute_service(bool b_enable) {
   1673   if (b_enable) {
   1674     /* Enable and register with BTA-HH */
   1675     BTA_HhEnable(BTUI_HH_SECURITY, bte_hh_evt);
   1676   } else {
   1677     /* Disable HH */
   1678     BTA_HhDisable();
   1679   }
   1680   return BT_STATUS_SUCCESS;
   1681 }
   1682 
   1683 /*******************************************************************************
   1684  *
   1685  * Function         btif_hh_get_interface
   1686  *
   1687  * Description      Get the hh callback interface
   1688  *
   1689  * Returns          bthh_interface_t
   1690  *
   1691  ******************************************************************************/
   1692 const bthh_interface_t* btif_hh_get_interface() {
   1693   BTIF_TRACE_EVENT("%s", __func__);
   1694   return &bthhInterface;
   1695 }
   1696