Consolidate HID report descriptor parsing across backends #833

Open
opened 2026-07-30 17:38:04 -05:00 by Youw · 2 comments
Youw commented 2026-07-30 17:38:04 -05:00 (Migrated from github.com)

Problem

HIDAPI currently has several private implementations that decode or walk HID report descriptors:

  • libusb/hid.c has its own item walker for Usage Page/Usage extraction.
  • PR #728 adds libusb/hidapi_libusb_report_descriptor.h to calculate maximum Input/Output/Feature report sizes.
  • linux/hid.c independently implements report-item decoding and Usage Page/Usage extraction.
  • netbsd/hid.c contains another closely related implementation.

These routines duplicate short/long item decoding, bounds checks, global-item state, Usage handling, and malformed-descriptor behavior. Keeping the new libusb parser under the backend directory also makes reuse by the hidraw and NetBSD backends unnecessarily difficult.

Windows' hidapi_descriptor_reconstruct.c performs the inverse operation—reconstructing a descriptor from preparsed data—so it may remain separate, but shared item definitions or test data could still be evaluated.

Proposal

Introduce a private common report-descriptor module, for example under src/ or another backend-neutral internal directory, and migrate reusable decoding logic into it.

The common layer should:

  • Decode HID short and long items safely.
  • Expose enough parser state or callbacks to derive Usage Page/Usage and per-report-ID sizes.
  • Keep transport-specific descriptor retrieval in each backend.
  • Remain an internal implementation detail with no public ABI additions.
  • Compile as both C and C++ under HIDAPI_BUILD_AS_CXX.
  • Preserve each backend's existing fallback and malformed-descriptor behavior.

Acceptance criteria

  • libusb, Linux hidraw, and NetBSD reuse the common descriptor walker where practical.
  • Duplicated byte/item decoding helpers are removed.
  • Existing backend behavior remains covered by tests.
  • The Windows fixture corpus and focused malformed/boundary cases provide shared parser coverage.
  • The eventual location and naming of hidapi_libusb_report_descriptor.h no longer imply that generic parsing belongs exclusively to libusb.

Related to #728.

Related to #796.

Generated by Codex (GPT-5.6 Sol).

## Problem HIDAPI currently has several private implementations that decode or walk HID report descriptors: - `libusb/hid.c` has its own item walker for Usage Page/Usage extraction. - PR #728 adds `libusb/hidapi_libusb_report_descriptor.h` to calculate maximum Input/Output/Feature report sizes. - `linux/hid.c` independently implements report-item decoding and Usage Page/Usage extraction. - `netbsd/hid.c` contains another closely related implementation. These routines duplicate short/long item decoding, bounds checks, global-item state, Usage handling, and malformed-descriptor behavior. Keeping the new libusb parser under the backend directory also makes reuse by the hidraw and NetBSD backends unnecessarily difficult. Windows' `hidapi_descriptor_reconstruct.c` performs the inverse operation—reconstructing a descriptor from preparsed data—so it may remain separate, but shared item definitions or test data could still be evaluated. ## Proposal Introduce a private common report-descriptor module, for example under `src/` or another backend-neutral internal directory, and migrate reusable decoding logic into it. The common layer should: - Decode HID short and long items safely. - Expose enough parser state or callbacks to derive Usage Page/Usage and per-report-ID sizes. - Keep transport-specific descriptor retrieval in each backend. - Remain an internal implementation detail with no public ABI additions. - Compile as both C and C++ under `HIDAPI_BUILD_AS_CXX`. - Preserve each backend's existing fallback and malformed-descriptor behavior. ## Acceptance criteria - libusb, Linux hidraw, and NetBSD reuse the common descriptor walker where practical. - Duplicated byte/item decoding helpers are removed. - Existing backend behavior remains covered by tests. - The Windows fixture corpus and focused malformed/boundary cases provide shared parser coverage. - The eventual location and naming of `hidapi_libusb_report_descriptor.h` no longer imply that generic parsing belongs exclusively to libusb. Related to #728. Related to #796. Generated by Codex (GPT-5.6 Sol).
benedekkupper commented 2026-09-02 05:25:09 -05:00 (Migrated from github.com)

I don't know what are your feelings/policies about C++, but this library could be helpful here: https://github.com/IntergatedCircuits/hid-rp
It has various levels of facilities for parsing HID report descriptors, from the simplest iteration from item to item, to more structured parsing with global state stack tracking. It also generates full usage tables and can print report descriptors with usage information.

I don't know what are your feelings/policies about C++, but this library could be helpful here: https://github.com/IntergatedCircuits/hid-rp It has various levels of facilities for parsing HID report descriptors, from the simplest iteration from item to item, to more structured parsing with global state stack tracking. It also generates full usage tables and can print report descriptors with usage information.
Youw commented 2026-09-02 09:06:44 -05:00 (Migrated from github.com)

I don't mind anything regarding C++ (I'm a C++ developer myself), specially where it makes sense.
As for the scope of this particular task - using hid-rp would mean make all of HIDAPI implementation a C++ source, or introduce C++ modules with "C bindings", which I don't thinkg neither should happen. What is used by HIDAPI internally is partial and isolated, let it stay that way.

I don't mind anything regarding C++ (I'm a C++ developer myself), specially where it makes sense. As for the scope of this particular task - using `hid-rp` would mean make all of HIDAPI implementation a C++ source, or introduce C++ modules with "C bindings", which I don't thinkg neither should happen. What is used by HIDAPI internally is partial and isolated, let it stay that way.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-libusb/hidapi#833
No description provided.