Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions common/usbx_device_classes/inc/ux_device_class_hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT
UINT ux_device_class_hid_state;
UINT (*ux_device_class_hid_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
UINT (*ux_device_class_hid_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
VOID (*ux_device_class_hid_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol);
VOID (*ux_slave_class_hid_instance_activate)(VOID *);
VOID (*ux_slave_class_hid_instance_deactivate)(VOID *);
UCHAR *ux_device_class_hid_report_address;
Expand Down Expand Up @@ -365,6 +366,10 @@ typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT
ULONG ux_device_class_hid_parameter_report_length;
UINT (*ux_device_class_hid_parameter_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
UINT (*ux_device_class_hid_parameter_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);

/* Optional callback invoked when protocol changes (boot/report). */
VOID (*ux_device_class_hid_parameter_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol);

#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE)
ULONG ux_device_class_hid_parameter_event_max_number;
ULONG ux_device_class_hid_parameter_event_max_length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,28 @@ UX_SLAVE_CLASS_HID *hid;

case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL:

/* Send the protocol. */
/* Send the protocol to host. */
*transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_protocol;
_ux_device_stack_transfer_request(transfer_request, 1, request_length);
break;

case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL:

/* Check protocol must be 0 (Boot) or 1 (Report). */
if ((request_value != UX_DEVICE_CLASS_HID_PROTOCOL_BOOT) &&
(request_value != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT))
{
/* Invalid value: not handled. */
return(UX_ERROR);
}

/* Accept the protocol. */
hid -> ux_device_class_hid_protocol = request_value;

/* If there is a callback defined by the application, send the protocol to it. */
if (hid -> ux_device_class_hid_set_protocol_callback != UX_NULL)
hid -> ux_device_class_hid_set_protocol_callback(hid, request_value);

break;

default:
Expand All @@ -225,4 +238,3 @@ UX_SLAVE_CLASS_HID *hid;
/* It's handled. */
return(UX_SUCCESS);
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/


/**************************************************************************/
/**************************************************************************/
/** */
Expand Down Expand Up @@ -196,6 +197,7 @@ UCHAR *buffer;
/* Store the callback function. */
hid -> ux_device_class_hid_callback = hid_parameter -> ux_device_class_hid_parameter_callback;
hid -> ux_device_class_hid_get_callback = hid_parameter -> ux_device_class_hid_parameter_get_callback;
hid -> ux_device_class_hid_set_protocol_callback = hid_parameter -> ux_device_class_hid_parameter_set_protocol_callback;

Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ux_device_class_hid_protocol field is not explicitly initialized in ux_device_class_hid_initialize. Since _ux_utility_memory_allocate typically zeroes allocated memory, the protocol will default to 0 (BOOT), but according to the USB HID specification (section 7.2.6), the default protocol should be REPORT (1) for boot-capable devices. The protocol field should be explicitly initialized to UX_DEVICE_CLASS_HID_PROTOCOL_REPORT (1) to comply with the USB HID specification and match the test expectations at line 261.

Suggested change
/* Set default protocol to REPORT as required by USB HID specification (section 7.2.6). */
hid -> ux_device_class_hid_protocol = UX_DEVICE_CLASS_HID_PROTOCOL_REPORT;

Copilot uses AI. Check for mistakes.
#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE)

Expand Down
2 changes: 2 additions & 0 deletions common/usbx_host_classes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_instance_clean.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_interrupt_endpoint_search.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_item_data_get.c
Expand Down
355 changes: 182 additions & 173 deletions common/usbx_host_classes/inc/ux_host_class_hid.h

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/


/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Host HID Class */
/** */
/**************************************************************************/
/**************************************************************************/

/* Include necessary system files. */

#define UX_SOURCE_CODE

#include "ux_api.h"
#include "ux_host_class_hid.h"
#include "ux_host_stack.h"

/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_hid_protocol_get PORTABLE C */
/* */
/* DESCRIPTION */
/* */
/* This function performs a GET_PROTOCOL to the HID device to read */
/* current protocol (BOOT=0 or REPORT=1). */
/* */
/* INPUT */
/* */
/* hid Pointer to HID class */
/* protocol Destination for protocol */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */
/* */
/**************************************************************************/
UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol)
{

UX_ENDPOINT *control_endpoint;
UX_TRANSFER *transfer_request;
UINT status;
UCHAR proto_byte = 0xFFu;

/* Ensure the instance is valid. */
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS)
{

/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)

#if defined(UX_HOST_STANDALONE)
hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN;
#endif

return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
}

/* Get the default control endpoint transfer request pointer. */
control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
transfer_request = &control_endpoint -> ux_endpoint_transfer_request;

#if !defined(UX_HOST_STANDALONE)

/* Protect thread reentry to this instance. */
status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
if (status != UX_SUCCESS)
return(status);

#endif

/* Create a transfer request for the GET_PROTOCOL request. */
transfer_request -> ux_transfer_request_data_pointer = &proto_byte;
transfer_request -> ux_transfer_request_requested_length = 1;
transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL;
transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
transfer_request -> ux_transfer_request_value = 0;
transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;

/* Send request to HCD layer. */
status = _ux_host_stack_transfer_request(transfer_request);

#if !defined(UX_HOST_STANDALONE)
/* Unprotect thread reentry to this instance. */
_ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore);
#endif

if (status == UX_SUCCESS && protocol)
*protocol = (USHORT)proto_byte;

return(status);
}

/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _uxe_host_class_hid_protocol_get PORTABLE C */
/* */
/* DESCRIPTION */
/* */
/* This function checks errors in HID protocol get function call. */
/* */
/* INPUT */
/* */
/* hid Pointer to HID class */
/* protocol Destination for protocol */
/* */
/* OUTPUT */
/* */
/* Status */
/* */
/**************************************************************************/
UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol)
{
/* Sanity check. */
if (hid == UX_NULL || protocol == UX_NULL)
return(UX_INVALID_PARAMETER);

/* Invoke protocol get function. */
return(_ux_host_class_hid_protocol_get(hid, protocol));
}
147 changes: 147 additions & 0 deletions common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/


/**************************************************************************/
/**************************************************************************/
/** */
/** USBX Component */
/** */
/** Host HID Class */
/** */
/**************************************************************************/
/**************************************************************************/

/* Include necessary system files. */

#define UX_SOURCE_CODE

#include "ux_api.h"
#include "ux_host_class_hid.h"
#include "ux_host_stack.h"

/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_hid_protocol_set PORTABLE C */
/* */
/* DESCRIPTION */
/* */
/* This function performs a SET_PROTOCOL to the HID device to switch */
/* between BOOT (0) and REPORT (1) protocols. */
/* */
/* INPUT */
/* */
/* hid Pointer to HID class */
/* protocol Protocol (BOOT/REPORT) */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */
/* */
/**************************************************************************/
UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol)
{

UX_ENDPOINT *control_endpoint;
UX_TRANSFER *transfer_request;
UINT status;

/* Ensure the instance is valid. */
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent indentation: The comment has an extra leading space. Should align with the code below at 4 spaces indentation.

Copilot uses AI. Check for mistakes.
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS)
{

/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)

#if defined(UX_HOST_STANDALONE)
hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN;
#endif
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
}

/* Get the default control endpoint transfer request pointer. */
control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
transfer_request = &control_endpoint -> ux_endpoint_transfer_request;

#if !defined(UX_HOST_STANDALONE)

/* Protect thread reentry to this instance. */
status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
if (status != UX_SUCCESS)
return(status);

#endif

/* Create a transfer request for the SET_PROTOCOL request. */
transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
transfer_request -> ux_transfer_request_requested_length = 0;
transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_PROTOCOL;
transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
transfer_request -> ux_transfer_request_value = (UINT)protocol;
transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;

/* Send request to HCD layer. */
status = _ux_host_stack_transfer_request(transfer_request);

#if !defined(UX_HOST_STANDALONE)
/* Unprotect thread reentry to this instance. */
_ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore);
#endif

/* Return the function status. */
return(status);
}

/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _uxe_host_class_hid_protocol_set PORTABLE C */
/* */
/* DESCRIPTION */
/* */
/* This function checks errors in HID protocol set function call. */
/* */
/* INPUT */
/* */
/* hid Pointer to HID class */
/* protocol Protocol (BOOT/REPORT) */
/* */
/* OUTPUT */
/* */
/* Status */
/* */
/**************************************************************************/
UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol)
{
/* Sanity check. */
if (hid == UX_NULL)
return(UX_INVALID_PARAMETER);

/* Validate protocol value: must be BOOT(0) or REPORT(1). */
if (protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT &&
protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT)
return(UX_INVALID_PARAMETER);

/* Invoke protocol set function. */
return(_ux_host_class_hid_protocol_set(hid, protocol));
}
Loading