diff --git a/common/usbx_device_classes/inc/ux_device_class_hid.h b/common/usbx_device_classes/inc/ux_device_class_hid.h index 5dead7db..781f4607 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -1,10 +1,10 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * 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 **************************************************************************/ @@ -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; @@ -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; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c index 83305021..04ae23e1 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c @@ -1,17 +1,17 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * 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 */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -28,44 +28,44 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_control_request PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_control_request PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function manages the based sent by the host on the control */ -/* endpoints with a CLASS or VENDOR SPECIFIC type. */ -/* */ -/* INPUT */ -/* */ -/* hid Pointer to hid class */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _ux_device_stack_transfer_request Transfer request */ +/* */ +/* This function manages the based sent by the host on the control */ +/* endpoints with a CLASS or VENDOR SPECIFIC type. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to hid class */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_transfer_request Transfer request */ /* _ux_device_class_hid_report_get Process Get_Report request */ /* _ux_device_class_hid_report_set Process Set_Report request */ /* _ux_device_class_hid_descriptor_send Send requested descriptor */ -/* */ -/* CALLED BY */ -/* */ +/* */ +/* CALLED BY */ +/* */ /* HID Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* prefixed UX to MS_TO_TICK, */ @@ -119,10 +119,10 @@ UX_SLAVE_CLASS_HID *hid; /* Duration - upper byte of wValue. */ duration = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE + 1); - + /* Get the class container. */ class_ptr = command -> ux_slave_class_command_class_ptr; - + /* Get the storage instance from this class container. */ hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; @@ -149,8 +149,8 @@ UX_SLAVE_CLASS_HID *hid; /* Send the requested descriptor to the host. */ _ux_device_class_hid_descriptor_send(hid, request_value, request_index, request_length); - break; - + break; + case UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE: case UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE: @@ -204,15 +204,43 @@ UX_SLAVE_CLASS_HID *hid; case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL: - /* Send the protocol. */ + /* Only boot subclass devices should respond to GET_PROTOCOL. */ + if ((hid->ux_slave_class_hid_interface == UX_NULL) || + (hid->ux_slave_class_hid_interface->ux_slave_interface_descriptor.bInterfaceSubClass != 0x01)) + { + return (UX_ERROR); + } + + /* 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); + } + + /* Only boot subclass devices are expected to handle SET_PROTOCOL. */ + if ((hid->ux_slave_class_hid_interface == UX_NULL) || + (hid->ux_slave_class_hid_interface->ux_slave_interface_descriptor.bInterfaceSubClass != 0x01)) + { + /* Not a boot subclass: not handled. */ + return (UX_ERROR); + } + + /* 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); + /* Accept the protocol. */ hid -> ux_device_class_hid_protocol = request_value; + break; default: @@ -224,4 +252,3 @@ UX_SLAVE_CLASS_HID *hid; /* It's handled. */ return(UX_SUCCESS); } - diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c index a23aca30..afad6a50 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c @@ -1,16 +1,16 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * 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 */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -27,46 +27,46 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_initialize PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_initialize PORTABLE C */ /* 6.3.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function initializes the USB HID device. */ -/* This function is called by the class register function. It is only */ -/* done once. */ -/* */ -/* INPUT */ -/* */ -/* command Pointer to hid command */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* */ +/* This function initializes the USB HID device. */ +/* This function is called by the class register function. It is only */ +/* done once. */ +/* */ +/* INPUT */ +/* */ +/* command Pointer to hid command */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_utility_memory_allocate Allocate memory */ /* _ux_utility_memory_free Free memory */ /* _ux_device_thread_create Create thread */ /* _ux_device_thread_delete Delete thread */ /* _ux_utility_event_flags_create Create event flags group */ -/* */ -/* CALLED BY */ -/* */ -/* USBX Source Code */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Source Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* used UX prefix to refer to */ @@ -97,7 +97,7 @@ /**************************************************************************/ UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) { - + UX_SLAVE_CLASS_HID *hid; UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; UX_SLAVE_CLASS *class_ptr; @@ -149,9 +149,9 @@ UCHAR *buffer; #if !defined(UX_DEVICE_STANDALONE) /* Allocate some memory for the thread stack. */ - class_ptr -> ux_slave_class_thread_stack = + class_ptr -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE); - + /* Check for successful allocation. */ if (class_ptr -> ux_slave_class_thread_stack == UX_NULL) status = UX_MEMORY_INSUFFICIENT; @@ -160,7 +160,7 @@ UCHAR *buffer; a new thread. We pass a pointer to the class to the new thread. This thread does not start until we have a instance of the class. */ if (status == UX_SUCCESS) - status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", + status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", _ux_device_class_hid_interrupt_thread, (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) class_ptr -> ux_slave_class_thread_stack, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, @@ -195,6 +195,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; #if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) @@ -263,7 +264,7 @@ UCHAR *buffer; if (hid -> ux_device_class_hid_event_array != UX_NULL) { - /* Initialize the head and tail of the notification round robin buffers. + /* Initialize the head and tail of the notification round robin buffers. At first, the head and tail are pointing to the beginning of the array. */ hid -> ux_device_class_hid_event_array_head = hid -> ux_device_class_hid_event_array; hid -> ux_device_class_hid_event_array_tail = hid -> ux_device_class_hid_event_array; @@ -392,7 +393,7 @@ UCHAR *buffer; /* */ /* INPUT */ /* */ -/* command Pointer to hid command */ +/* command Pointer to hid command */ /* */ /* OUTPUT */ /* */