Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55c7cf0d authored by Archie Pusaka's avatar Archie Pusaka
Browse files

hid: separate the struct accessed by the uhid thread

The uhid thread shared the same resource with btif and main thread,
making it easier to crash. This can be prevented by making sure the
uhid thread has an exclusive access to a part of the memory that is
not controlled by the other threads.

This CL splits the information needed by the uhid thread into its own
struct, btif_hh_uhid_t. However, this is only a mechanical refactor,
the btif thread can still access this part of memory like before.
A future CL shall make sure that uhid thread fully manages the struct
btif_hh_uhid_t and has exclusive access to it.

Bug: 291522341
Test: mmm packages/modules/Bluetooth
Flag: EXEMPT, mechanical refactor

Change-Id: Ied37b336a0d6b36a2b1c438381c6388bfce13c1b
parent 941bb283
Loading
Loading
Loading
Loading
+91 −87
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ void uhid_set_non_blocking(int fd) {
    log::verbose("Setting non-blocking flag failed ({})", strerror(errno));
}

static bool uhid_feature_req_handler(btif_hh_device_t* p_dev,
static bool uhid_feature_req_handler(btif_hh_uhid_t* p_uhid,
                                     struct uhid_feature_req& req) {
  log::debug("Report type = {}, id = {}", req.rtype, req.rnum);

@@ -77,7 +77,7 @@ static bool uhid_feature_req_handler(btif_hh_device_t* p_dev,
    return false;
  }

  if (p_dev->get_rpt_id_queue == nullptr) {
  if (p_uhid->get_rpt_id_queue == nullptr) {
    log::error("Queue is not initialized");
    return false;
  }
@@ -85,18 +85,18 @@ static bool uhid_feature_req_handler(btif_hh_device_t* p_dev,
  uint32_t* context = (uint32_t*)osi_malloc(sizeof(uint32_t));
  *context = req.id;

  if (!fixed_queue_try_enqueue(p_dev->get_rpt_id_queue, (void*)context)) {
  if (!fixed_queue_try_enqueue(p_uhid->get_rpt_id_queue, (void*)context)) {
    osi_free(context);
    log::error("Queue is full, dropping event {}", req.id);
    return false;
  }

  btif_hh_getreport(p_dev, map_rtype_uhid_hh[req.rtype], req.rnum, 0);
  btif_hh_getreport(p_uhid, map_rtype_uhid_hh[req.rtype], req.rnum, 0);
  return true;
}

#if ENABLE_UHID_SET_REPORT
static bool uhid_set_report_req_handler(btif_hh_device_t* p_dev,
static bool uhid_set_report_req_handler(btif_hh_uhid_t* p_uhid,
                                        struct uhid_set_report_req& req) {
  log::debug("Report type = {}, id = {}", req.rtype, req.rnum);

@@ -105,7 +105,7 @@ static bool uhid_set_report_req_handler(btif_hh_device_t* p_dev,
    return false;
  }

  if (p_dev->set_rpt_id_queue == nullptr) {
  if (p_uhid->set_rpt_id_queue == nullptr) {
    log::error("Queue is not initialized");
    return false;
  }
@@ -113,13 +113,13 @@ static bool uhid_set_report_req_handler(btif_hh_device_t* p_dev,
  uint32_t* context = (uint32_t*)osi_malloc(sizeof(uint32_t));
  *context = req.id;

  if (!fixed_queue_try_enqueue(p_dev->set_rpt_id_queue, (void*)context)) {
  if (!fixed_queue_try_enqueue(p_uhid->set_rpt_id_queue, (void*)context)) {
    osi_free(context);
    log::error("Queue is full, dropping event {}", req.id);
    return false;
  }

  btif_hh_setreport(p_dev, map_rtype_uhid_hh[req.rtype], req.size, req.data);
  btif_hh_setreport(p_uhid, map_rtype_uhid_hh[req.rtype], req.size, req.data);
  return true;
}
#endif  // ENABLE_UHID_SET_REPORT
@@ -142,14 +142,14 @@ static int uhid_write(int fd, const struct uhid_event* ev) {
}

/* Internal function to parse the events received from UHID driver*/
static int uhid_read_event(btif_hh_device_t* p_dev) {
  log::assert_that(p_dev != nullptr, "assert failed: p_dev != nullptr");
static int uhid_read_event(btif_hh_uhid_t* p_uhid) {
  log::assert_that(p_uhid != nullptr, "assert failed: p_uhid != nullptr");

  struct uhid_event ev;
  memset(&ev, 0, sizeof(ev));

  ssize_t ret;
  OSI_NO_INTR(ret = read(p_dev->fd, &ev, sizeof(ev)));
  OSI_NO_INTR(ret = read(p_uhid->fd, &ev, sizeof(ev)));

  if (ret == 0) {
    log::error("Read HUP on uhid-cdev {}", strerror(errno));
@@ -162,19 +162,19 @@ static int uhid_read_event(btif_hh_device_t* p_dev) {
  switch (ev.type) {
    case UHID_START:
      log::verbose("UHID_START from uhid-dev\n");
      p_dev->ready_for_data = true;
      p_uhid->ready_for_data = true;
      break;
    case UHID_STOP:
      log::verbose("UHID_STOP from uhid-dev\n");
      p_dev->ready_for_data = false;
      p_uhid->ready_for_data = false;
      break;
    case UHID_OPEN:
      log::verbose("UHID_OPEN from uhid-dev\n");
      p_dev->ready_for_data = true;
      p_uhid->ready_for_data = true;
      break;
    case UHID_CLOSE:
      log::verbose("UHID_CLOSE from uhid-dev\n");
      p_dev->ready_for_data = false;
      p_uhid->ready_for_data = false;
      break;
    case UHID_OUTPUT:
      if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.output))) {
@@ -188,10 +188,10 @@ static int uhid_read_event(btif_hh_device_t* p_dev) {
      // Send SET_REPORT with feature report if the report type in output event
      // is FEATURE
      if (ev.u.output.rtype == UHID_FEATURE_REPORT)
        btif_hh_setreport(p_dev, BTHH_FEATURE_REPORT, ev.u.output.size,
        btif_hh_setreport(p_uhid, BTHH_FEATURE_REPORT, ev.u.output.size,
                          ev.u.output.data);
      else if (ev.u.output.rtype == UHID_OUTPUT_REPORT)
        btif_hh_senddata(p_dev, ev.u.output.size, ev.u.output.data);
        btif_hh_senddata(p_uhid, ev.u.output.size, ev.u.output.data);
      else
        log::error("UHID_OUTPUT: Invalid report type = {}", ev.u.output.rtype);
      break;
@@ -211,7 +211,7 @@ static int uhid_read_event(btif_hh_device_t* p_dev) {
        return -EFAULT;
      }

      if (!uhid_feature_req_handler(p_dev, ev.u.feature)) {
      if (!uhid_feature_req_handler(p_uhid, ev.u.feature)) {
        return -EFAULT;
      }

@@ -225,7 +225,7 @@ static int uhid_read_event(btif_hh_device_t* p_dev) {
        return -EFAULT;
      }

      if (!uhid_set_report_req_handler(p_dev, ev.u.set_report)) {
      if (!uhid_set_report_req_handler(p_uhid, ev.u.set_report)) {
        return -EFAULT;
      }
      break;
@@ -265,42 +265,43 @@ static inline pthread_t create_thread(void* (*start_routine)(void*),
}

/* Internal function to close the UHID driver*/
static void uhid_fd_close(btif_hh_device_t* p_dev) {
  if (p_dev->fd >= 0) {
static void uhid_fd_close(btif_hh_uhid_t* p_uhid) {
  if (p_uhid->fd >= 0) {
    struct uhid_event ev = {};
    ev.type = UHID_DESTROY;
    uhid_write(p_dev->fd, &ev);
    log::debug("Closing fd={}, addr:{}", p_dev->fd, p_dev->link_spec);
    close(p_dev->fd);
    p_dev->fd = -1;
    uhid_write(p_uhid->fd, &ev);
    log::debug("Closing fd={}, addr:{}", p_uhid->fd, p_uhid->link_spec);
    close(p_uhid->fd);
    p_uhid->fd = -1;
  }
}

/* Internal function to open the UHID driver*/
static bool uhid_fd_open(btif_hh_device_t* p_dev) {
  if (p_dev->fd < 0) {
    p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
    if (p_dev->fd < 0) {
  if (p_dev->uhid.fd < 0) {
    p_dev->uhid.fd = open(dev_path, O_RDWR | O_CLOEXEC);
    if (p_dev->uhid.fd < 0) {
      log::error("Failed to open uhid, err:{}", strerror(errno));
      return false;
    }
  }

  if (p_dev->hh_keep_polling == 0) {
    p_dev->hh_keep_polling = 1;
    p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev);
  if (p_dev->uhid.hh_keep_polling == 0) {
    p_dev->uhid.hh_keep_polling = 1;
    p_dev->hh_poll_thread_id =
        create_thread(btif_hh_poll_event_thread, &p_dev->uhid);
  }
  return true;
}

static int uhid_fd_poll(btif_hh_device_t* p_dev,
static int uhid_fd_poll(btif_hh_uhid_t* p_uhid,
                        std::array<struct pollfd, 1>& pfds) {
  int ret = 0;
  int counter = 0;

  do {
    if (com::android::bluetooth::flags::break_uhid_polling_early() &&
        !p_dev->hh_keep_polling) {
        !p_uhid->hh_keep_polling) {
      log::debug("Polling stopped");
      return -1;
    }
@@ -324,13 +325,13 @@ static int uhid_fd_poll(btif_hh_device_t* p_dev,
  return ret;
}

static void uhid_start_polling(btif_hh_device_t* p_dev) {
static void uhid_start_polling(btif_hh_uhid_t* p_uhid) {
  std::array<struct pollfd, 1> pfds = {};
  pfds[0].fd = p_dev->fd;
  pfds[0].fd = p_uhid->fd;
  pfds[0].events = POLLIN;

  while (p_dev->hh_keep_polling) {
    int ret = uhid_fd_poll(p_dev, pfds);
  while (p_uhid->hh_keep_polling) {
    int ret = uhid_fd_poll(p_uhid, pfds);

    if (ret < 0) {
      log::error("Cannot poll for fds: {}\n", strerror(errno));
@@ -343,7 +344,7 @@ static void uhid_start_polling(btif_hh_device_t* p_dev) {
    /* At least one of the fd is ready */
    if (pfds[0].revents & POLLIN) {
      log::verbose("POLLIN");
      int result = uhid_read_event(p_dev);
      int result = uhid_read_event(p_uhid);
      if (result != 0) {
        log::error("Unhandled UHID event, error: {}", result);
        break;
@@ -352,7 +353,7 @@ static void uhid_start_polling(btif_hh_device_t* p_dev) {
  }
}

static bool uhid_configure_thread(btif_hh_device_t* p_dev) {
static bool uhid_configure_thread(btif_hh_uhid_t* p_uhid) {
  pid_t pid = gettid();
  // This thread is created by bt_main_thread with RT priority. Lower the thread
  // priority here since the tasks in this thread is not timing critical.
@@ -366,14 +367,14 @@ static bool uhid_configure_thread(btif_hh_device_t* p_dev) {
  // Change the name of thread
  char thread_name[16] = {};
  sprintf(thread_name, BT_HH_THREAD_PREFIX "%02x:%02x",
          p_dev->link_spec.addrt.bda.address[4],
          p_dev->link_spec.addrt.bda.address[5]);
          p_uhid->link_spec.addrt.bda.address[4],
          p_uhid->link_spec.addrt.bda.address[5]);
  pthread_setname_np(pthread_self(), thread_name);
  log::debug("Host hid polling thread created name:{} pid:{} fd:{}",
             thread_name, pid, p_dev->fd);
             thread_name, pid, p_uhid->fd);

  // Set the uhid fd as non-blocking to ensure we never block the BTU thread
  uhid_set_non_blocking(p_dev->fd);
  uhid_set_non_blocking(p_uhid->fd);

  return true;
}
@@ -388,17 +389,16 @@ static bool uhid_configure_thread(btif_hh_device_t* p_dev) {
 *
 ******************************************************************************/
static void* btif_hh_poll_event_thread(void* arg) {
  btif_hh_device_t* p_dev = (btif_hh_device_t*)arg;
  btif_hh_uhid_t* p_uhid = (btif_hh_uhid_t*)arg;

  if (uhid_configure_thread(p_dev)) {
    uhid_start_polling(p_dev);
  if (uhid_configure_thread(p_uhid)) {
    uhid_start_polling(p_uhid);
  }

  /* Todo: Disconnect if loop exited due to a failure */
  log::info("Polling thread stopped for device {}", p_dev->link_spec);
  p_dev->hh_poll_thread_id = -1;
  p_dev->hh_keep_polling = 0;
  uhid_fd_close(p_dev);
  log::info("Polling thread stopped for device {}", p_uhid->link_spec);
  p_uhid->hh_keep_polling = 0;
  uhid_fd_close(p_uhid);
  return 0;
}

@@ -455,8 +455,10 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class,
    new_device = true;
    log::verbose("New HID device added for handle {}", dev_handle);

    p_dev->fd = -1;
    p_dev->hh_keep_polling = 0;
    p_dev->uhid.fd = -1;
    p_dev->uhid.hh_keep_polling = 0;
    p_dev->uhid.link_spec = p_dev->link_spec;
    p_dev->uhid.dev_handle = p_dev->dev_handle;
    p_dev->attr_mask = attr_mask;
    p_dev->sub_class = sub_class;
    p_dev->app_id = app_id;
@@ -473,13 +475,13 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class,

  p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
  p_dev->dev_handle = dev_handle;
  p_dev->get_rpt_id_queue = fixed_queue_new(SIZE_MAX);
  log::assert_that(p_dev->get_rpt_id_queue,
                   "assert failed: p_dev->get_rpt_id_queue");
  p_dev->uhid.get_rpt_id_queue = fixed_queue_new(SIZE_MAX);
  log::assert_that(p_dev->uhid.get_rpt_id_queue,
                   "assert failed: p_dev->uhid.get_rpt_id_queue");
#if ENABLE_UHID_SET_REPORT
  p_dev->set_rpt_id_queue = fixed_queue_new(SIZE_MAX);
  log::assert_that(p_dev->set_rpt_id_queue,
                   "assert failed: p_dev->set_rpt_id_queue");
  p_dev->uhid.set_rpt_id_queue = fixed_queue_new(SIZE_MAX);
  log::assert_that(p_dev->uhid.set_rpt_id_queue,
                   "assert failed: p_dev->uhid.set_rpt_id_queue");
#endif  // ENABLE_UHID_SET_REPORT

  log::debug("Return device status {}", p_dev->dev_status);
@@ -502,18 +504,18 @@ void bta_hh_co_close(btif_hh_device_t* p_dev) {
            p_dev->dev_handle, p_dev->dev_status, p_dev->link_spec);

  /* Clear the queues */
  fixed_queue_flush(p_dev->get_rpt_id_queue, osi_free);
  fixed_queue_free(p_dev->get_rpt_id_queue, NULL);
  p_dev->get_rpt_id_queue = NULL;
  fixed_queue_flush(p_dev->uhid.get_rpt_id_queue, osi_free);
  fixed_queue_free(p_dev->uhid.get_rpt_id_queue, NULL);
  p_dev->uhid.get_rpt_id_queue = NULL;
#if ENABLE_UHID_SET_REPORT
  fixed_queue_flush(p_dev->set_rpt_id_queue, osi_free);
  fixed_queue_free(p_dev->set_rpt_id_queue, nullptr);
  p_dev->set_rpt_id_queue = nullptr;
  fixed_queue_flush(p_dev->uhid.set_rpt_id_queue, osi_free);
  fixed_queue_free(p_dev->uhid.set_rpt_id_queue, nullptr);
  p_dev->uhid.set_rpt_id_queue = nullptr;
#endif  // ENABLE_UHID_SET_REPORT

  /* Stop the polling thread */
  if (p_dev->hh_keep_polling) {
    p_dev->hh_keep_polling = 0;
  if (p_dev->uhid.hh_keep_polling) {
    p_dev->uhid.hh_keep_polling = 0;
    pthread_join(p_dev->hh_poll_thread_id, NULL);
    p_dev->hh_poll_thread_id = -1;
  }
@@ -546,20 +548,20 @@ void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len) {

  // Wait a maximum of MAX_POLLING_ATTEMPTS x POLLING_SLEEP_DURATION in case
  // device creation is pending.
  if (p_dev->fd >= 0) {
  if (p_dev->uhid.fd >= 0) {
    uint32_t polling_attempts = 0;
    while (!p_dev->ready_for_data &&
    while (!p_dev->uhid.ready_for_data &&
           polling_attempts++ < BTIF_HH_MAX_POLLING_ATTEMPTS) {
      usleep(BTIF_HH_POLLING_SLEEP_DURATION_US);
    }
  }

  // Send the HID data to the kernel.
  if ((p_dev->fd >= 0) && p_dev->ready_for_data) {
    bta_hh_co_write(p_dev->fd, p_rpt, len);
  if ((p_dev->uhid.fd >= 0) && p_dev->uhid.ready_for_data) {
    bta_hh_co_write(p_dev->uhid.fd, p_rpt, len);
  } else {
    log::warn("Error: fd = {}, ready {}, len = {}", p_dev->fd,
              p_dev->ready_for_data, len);
    log::warn("Error: fd = {}, ready {}, len = {}", p_dev->uhid.fd,
              p_dev->uhid.ready_for_data, len);
  }
}

@@ -583,12 +585,12 @@ void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name,
  int result;
  struct uhid_event ev;

  if (p_dev->fd < 0) {
    log::warn("Error: fd = {}, dscp_len = {}", p_dev->fd, dscp_len);
  if (p_dev->uhid.fd < 0) {
    log::warn("Error: fd = {}, dscp_len = {}", p_dev->uhid.fd, dscp_len);
    return;
  }

  log::warn("fd = {}, name = [{}], dscp_len = {}", p_dev->fd, dev_name,
  log::warn("fd = {}, name = [{}], dscp_len = {}", p_dev->uhid.fd, dev_name,
            dscp_len);
  log::warn(
      "vendor_id = 0x{:04x}, product_id = 0x{:04x}, version= "
@@ -617,17 +619,17 @@ void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name,
  ev.u.create.product = product_id;
  ev.u.create.version = version;
  ev.u.create.country = ctry_code;
  result = uhid_write(p_dev->fd, &ev);
  result = uhid_write(p_dev->uhid.fd, &ev);

  log::warn("wrote descriptor to fd = {}, dscp_len = {}, result = {}",
            p_dev->fd, dscp_len, result);
            p_dev->uhid.fd, dscp_len, result);

  if (result) {
    log::warn("Error: failed to send DSCP, result = {}", result);

    /* The HID report descriptor is corrupted. Close the driver. */
    close(p_dev->fd);
    p_dev->fd = -1;
    close(p_dev->uhid.fd);
    p_dev->uhid.fd = -1;
  }
}

@@ -651,18 +653,19 @@ void bta_hh_co_set_rpt_rsp(uint8_t dev_handle, uint8_t status) {
    return;
  }

  if (!p_dev->set_rpt_id_queue) {
  if (!p_dev->uhid.set_rpt_id_queue) {
    log::warn("Missing UHID_SET_REPORT id queue");
    return;
  }

  // Send the HID set report reply to the kernel.
  if (p_dev->fd < 0) {
  if (p_dev->uhid.fd < 0) {
    log::error("Unexpected Set Report response");
    return;
  }

  uint32_t* context = (uint32_t*)fixed_queue_try_dequeue(p_dev->set_rpt_id_queue);
  uint32_t* context =
      (uint32_t*)fixed_queue_try_dequeue(p_dev->uhid.set_rpt_id_queue);

  if (context == nullptr) {
    log::warn("No pending UHID_SET_REPORT");
@@ -678,7 +681,7 @@ void bta_hh_co_set_rpt_rsp(uint8_t dev_handle, uint8_t status) {
          },
      },
  };
  uhid_write(p_dev->fd, &ev);
  uhid_write(p_dev->uhid.fd, &ev);
  osi_free(context);

#else
@@ -708,18 +711,19 @@ void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status,
    return;
  }

  if (!p_dev->get_rpt_id_queue) {
  if (!p_dev->uhid.get_rpt_id_queue) {
    log::warn("Missing UHID_GET_REPORT id queue");
    return;
  }

  // Send the HID report to the kernel.
  if (p_dev->fd < 0) {
  if (p_dev->uhid.fd < 0) {
    log::warn("Unexpected Get Report response");
    return;
  }

  uint32_t* context = (uint32_t*)fixed_queue_try_dequeue(p_dev->get_rpt_id_queue);
  uint32_t* context =
      (uint32_t*)fixed_queue_try_dequeue(p_dev->uhid.get_rpt_id_queue);

  if (context == nullptr) {
    log::warn("No pending UHID_GET_REPORT");
@@ -743,7 +747,7 @@ void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status,
  };
  memcpy(ev.u.feature_answer.data, p_rpt, len);

  uhid_write(p_dev->fd, &ev);
  uhid_write(p_dev->uhid.fd, &ev);
  osi_free(context);
}

+19 −11
Original line number Diff line number Diff line
@@ -84,7 +84,21 @@ inline std::string btif_hh_status_text(const BTIF_HH_STATUS& status) {
  }
}

// Shared with uhid polling thread
/* Supposedly is exclusive to uhid thread, but now is still accessed by btif. */
/* TODO: remove btif_hh_uhid_t from btif_hh_device_t. */
typedef struct {
  int fd;
  uint8_t dev_handle;
  tAclLinkSpec link_spec;
  uint8_t hh_keep_polling;
  bool ready_for_data;
  fixed_queue_t* get_rpt_id_queue;
#if ENABLE_UHID_SET_REPORT
  fixed_queue_t* set_rpt_id_queue;
#endif  // ENABLE_UHID_SET_REPORT
} btif_hh_uhid_t;

/* Control block to maintain properties of devices */
typedef struct {
  bthh_connection_state_t dev_status;
  uint8_t dev_handle;
@@ -92,16 +106,10 @@ typedef struct {
  tBTA_HH_ATTR_MASK attr_mask;
  uint8_t sub_class;
  uint8_t app_id;
  int fd;
  bool ready_for_data;
  pthread_t hh_poll_thread_id;
  uint8_t hh_keep_polling;
  alarm_t* vup_timer;
  fixed_queue_t* get_rpt_id_queue;
#if ENABLE_UHID_SET_REPORT
  fixed_queue_t* set_rpt_id_queue;
#endif // ENABLE_UHID_SET_REPORT
  bool local_vup;  // Indicated locally initiated VUP
  btif_hh_uhid_t uhid;
} btif_hh_device_t;

/* Control block to maintain properties of devices */
@@ -137,10 +145,10 @@ btif_hh_device_t* btif_hh_find_empty_dev(void);
bt_status_t btif_hh_connect(const tAclLinkSpec& link_spec);
bt_status_t btif_hh_virtual_unplug(const tAclLinkSpec& link_spec);
void btif_hh_remove_device(const tAclLinkSpec& link_spec);
void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
void btif_hh_setreport(btif_hh_uhid_t* p_uhid, bthh_report_type_t r_type,
                       uint16_t size, uint8_t* report);
void btif_hh_senddata(btif_hh_device_t* p_dev, uint16_t size, uint8_t* report);
void btif_hh_getreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
void btif_hh_senddata(btif_hh_uhid_t* p_uhid, uint16_t size, uint8_t* report);
void btif_hh_getreport(btif_hh_uhid_t* p_uhid, bthh_report_type_t r_type,
                       uint8_t reportId, uint16_t bufferSize);
void btif_hh_service_registration(bool enable);

+18 −17
Original line number Diff line number Diff line
@@ -299,7 +299,7 @@ static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) {
        "Sending hid report to kernel indicating lock key state 0x{:x}",
        keylockstates);
    usleep(200000);
    toggle_os_keylockstates(p_dev->fd, keylockstates);
    toggle_os_keylockstates(p_dev->uhid.fd, keylockstates);
  } else {
    log::verbose(
        "NOT sending hid report to kernel indicating lock key state 0x{:x}",
@@ -708,7 +708,7 @@ void btif_hh_remove_device(const tAclLinkSpec& link_spec) {
    bta_hh_co_close(p_dev);
    p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
    p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    p_dev->ready_for_data = false;
    p_dev->uhid.ready_for_data = false;
  }
}

@@ -882,38 +882,38 @@ void btif_hh_disconnect(const tAclLinkSpec& link_spec) {
 *
 * Function         btif_btif_hh_setreport
 *
 * Description      setreport initiated from the BTIF thread context
 * Description      setreport initiated from the UHID thread context
 *
 * Returns          void
 *
 ******************************************************************************/
void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
void btif_hh_setreport(btif_hh_uhid_t* p_uhid, bthh_report_type_t r_type,
                       uint16_t size, uint8_t* report) {
  BT_HDR* p_buf = create_pbuf(size, report);
  if (p_buf == NULL) {
    log::error("Error, failed to allocate RPT buffer, size = {}", size);
    return;
  }
  BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
  BTA_HhSetReport(p_uhid->dev_handle, r_type, p_buf);
}

/*******************************************************************************
 *
 * Function         btif_btif_hh_senddata
 *
 * Description      senddata initiated from the BTIF thread context
 * Description      senddata initiated from the UHID thread context
 *
 * Returns          void
 *
 ******************************************************************************/
void btif_hh_senddata(btif_hh_device_t* p_dev, uint16_t size, uint8_t* report) {
void btif_hh_senddata(btif_hh_uhid_t* p_uhid, uint16_t size, uint8_t* report) {
  BT_HDR* p_buf = create_pbuf(size, report);
  if (p_buf == NULL) {
    log::error("Error, failed to allocate RPT buffer, size = {}", size);
    return;
  }
  p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
  BTA_HhSendData(p_dev->dev_handle, p_dev->link_spec, p_buf);
  BTA_HhSendData(p_uhid->dev_handle, p_uhid->link_spec, p_buf);
}

/*******************************************************************************
@@ -950,14 +950,14 @@ void btif_hh_service_registration(bool enable) {
 *
 * Function         btif_hh_getreport
 *
 * Description      getreport initiated from the BTIF thread context
 * Description      getreport initiated from the UHID thread context
 *
 * Returns          void
 *
 ******************************************************************************/
void btif_hh_getreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type,
void btif_hh_getreport(btif_hh_uhid_t* p_uhid, bthh_report_type_t r_type,
                       uint8_t reportId, uint16_t bufferSize) {
  BTA_HhGetReport(p_dev->dev_handle, r_type, reportId, bufferSize);
  BTA_HhGetReport(p_uhid->dev_handle, r_type, reportId, bufferSize);
}

/*****************************************************************************
@@ -1038,7 +1038,8 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
      p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
      if (p_dev != NULL) {
        BTHH_STATE_UPDATE(p_dev->link_spec, BTHH_CONN_STATE_DISCONNECTING);
        log::verbose("uhid fd={} local_vup={}", p_dev->fd, p_dev->local_vup);
        log::verbose("uhid fd={} local_vup={}", p_dev->uhid.fd,
                     p_dev->local_vup);
        btif_hh_stop_vup_timer(p_dev->link_spec);
        /* If this is a locally initiated VUP, remove the bond as ACL got
         *  disconnected while VUP being processed.
@@ -1185,7 +1186,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
        return;
      }

      if (p_dev->fd < 0) {
      if (p_dev->uhid.fd < 0) {
        log::error("BTA_HH_GET_DSCP_EVT: failed to find the uhid driver...");
        return;
      }
@@ -2134,8 +2135,8 @@ static void cleanup(void) {
  }
  for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    p_dev = &btif_hh_cb.devices[i];
    if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
      log::verbose("Closing uhid fd = {}", p_dev->fd);
    if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->uhid.fd >= 0) {
      log::verbose("Closing uhid fd = {}", p_dev->uhid.fd);
      bta_hh_co_close(p_dev);
    }
  }
@@ -2222,9 +2223,9 @@ void DumpsysHid(int fd) {
    if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) {
      LOG_DUMPSYS(
          fd, "  %u: addr:%s fd:%d state:%s ready:%s thread_id:%d handle:%d", i,
          p_dev->link_spec.ToRedactedStringForLogging().c_str(), p_dev->fd,
          p_dev->link_spec.ToRedactedStringForLogging().c_str(), p_dev->uhid.fd,
          bthh_connection_state_text(p_dev->dev_status).c_str(),
          (p_dev->ready_for_data) ? ("T") : ("F"),
          (p_dev->uhid.ready_for_data) ? ("T") : ("F"),
          static_cast<int>(p_dev->hh_poll_thread_id), p_dev->dev_handle);
    }
  }