summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeanHowsonAdvCo <[email protected]>2026-06-04 14:51:26 +0100
committerGitHub <[email protected]>2026-06-04 09:51:26 -0400
commitc048e1ce16f90ab4c670238d0ebbc487faac9118 (patch)
tree29679df8b6b0df00313d527fcd6b2cfc398e5d93
parent0fbb14573df8b9f791e64efa0a43d4e71f6195d1 (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.c17
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;
}