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

Commit 53177919 authored by Himanshu Rawat's avatar Himanshu Rawat Committed by Gerrit Code Review
Browse files

Merge "hid: separate the struct accessed by the uhid thread" into main

parents 1f49b379 55c7cf0d
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);
    }
  }