summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-11-20 10:03:27 +0700
committerhathach <[email protected]>2025-11-20 11:15:32 +0700
commitaa3aec00344bf5e723bf27eba406155d133459cc (patch)
treec5b1328b7071fda90a7f57f5dadee25998968eb3 /src
parentdba5d799f211291544faacec90c8f3d973998437 (diff)
Revert "add find_hid_desc"
support rare case where hid descriptor is after endpoint descriptor
Diffstat (limited to 'src')
-rw-r--r--src/class/hid/hid_host.c104
1 files changed, 37 insertions, 67 deletions
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index a67267aa5..fe9a90d33 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -141,7 +141,9 @@ static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) {
static hidh_interface_t* find_new_itf(void) {
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr == 0) return &_hidh_itf[i];
+ if (_hidh_itf[i].daddr == 0) {
+ return &_hidh_itf[i];
+ }
}
return NULL;
}
@@ -152,7 +154,9 @@ static hidh_interface_t* find_new_itf(void) {
uint8_t tuh_hid_itf_get_count(uint8_t daddr) {
uint8_t count = 0;
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr == daddr) count++;
+ if (_hidh_itf[i].daddr == daddr) {
+ count++;
+ }
}
return count;
}
@@ -160,7 +164,9 @@ uint8_t tuh_hid_itf_get_count(uint8_t daddr) {
uint8_t tuh_hid_itf_get_total_count(void) {
uint8_t count = 0;
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr != 0) count++;
+ if (_hidh_itf[i].daddr != 0) {
+ count++;
+ }
}
return count;
}
@@ -507,27 +513,6 @@ void hidh_close(uint8_t daddr) {
// Enumeration
//--------------------------------------------------------------------+
-// Helper: locate the first HID descriptor (0x21) after the interface
-static tusb_hid_descriptor_hid_t const* find_hid_desc(uint8_t const* p, uint16_t remaining_len)
-{
- while (remaining_len >= 2)
- {
- uint8_t len = p[0];
- uint8_t type = p[1];
-
- if (len == 0) break; // Invalid descriptor
- if (type == HID_DESC_TYPE_HID) // Found it
- return (tusb_hid_descriptor_hid_t const*)p;
-
- // Move to next descriptor
- if (remaining_len < len) break;
- p += len;
- remaining_len -= len;
- }
-
- return NULL; // not found
-}
-
bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) {
(void) rhport;
(void) max_len;
@@ -540,58 +525,43 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_
desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
TU_ASSERT(max_len >= drv_len);
uint8_t const* p_desc = (uint8_t const*) desc_itf;
- uint16_t len_left = max_len;
-
- // Move past Interface descriptor
- uint16_t itf_len = p_desc[0];
- p_desc += itf_len;
- len_left -= itf_len;
-
- // Find the descriptor anywhere in the report
- tusb_hid_descriptor_hid_t const* desc_hid = find_hid_desc(p_desc, len_left);
- // Did not find the descriptor in the report
- TU_ASSERT(desc_hid != NULL);
-
- // Open endpoints, scan all descs
- p_desc = (uint8_t const*)desc_itf + desc_itf->bLength;
- len_left = max_len - desc_itf->bLength;
+ // HID descriptor: mostly right after interface descriptor, in some rare case it might be after endpoint descriptors
+ p_desc = tu_desc_next(p_desc);
+ const tusb_hid_descriptor_hid_t *desc_hid;
+ if (tu_desc_type(p_desc) == HID_DESC_TYPE_HID) {
+ // HID after interface
+ desc_hid = (const tusb_hid_descriptor_hid_t *)p_desc;
+ p_desc = tu_desc_next(p_desc);
+ } else {
+ // HID after endpoint
+ desc_hid = (const tusb_hid_descriptor_hid_t *)(p_desc + sizeof(tusb_desc_endpoint_t) * desc_itf->bNumEndpoints);
+ TU_ASSERT(tu_desc_type(desc_hid) == HID_DESC_TYPE_HID);
+ }
- hidh_interface_t* p_hid = find_new_itf();
+ // Allocate new interface
+ hidh_interface_t *p_hid = find_new_itf();
TU_ASSERT(p_hid); // not enough interface, try to increase CFG_TUH_HID
- p_hid->daddr = daddr;
-
- p_hid->ep_in = 0;
- p_hid->ep_out = 0;
-
- while (len_left >= 2)
- {
- uint8_t len = p_desc[0];
- uint8_t type = p_desc[1];
-
- if (len == 0) break;
+ p_hid->daddr = daddr;
+ p_hid->itf_num = desc_itf->bInterfaceNumber;
- if (type == TUSB_DESC_ENDPOINT)
- {
- tusb_desc_endpoint_t const* ep = (tusb_desc_endpoint_t const*)p_desc;
- TU_ASSERT(tuh_edpt_open(daddr, ep));
+ // Endpoint Descriptors
+ for (uint8_t i = 0; i < desc_itf->bNumEndpoints; i++) {
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;
+ TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType);
+ TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
- if (tu_edpt_dir(ep->bEndpointAddress) == TUSB_DIR_IN) {
- p_hid->ep_in = ep->bEndpointAddress;
- p_hid->epin_size = tu_edpt_packet_size(ep);
- } else {
- p_hid->ep_out = ep->bEndpointAddress;
- p_hid->epout_size = tu_edpt_packet_size(ep);
- }
+ if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
+ p_hid->ep_in = desc_ep->bEndpointAddress;
+ p_hid->epin_size = tu_edpt_packet_size(desc_ep);
+ } else {
+ p_hid->ep_out = desc_ep->bEndpointAddress;
+ p_hid->epout_size = tu_edpt_packet_size(desc_ep);
}
- p_desc += len;
- len_left -= len;
+ p_desc = tu_desc_next(p_desc);
}
- // Store HID report info
- p_hid->itf_num = desc_itf->bInterfaceNumber;
-
// Assume bNumDescriptors = 1
p_hid->report_desc_type = desc_hid->bReportType;
// Use offsetof to avoid pointer to the odd/misaligned address