diff options
| author | sakumisu <[email protected]> | 2026-03-03 18:55:31 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2026-03-03 18:55:31 +0800 |
| commit | 505d2ef406aa6b492c2c24fc726a85703c587ad2 (patch) | |
| tree | 4468a30f37c3755819fed5225b92be05f891824f | |
| parent | 0ffa68c6c66d316e250f66d0785f822b9f3ea2fd (diff) | |
refactor(class/hid/usbh_hid): refactor hid parse api again
Signed-off-by: sakumisu <[email protected]>
| -rw-r--r-- | class/hid/usbh_hid.c | 389 | ||||
| -rw-r--r-- | class/hid/usbh_hid.h | 94 |
2 files changed, 116 insertions, 367 deletions
diff --git a/class/hid/usbh_hid.c b/class/hid/usbh_hid.c index 4fd1a91a..47220306 100644 --- a/class/hid/usbh_hid.c +++ b/class/hid/usbh_hid.c @@ -296,40 +296,29 @@ static uint32_t hid_get_itemval(const uint8_t *data, unsigned int idx, unsigned return value; } -struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages) +int usbh_hid_parse_report_descriptor(const uint8_t *report_data, uint32_t report_size, struct usbh_hid_report_info *report_info) { + struct usbh_hid_report_item_attribute current_item_attr = { 0 }; + struct usbh_hid_report_item *current_item = NULL; + uint32_t itemtag, itemtype, itemsize, itemval; + uint16_t temp_usage; + uint32_t total_report_size[3] = { 0 }; /* input, output, feature */ uint32_t i = 0; - uint32_t itemtag, itemtype, itemsize; - uint32_t itemval; - struct hid_report_field field; - uint32_t usage_page = 0, usage = 0, usage_min = 0, usage_max = 0, flags = 0; - uint32_t *usages; - struct hid_report *hid_report; - hid_report = usb_osal_malloc(sizeof(struct hid_report)); - if (!hid_report) { - USB_LOG_ERR("hid report malloc failed\r\n"); - return NULL; - } - - usages = usb_osal_malloc(sizeof(uint32_t) * max_usages); - if (!usages) { - USB_LOG_ERR("hid usages malloc failed\r\n"); - goto err; - } - - memset(hid_report, 0, sizeof(struct hid_report)); - memset(&field, 0, sizeof(struct hid_report_field)); + memset(report_info, 0, sizeof(struct usbh_hid_report_info)); + memset(¤t_item_attr, 0, sizeof(struct usbh_hid_report_item_attribute)); + current_item_attr.usage_min = 0xffff; + current_item_attr.usage_max = 0; - while (i < report_len) { - itemtag = data[i] & HID_TAG_MASK; - itemtype = data[i] & HID_TYPE_MASK; - itemsize = data[i] & HID_SIZE_MASK; + while (i < report_size) { + itemtag = report_data[i] & HID_TAG_MASK; + itemtype = report_data[i] & HID_TYPE_MASK; + itemsize = report_data[i] & HID_SIZE_MASK; if (itemsize == 3) /* HID spec: 6.2.2.2 - Short Items */ itemsize = 4; - itemval = hid_get_itemval(data, i, itemsize); + itemval = hid_get_itemval(report_data, i, itemsize); USB_LOG_DBG("itemtype 0x%02x, itemtag 0x%02x, itemsize %d, itemval 0x%08x\r\n", itemtype, itemtag, itemsize, itemval); @@ -338,88 +327,37 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le case HID_ITEMTYPE_MAIN: switch (itemtag) { case HID_MAINITEM_TAG_INPUT: - if ((flags & HID_REPORT_FLAG_REQUIRED_MASK) != HID_REPORT_FLAG_REQUIRED_MASK) - goto err; - - if (hid_report->input_count >= CONFIG_USBHOST_HID_MAX_INPUT) { - USB_LOG_ERR("hid input fields exceed max limit\r\n"); + case HID_MAINITEM_TAG_OUTPUT: + case HID_MAINITEM_TAG_FEATURE: + if (report_info->report_item_count == CONFIG_USB_HID_MAX_REPORT_ITEMS) { goto err; } - field.flags = flags; - field.properties = itemval; - field.usage_page = usage_page; - memcpy(&hid_report->input_fields[hid_report->input_count], &field, sizeof(struct hid_report_field)); - if (field.usage_count > 0) { - hid_report->input_fields[hid_report->input_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count); - if (!hid_report->input_fields[hid_report->input_count].usages) { - USB_LOG_ERR("hid input usages malloc failed\r\n"); - goto err; - } - memcpy(hid_report->input_fields[hid_report->input_count].usages, usages, sizeof(uint32_t) * field.usage_count); - } - - hid_report->input_count++; + current_item = &report_info->report_items[report_info->report_item_count]; + current_item->report_flags = itemval; - /* only keep the global items */ - flags &= HID_REPORT_FLAG_GLOBAL_MASK; - memset(&field, 0, sizeof(struct hid_report_field)); - break; - case HID_MAINITEM_TAG_OUTPUT: - if ((flags & HID_REPORT_FLAG_REQUIRED_MASK) != HID_REPORT_FLAG_REQUIRED_MASK) - goto err; - - if (hid_report->output_count >= CONFIG_USBHOST_HID_MAX_OUTPUT) { - USB_LOG_ERR("hid output fields exceed max limit\r\n"); - goto err; + if (itemtag == HID_MAINITEM_TAG_INPUT) { + current_item->report_type = USBH_HID_REPORTITEM_TYPE_INPUT; + } else if (itemtag == HID_MAINITEM_TAG_OUTPUT) { + current_item->report_type = USBH_HID_REPORTITEM_TYPE_OUTPUT; + } else { + current_item->report_type = USBH_HID_REPORTITEM_TYPE_FEATURE; } - field.flags = flags; - field.properties = itemval; - field.usage_page = usage_page; - memcpy(&hid_report->output_fields[hid_report->output_count], &field, sizeof(struct hid_report_field)); - if (field.usage_count > 0) { - hid_report->output_fields[hid_report->output_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count); - if (!hid_report->output_fields[hid_report->output_count].usages) { - USB_LOG_ERR("hid output usages malloc failed\r\n"); - goto err; - } - memcpy(hid_report->output_fields[hid_report->output_count].usages, usages, sizeof(uint32_t) * field.usage_count); - } + current_item->report_bit_offset = total_report_size[current_item->report_type]; + total_report_size[current_item->report_type] += current_item_attr.report_size * current_item_attr.report_count; - hid_report->output_count++; + memcpy(¤t_item->attribute, ¤t_item_attr, sizeof(struct usbh_hid_report_item_attribute)); + report_info->report_item_count++; - /* only keep the global items */ - flags &= HID_REPORT_FLAG_GLOBAL_MASK; - memset(&field, 0, sizeof(struct hid_report_field)); + // reset for next item + current_item_attr.usage_min = 0xffff; + current_item_attr.usage_max = 0; break; case HID_MAINITEM_TAG_COLLECTION: - memset(&field, 0, sizeof(struct hid_report_field)); - break; - case HID_MAINITEM_TAG_FEATURE: - - if (hid_report->feature_count >= CONFIG_USBHOST_HID_MAX_FEATURE) { - USB_LOG_ERR("hid feature fields exceed max limit\r\n"); - goto err; - } - - field.flags = flags; - field.properties = itemval; - field.usage_page = usage_page; - memcpy(&hid_report->feature_fields[hid_report->feature_count], &field, sizeof(struct hid_report_field)); - if (field.usage_count > 0) { - hid_report->feature_fields[hid_report->feature_count].usages = usb_osal_malloc(sizeof(uint32_t) * field.usage_count); - if (!hid_report->feature_fields[hid_report->feature_count].usages) { - USB_LOG_ERR("hid feature usages malloc failed\r\n"); - goto err; - } - memcpy(hid_report->feature_fields[hid_report->feature_count].usages, usages, sizeof(uint32_t) * field.usage_count); - } - - hid_report->feature_count++; - - memset(&field, 0, sizeof(struct hid_report_field)); - + // reset for next item + current_item_attr.usage_min = 0xffff; + current_item_attr.usage_max = 0; break; case HID_MAINITEM_TAG_ENDCOLLECTION: break; @@ -430,33 +368,34 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le case HID_ITEMTYPE_GLOBAL: switch (itemtag) { case HID_GLOBALITEM_TAG_USAGE_PAGE: - usage_page = itemval; - - if (usage_page > UINT16_MAX) - goto err; - - flags |= HID_REPORT_FLAG_USAGE_PAGE; + current_item_attr.usage_page = (uint16_t)itemval; break; case HID_GLOBALITEM_TAG_LOGICAL_MIN: - field.logical_min = (int32_t)itemval; - flags |= HID_REPORT_FLAG_LOGICAL_MIN; + current_item_attr.logical_min = itemval; break; case HID_GLOBALITEM_TAG_LOGICAL_MAX: - field.logical_max = (int32_t)itemval; - flags |= HID_REPORT_FLAG_LOGICAL_MAX; + current_item_attr.logical_max = itemval; + break; + case HID_GLOBALITEM_TAG_PHYSICAL_MIN: + current_item_attr.physical_min = itemval; + break; + case HID_GLOBALITEM_TAG_PHYSICAL_MAX: + current_item_attr.physical_max = itemval; + break; + case HID_GLOBALITEM_TAG_UNIT_EXP: + current_item_attr.unit_exponent = itemval; + break; + case HID_GLOBALITEM_TAG_UNIT: + current_item_attr.unit = itemval; break; case HID_GLOBALITEM_TAG_REPORT_SIZE: - field.report_size = itemval; - flags |= HID_REPORT_FLAG_REPORT_SIZE; + current_item_attr.report_size = itemval; break; case HID_GLOBALITEM_TAG_REPORT_COUNT: - field.report_count = itemval; - flags |= HID_REPORT_FLAG_REPORT_COUNT; + current_item_attr.report_count = itemval; break; case HID_GLOBALITEM_TAG_REPORT_ID: - hid_report->uses_report_id = true; - field.report_id = itemval; - flags |= HID_REPORT_FLAG_REPORT_ID; + current_item_attr.report_id = itemval; break; default: goto err; @@ -465,64 +404,20 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le case HID_ITEMTYPE_LOCAL: switch (itemtag) { case HID_LOCALITEM_TAG_USAGE: - usage = itemval; - /* Extended usage (size 4) combines both usage page and id */ - if (itemsize != 4) { - if (!(flags & HID_REPORT_FLAG_USAGE_PAGE)) - goto err; - usage |= usage_page << 16; + if (itemsize == 4) { + temp_usage = (uint16_t)(itemval >> 16); + } else { + temp_usage = (uint16_t)itemval; } - - usages[field.usage_count++] = usage; + current_item_attr.usage_min = MIN(current_item_attr.usage_min, temp_usage); + current_item_attr.usage_max = MAX(current_item_attr.usage_max, temp_usage); break; case HID_LOCALITEM_TAG_USAGE_MIN: - usage_min = itemval; - if (itemsize == 4) { - /* Usage max must be extended as well */ - flags |= HID_REPORT_FLAG_EXTENDED_USAGE; - } else { - if (!(flags & HID_REPORT_FLAG_USAGE_PAGE)) - goto err; - usage_min |= usage_page << 16; - } - field.usage_min = usage_min; - flags |= HID_REPORT_FLAG_USAGE_MIN; + current_item_attr.usage_min = (uint16_t)itemval; break; case HID_LOCALITEM_TAG_USAGE_MAX: - if (!(flags & HID_REPORT_FLAG_USAGE_MIN)) - goto err; - - usage_max = itemval; - if (flags & HID_REPORT_FLAG_EXTENDED_USAGE) { - /* Fail if max is not extended usage (HID spec 6.2.2.8) */ - if (itemsize != 4) - goto err; - } else if (itemsize == 4) { - /* Fail because min wasn't extended, but max is */ - goto err; - } else { - if (!(flags & HID_REPORT_FLAG_USAGE_PAGE)) - goto err; - usage_max |= usage_page << 16; - } - - /* Usage min and max must be on the same page */ - if (USAGE_PAGE(usage_min) != USAGE_PAGE(usage_max)) { - goto err; - } - - if (usage_min > usage_max) { - goto err; - } - - for (uint32_t j = usage_min; j <= usage_max; j++) { - usages[field.usage_count++] = j; - } - - field.usage_max = usage_max; - flags |= HID_REPORT_FLAG_USAGE_MAX; - flags &= ~(HID_REPORT_FLAG_USAGE_MIN | HID_REPORT_FLAG_EXTENDED_USAGE); + current_item_attr.usage_max = (uint16_t)itemval; break; default: goto err; @@ -534,127 +429,36 @@ struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_le i += (1 + itemsize); } - usb_osal_free(usages); - return hid_report; -err: - if (hid_report) { - usb_osal_free(hid_report); - - for (uint32_t j = 0; j < hid_report->input_count; j++) - usb_osal_free(hid_report->input_fields[j].usages); - - for (uint32_t j = 0; j < hid_report->output_count; j++) - usb_osal_free(hid_report->output_fields[j].usages); - - for (uint32_t j = 0; j < hid_report->feature_count; j++) - usb_osal_free(hid_report->feature_fields[j].usages); - } - if (usages) - usb_osal_free(usages); - return NULL; + return 0; +err: + return -1; } -void usbh_hid_report_free(struct hid_report *hid_report) +static void usbh_hid_item_info_print(struct usbh_hid_report_item *item) { - if (hid_report) { - for (uint32_t j = 0; j < hid_report->input_count; j++) - usb_osal_free(hid_report->input_fields[j].usages); - - for (uint32_t j = 0; j < hid_report->output_count; j++) - usb_osal_free(hid_report->output_fields[j].usages); - - for (uint32_t j = 0; j < hid_report->feature_count; j++) - usb_osal_free(hid_report->feature_fields[j].usages); - - usb_osal_free(hid_report); - } + USB_LOG_RAW("Item Type: %s\r\n", (unsigned int)item->report_type == USBH_HID_REPORTITEM_TYPE_INPUT ? "Input" : + (unsigned int)item->report_type == USBH_HID_REPORTITEM_TYPE_OUTPUT ? "Output" : + "Feature"); + USB_LOG_RAW("Usage Page: 0x%04x\r\n", (unsigned int)item->attribute.usage_page); + USB_LOG_RAW("Report ID: 0x%04x\r\n", (unsigned int)item->attribute.report_id); + USB_LOG_RAW("Report Size: %ubit\r\n", (unsigned int)item->attribute.report_size); + USB_LOG_RAW("Report Count: %u\r\n", (unsigned int)item->attribute.report_count); + USB_LOG_RAW("Usages(0x%04x ~ 0x%04x)\r\n", (unsigned int)item->attribute.usage_min, (unsigned int)item->attribute.usage_max); + USB_LOG_RAW("Logical Min: %d\r\n", item->attribute.logical_min); + USB_LOG_RAW("Logical Max: %d\r\n", item->attribute.logical_max); + USB_LOG_RAW("Properties: 0x%04x\r\n", (unsigned int)item->report_flags); + USB_LOG_RAW("Bit Offset: 0x%04x\r\n", (unsigned int)item->report_bit_offset); + USB_LOG_RAW("\r\n"); } USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_report_buf[2048]; -static const char *hid_property_string(uint32_t value) -{ - uint32_t off = 0; - static char buffer[160]; - - memset(buffer, 0, sizeof(buffer)); - - if (value & HID_MAINITEM_CONSTANT) - off += snprintf(buffer + off, sizeof(buffer) - off, "Constant, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Data, "); - - if (value & HID_MAINITEM_VARIABLE) - off += snprintf(buffer + off, sizeof(buffer) - off, "Variable, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Array, "); - - if (value & HID_MAINITEM_RELATIVE) - off += snprintf(buffer + off, sizeof(buffer) - off, "Relative, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Absolute, "); - - if (value & HID_MAINITEM_WRAP) - off += snprintf(buffer + off, sizeof(buffer) - off, "Wrap, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "NoWrap, "); - - if (value & HID_MAINITEM_NONLINEAR) - off += snprintf(buffer + off, sizeof(buffer) - off, "NonLinear, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Linear, "); - - if (value & HID_MAINITEM_NOPREFERRED) - off += snprintf(buffer + off, sizeof(buffer) - off, "NoPreferred, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "Preferred, "); - - if (value & HID_MAINITEM_NULLSTATE) - off += snprintf(buffer + off, sizeof(buffer) - off, "NullState, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "NoNullState, "); - - if (value & HID_MAINITEM_VOLATILE) - off += snprintf(buffer + off, sizeof(buffer) - off, "Volatile, "); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "NonVolatile, "); - - if (value & HID_MAINITEM_BUFFEREDBYTES) - off += snprintf(buffer + off, sizeof(buffer) - off, "BufferedBytes"); - else - off += snprintf(buffer + off, sizeof(buffer) - off, "BitField"); - - return buffer; - -} - -static void usbh_hid_field_info_print(uint32_t idx, struct hid_report_field *field) -{ - USB_LOG_RAW(" Field %u:\r\n", idx); - USB_LOG_RAW(" Usage Page: 0x%04x\r\n", (unsigned int)field->usage_page); - USB_LOG_RAW(" Report ID: %u\r\n", (unsigned int)field->report_id); - USB_LOG_RAW(" Report Size: %ubit\r\n", (unsigned int)field->report_size); - USB_LOG_RAW(" Report Count: %u\r\n", (unsigned int)field->report_count); - USB_LOG_RAW(" Logical Min: %d\r\n", field->logical_min); - USB_LOG_RAW(" Logical Max: %d\r\n", field->logical_max); - USB_LOG_RAW(" Usage Count: %u\r\n", (unsigned int)field->usage_count); - if (field->usage_count > 0) { - if (field->usage_count == 1) { - USB_LOG_RAW(" Usage: 0x%04x\r\n", USAGE_ID(field->usages[0])); - } else { - USB_LOG_RAW(" Usages(0x%04x ~ 0x%04x)\r\n", USAGE_ID(field->usage_min), USAGE_ID(field->usage_max)); - } - } - USB_LOG_RAW(" Flags: 0x%04x\r\n", (unsigned int)field->flags); - USB_LOG_RAW(" Properties: 0x%04x(%s)\r\n", (unsigned int)field->properties, hid_property_string(field->properties)); -} - int lshid(int argc, char **argv) { struct usbh_hid *hid_class; - struct hid_report *hid_report; int ret; + struct usbh_hid_report_info report_info = { 0 }; if (argc < 2) { USB_LOG_ERR("please input correct command: lshid path\r\n"); @@ -678,32 +482,17 @@ int lshid(int argc, char **argv) return -1; } - hid_report = usbh_hid_report_parse(g_hid_report_buf, hid_class->report_size, 1024); - if (hid_report) { - USB_LOG_RAW("HID report parsed successfully\r\n"); - - USB_LOG_RAW("Input fields: %u\r\n", (unsigned int)hid_report->input_count); - for (uint32_t i = 0; i < hid_report->input_count; i++) { - struct hid_report_field *field = &hid_report->input_fields[i]; - usbh_hid_field_info_print(i, field); - } - - USB_LOG_RAW("Output fields: %u\r\n", (unsigned int)hid_report->output_count); - for (uint32_t i = 0; i < hid_report->output_count; i++) { - struct hid_report_field *field = &hid_report->output_fields[i]; - usbh_hid_field_info_print(i, field); - } - - USB_LOG_RAW("Feature fields: %u\r\n", (unsigned int)hid_report->feature_count); - for (uint32_t i = 0; i < hid_report->feature_count; i++) { - struct hid_report_field *field = &hid_report->feature_fields[i]; - usbh_hid_field_info_print(i, field); - } + ret = usbh_hid_parse_report_descriptor(g_hid_report_buf, hid_class->report_size, &report_info); + if (ret < 0) { + USB_LOG_ERR("parse hid report descriptor failed\r\n"); + return -1; + } - usbh_hid_report_free(hid_report); - } else { - USB_LOG_ERR("HID report parsed failed\r\n"); + USB_LOG_INFO("HID report item count: %u\r\n", report_info.report_item_count); + for (uint32_t i = 0; i < report_info.report_item_count; i++) { + usbh_hid_item_info_print(&report_info.report_items[i]); } + return 0; } diff --git a/class/hid/usbh_hid.h b/class/hid/usbh_hid.h index fa5c7663..1c63a0d2 100644 --- a/class/hid/usbh_hid.h +++ b/class/hid/usbh_hid.h @@ -8,80 +8,41 @@ #include "usb_hid.h" -/* local items */ -#define HID_REPORT_FLAG_USAGE_MIN (1 << 0) -#define HID_REPORT_FLAG_USAGE_MAX (1 << 1) - -/* global items */ -#define HID_REPORT_FLAG_REPORT_ID (1 << 2) -#define HID_REPORT_FLAG_REPORT_COUNT (1 << 3) -#define HID_REPORT_FLAG_REPORT_SIZE (1 << 4) -#define HID_REPORT_FLAG_LOGICAL_MIN (1 << 5) -#define HID_REPORT_FLAG_LOGICAL_MAX (1 << 6) -#define HID_REPORT_FLAG_USAGE_PAGE (1 << 7) - -/* main items */ -#define HID_REPORT_FLAG_INPUT (1 << 8) -#define HID_REPORT_FLAG_OUTPUT (1 << 9) -#define HID_REPORT_FLAG_FEATURE (1 << 10) - -#define HID_REPORT_FLAG_EXTENDED_USAGE (1 << 11) - -/* masks */ - -#define HID_REPORT_FLAG_GLOBAL_MASK (HID_REPORT_FLAG_REPORT_ID | \ - HID_REPORT_FLAG_REPORT_COUNT | \ - HID_REPORT_FLAG_REPORT_SIZE | \ - HID_REPORT_FLAG_LOGICAL_MIN | \ - HID_REPORT_FLAG_LOGICAL_MAX | \ - HID_REPORT_FLAG_USAGE_PAGE) - -#define HID_REPORT_FLAG_REQUIRED_MASK (HID_REPORT_FLAG_REPORT_COUNT | \ - HID_REPORT_FLAG_REPORT_SIZE | \ - HID_REPORT_FLAG_LOGICAL_MIN | \ - HID_REPORT_FLAG_LOGICAL_MAX) - -#define USAGE_ID(usage) (usage & 0x0000FFFF) -#define USAGE_PAGE(usage) ((usage & 0xFFFF0000) >> 16) - -#ifndef CONFIG_USBHOST_HID_MAX_INPUT -#define CONFIG_USBHOST_HID_MAX_INPUT 16 +#ifndef CONFIG_USB_HID_MAX_REPORT_ITEMS +#define CONFIG_USB_HID_MAX_REPORT_ITEMS 16 #endif -#ifndef CONFIG_USBHOST_HID_MAX_OUTPUT -#define CONFIG_USBHOST_HID_MAX_OUTPUT 16 -#endif - -#ifndef CONFIG_USBHOST_HID_MAX_FEATURE -#define CONFIG_USBHOST_HID_MAX_FEATURE 16 -#endif - -struct hid_report_field { - uint32_t *usages; /* usage page + usage */ - uint32_t usage_count; - uint32_t usage_page; +#define USBH_HID_REPORTITEM_TYPE_INPUT 0 +#define USBH_HID_REPORTITEM_TYPE_OUTPUT 1 +#define USBH_HID_REPORTITEM_TYPE_FEATURE 2 - uint32_t report_id; /* optional */ - uint32_t report_count; - uint32_t report_size; +struct usbh_hid_report_item_attribute { + uint16_t usage_page; + uint16_t usage_min; + uint16_t usage_max; int32_t logical_min; int32_t logical_max; - uint32_t properties; + uint32_t physical_min; + uint32_t physical_max; + uint32_t unit_exponent; + uint32_t unit; + uint32_t report_count; + uint8_t report_size; + uint8_t report_id; +}; - uint32_t usage_min; - uint32_t usage_max; +struct usbh_hid_report_item { + uint8_t report_type; /* input, output, feature */ + uint16_t report_flags; + uint32_t report_bit_offset; - uint32_t flags; + struct usbh_hid_report_item_attribute attribute; }; -struct hid_report { - bool uses_report_id; - uint32_t input_count; - struct hid_report_field input_fields[CONFIG_USBHOST_HID_MAX_INPUT]; - uint32_t output_count; - struct hid_report_field output_fields[CONFIG_USBHOST_HID_MAX_OUTPUT]; - uint32_t feature_count; - struct hid_report_field feature_fields[CONFIG_USBHOST_HID_MAX_FEATURE]; +struct usbh_hid_report_info { + struct usbh_hid_report_item report_items[CONFIG_USB_HID_MAX_REPORT_ITEMS]; + uint32_t report_item_count; + bool using_report_id; }; struct usbh_hid { @@ -112,8 +73,7 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol); int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen); int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen); -struct hid_report *usbh_hid_report_parse(const uint8_t *data, uint32_t report_len, uint32_t max_usages); -void usbh_hid_report_free(struct hid_report *hid_report); +int usbh_hid_parse_report_descriptor(const uint8_t *report_data, uint32_t report_size, struct usbh_hid_report_info *report_info); void usbh_hid_run(struct usbh_hid *hid_class); void usbh_hid_stop(struct usbh_hid *hid_class); |
