diff options
| author | SeanHowsonAdvCo <[email protected]> | 2026-06-04 14:51:26 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-06-04 09:51:26 -0400 |
| commit | c048e1ce16f90ab4c670238d0ebbc487faac9118 (patch) | |
| tree | 29679df8b6b0df00313d527fcd6b2cfc398e5d93 | |
| parent | 0fbb14573df8b9f791e64efa0a43d4e71f6195d1 (diff) | |
Implemented a bugfix for control transfer requests parsing (#218)
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <[email protected]>
Co-authored-by: Copilot <[email protected]>
| -rw-r--r-- | common/core/src/ux_device_stack_control_request_process.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/common/core/src/ux_device_stack_control_request_process.c b/common/core/src/ux_device_stack_control_request_process.c index 013c345..eb15355 100644 --- a/common/core/src/ux_device_stack_control_request_process.c +++ b/common/core/src/ux_device_stack_control_request_process.c @@ -109,13 +109,22 @@ ULONG application_data_length; request_index = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_INDEX); request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); - /* Filter for GET_DESCRIPTOR/SET_DESCRIPTOR commands. If the descriptor to be returned is not a standard descriptor, - treat the command as a CLASS command. */ - if ((request == UX_GET_DESCRIPTOR || request == UX_SET_DESCRIPTOR) && (((request_value >> 8) & UX_REQUEST_TYPE) != UX_REQUEST_TYPE_STANDARD)) + /* Per USB HID 1.11 section 7.1.1, GET_DESCRIPTOR/SET_DESCRIPTOR for a + class-defined descriptor type (e.g. HID Report 0x22, Physical 0x23) + may arrive with bmRequestType set to STANDARD rather than CLASS. + Detect this via the high byte of wValue (bDescriptorType): USB-IF + allocates 0x21..0x2F to class-defined descriptors, so re-route any + such request to the class layer. Standard descriptors (< 0x21, + including BOS 0x0F) and vendor descriptors (>= 0x40) are left + unchanged. */ + if ((request == UX_GET_DESCRIPTOR || request == UX_SET_DESCRIPTOR) && + ((request_type & UX_REQUEST_TYPE) == UX_REQUEST_TYPE_STANDARD) && + (((request_value >> 8) & 0xFFu) >= 0x21u) && + (((request_value >> 8) & 0xFFu) <= 0x2Fu)) { /* This request is to be handled by the class layer. */ - request_type &= (UINT)~UX_REQUEST_TYPE; + request_type &= (ULONG)~UX_REQUEST_TYPE; request_type |= UX_REQUEST_TYPE_CLASS; } |
