Loading system/btif/co/bta_hh_co.cc +91 −87 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; } Loading @@ -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); Loading @@ -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; } Loading @@ -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 Loading @@ -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)); Loading @@ -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))) { Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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)); Loading @@ -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; Loading @@ -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. Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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); } } Loading @@ -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= " Loading Loading @@ -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; } } Loading @@ -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"); Loading @@ -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 Loading Loading @@ -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"); Loading @@ -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); } Loading system/btif/include/btif_hh.h +19 −11 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 */ Loading Loading @@ -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); Loading system/btif/src/btif_hh.cc +18 −17 Original line number Diff line number Diff line Loading @@ -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}", Loading Loading @@ -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; } } Loading Loading @@ -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); } /******************************************************************************* Loading Loading @@ -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); } /***************************************************************************** Loading Loading @@ -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. Loading Loading @@ -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; } Loading Loading @@ -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); } } Loading Loading @@ -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); } } Loading Loading
system/btif/co/bta_hh_co.cc +91 −87 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; } Loading @@ -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); Loading @@ -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; } Loading @@ -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 Loading @@ -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)); Loading @@ -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))) { Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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)); Loading @@ -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; Loading @@ -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. Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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); } } Loading @@ -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= " Loading Loading @@ -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; } } Loading @@ -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"); Loading @@ -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 Loading Loading @@ -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"); Loading @@ -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); } Loading
system/btif/include/btif_hh.h +19 −11 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 */ Loading Loading @@ -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); Loading
system/btif/src/btif_hh.cc +18 −17 Original line number Diff line number Diff line Loading @@ -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}", Loading Loading @@ -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; } } Loading Loading @@ -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); } /******************************************************************************* Loading Loading @@ -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); } /***************************************************************************** Loading Loading @@ -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. Loading Loading @@ -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; } Loading Loading @@ -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); } } Loading Loading @@ -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); } } Loading