summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrédéric Desbiens <[email protected]>2025-10-02 15:30:29 +0100
committerGitHub <[email protected]>2025-10-02 15:30:29 +0100
commit68aee7d1053bad353f941a7e71b46585c7398270 (patch)
tree1c1dcf0ad233ec403ea1a7d2b6f4414b3843bddc
parentcfdd55c48a2f44afa55cdb198fe65ddb0c8565ba (diff)
parentb04317108a3db8ac052d864c185093419e5d7b58 (diff)
Merge pull request #211 from eclipse-threadx/devv6.4.3.202503_relv.6.4.3.2025_rel
Merge changes ahead of the v.6.4.3.202503 release.
-rw-r--r--common/core/inc/ux_api.h8
-rw-r--r--common/core/inc/ux_utility.h2
-rw-r--r--common/usbx_device_classes/src/ux_device_class_hid_deactivate.c4
-rw-r--r--common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c4
-rw-r--r--common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c14
-rw-r--r--common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c14
-rw-r--r--common/usbx_device_classes/src/ux_device_class_storage_initialize.c19
-rw-r--r--common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c117
-rw-r--r--common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c8
-rw-r--r--common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c73
-rw-r--r--common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c183
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c96
-rw-r--r--common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c107
-rw-r--r--common/usbx_host_classes/src/ux_host_class_hid_report_item_analyse.c20
-rw-r--r--ports/cortex_m33/gnu/CMakeLists.txt9
-rw-r--r--ports/cortex_m33/gnu/inc/ux_port.h262
-rw-r--r--ports/cortex_m33/iar/inc/ux_port.h264
-rw-r--r--test/cmake/usbx/regression/CMakeLists.txt1
-rw-r--r--test/regression/usbx_ux_utility_time_elapsed_test.c366
-rw-r--r--test/regression/ux_test.c4
20 files changed, 1336 insertions, 239 deletions
diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h
index 5f5feba..87b6b9c 100644
--- a/common/core/inc/ux_api.h
+++ b/common/core/inc/ux_api.h
@@ -348,7 +348,9 @@ typedef signed char SCHAR;
#define AZURE_RTOS_USBX
#define USBX_MAJOR_VERSION 6
#define USBX_MINOR_VERSION 4
-#define USBX_PATCH_VERSION 2
+#define USBX_PATCH_VERSION 3
+#define USBX_BUILD_VERSION 202503
+#define USBX_HOTFIX_VERSION ''
/* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */
@@ -2747,9 +2749,9 @@ typedef struct UX_HOST_CLASS_DPUMP_STRUCT
/* Define USBX Services. */
#if defined(UX_SYSTEM_ENABLE_ERROR_CHECKING)
-#define ux_system_initialize _ux_system_initialize
-#else
#define ux_system_initialize _uxe_system_initialize
+#else
+#define ux_system_initialize _ux_system_initialize
#endif
#define ux_system_uninitialize _ux_system_uninitialize
diff --git a/common/core/inc/ux_utility.h b/common/core/inc/ux_utility.h
index 8a8ea98..c2fd8f4 100644
--- a/common/core/inc/ux_utility.h
+++ b/common/core/inc/ux_utility.h
@@ -172,7 +172,7 @@ extern ULONG _ux_utility_time_get(VOID);
#endif
#ifndef _ux_utility_time_elapsed
-#define _ux_utility_time_elapsed(a,b) (((b)>=(a)) ? ((b)-(a)) : (0xFFFFFFFFul-(b)+(a)+1))
+#define _ux_utility_time_elapsed(a,b) (((b)>=(a)) ? ((b)-(a)) : (0xFFFFFFFFul-(a)+(b)+1))
#else
extern ALIGN_TYPE _ux_utility_time_elapsed(ALIGN_TYPE, ALIGN_TYPE);
#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c
index c83e1bd..cf41404 100644
--- a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c
+++ b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c
@@ -86,6 +86,10 @@ UX_SLAVE_CLASS *class_ptr;
/* Terminate the transactions pending on the endpoints. */
_ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_interrupt_endpoint, UX_TRANSFER_BUS_RESET);
+#if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT)
+ _ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_read_endpoint, UX_TRANSFER_BUS_RESET);
+#endif
+
/* If there is a deactivate function call it. */
if (hid -> ux_slave_class_hid_instance_deactivate != UX_NULL)
{
diff --git a/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c
index 08db3f2..290bea1 100644
--- a/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c
@@ -169,10 +169,10 @@ UCHAR *buffer;
_ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_1, pima_event.ux_device_class_pima_event_parameter_1);
/* Put the value of parameter 2. */
- _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_3);
+ _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_2);
/* Put the value of parameter 3. */
- _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_3);
+ _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_3, pima_event.ux_device_class_pima_event_parameter_3);
/* Send the request to the device controller. */
status = _ux_device_stack_transfer_request(transfer_request_in, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH);
diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c b/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c
index 4d64c6a..557c386 100644
--- a/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c
+++ b/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c
@@ -223,10 +223,18 @@ ULONG object_handle;
/* Send the object to the application. */
status = pima -> ux_device_class_pima_object_info_send(pima, object, storage_id, parent_object_handle, &object_handle);
- /* Now we return a response with success. */
- status = (status == UX_SUCCESS) ? UX_DEVICE_CLASS_PIMA_RC_OK : status;
- _ux_device_class_pima_response_send(pima, status, 3, pima -> ux_device_class_pima_storage_id,
+ if (status != UX_SUCCESS)
+ {
+ /* Now we return a response with error. */
+ _ux_device_class_pima_response_send(pima, status, 3, pima -> ux_device_class_pima_storage_id,
object -> ux_device_class_pima_object_parent_object, object_handle);
+ }
+ else
+ {
+ /* Now we return a response with success. */
+ _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_OK, 3, pima -> ux_device_class_pima_storage_id,
+ object -> ux_device_class_pima_object_parent_object, object_handle);
+ }
/* Store the object handle. It will be used for the OBJECT_SEND command. */
pima -> ux_device_class_pima_current_object_handle = object_handle;
diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c b/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c
index d9c704d..5197f06 100644
--- a/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c
+++ b/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c
@@ -128,10 +128,16 @@ ULONG object_references_length;
/* Send the object references to the application. */
status = pima -> ux_device_class_pima_object_references_set(pima, object_handle, object_references, object_references_length);
-
- /* Now we return a response with success. */
- status = (status == UX_SUCCESS) ? UX_DEVICE_CLASS_PIMA_RC_OK : status;
- _ux_device_class_pima_response_send(pima, status, 0, 0, 0, 0);
+
+ /* Check error code from application. */
+ if (status == UX_SUCCESS)
+
+ /* Now we return a response with success. */
+ _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_OK, 0, 0, 0, 0);
+ else
+
+ /* We return an error. The code is passed by the application. */
+ _ux_device_class_pima_response_send(pima, status, 0, 0, 0, 0);
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c
index 0ec29d8..c6f393e 100644
--- a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c
@@ -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
**************************************************************************/
@@ -30,7 +30,7 @@
/* Define the Slave Storage Class Inquiry data : DO NOT CHANGE THE LENGTH OF THESE ITEMS */
-UCHAR _ux_system_slave_class_storage_vendor_id[] = "AzureRTO";
+UCHAR _ux_system_slave_class_storage_vendor_id[] = "Eclipse ";
UCHAR _ux_system_slave_class_storage_product_id[] = "USBX storage dev";
UCHAR _ux_system_slave_class_storage_product_rev[] = "2000";
UCHAR _ux_system_slave_class_storage_product_serial[] = "12345678901234567890";
@@ -290,8 +290,17 @@ UINT i;
storage_parameter = command -> ux_slave_class_command_parameter;
/* Sanity checks. */
- if (storage_parameter -> ux_slave_class_storage_parameter_number_lun > UX_MAX_SLAVE_LUN)
+ if ((storage_parameter -> ux_slave_class_storage_parameter_number_lun > UX_MAX_SLAVE_LUN) ||
+ ((storage_parameter -> ux_slave_class_storage_parameter_vendor_id != UX_NULL) &&
+ ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_vendor_id) != 8)) ||
+ ((storage_parameter -> ux_slave_class_storage_parameter_product_id != UX_NULL) &&
+ ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_product_id) != 16)) ||
+ ((storage_parameter -> ux_slave_class_storage_parameter_product_rev != UX_NULL) &&
+ ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_product_rev) != 4)) ||
+ ((storage_parameter -> ux_slave_class_storage_parameter_product_serial != UX_NULL) &&
+ ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_product_serial) != 20)))
return(UX_INVALID_PARAMETER);
+
for (i = 0; i < storage_parameter -> ux_slave_class_storage_parameter_number_lun; i ++)
{
if ((storage_parameter -> ux_slave_class_storage_parameter_lun[i].
diff --git a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c
index eb9cc4b..f93505d 100644
--- a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c
+++ b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c
@@ -11,8 +11,8 @@
/**************************************************************************/
/**************************************************************************/
-/** */
-/** USBX Component */
+/** */
+/** USBX Component */
/** */
/** Audio Class */
/** */
@@ -37,44 +37,44 @@ static inline UINT _ux_host_class_audio_alternate_setting_locate_2(
#endif
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _ux_host_class_audio_alternate_setting_locate PORTABLE C */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_host_class_audio_alternate_setting_locate PORTABLE C */
/* 6.1.12 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
-/* */
+/* */
/* This function finds the right alternate setting according to the */
-/* sampling desired. */
-/* */
-/* INPUT */
-/* */
-/* audio Pointer to audio class */
-/* audio_sampling Pointer to audio sampling */
-/* alternate_setting Pointer to located alternate */
-/* setting */
-/* */
-/* OUTPUT */
-/* */
-/* Completion Status */
-/* */
-/* CALLS */
-/* */
-/* _ux_utility_descriptor_parse Parse descriptor */
-/* */
-/* CALLED BY */
-/* */
-/* Audio Class */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
+/* sampling desired. */
+/* */
+/* INPUT */
+/* */
+/* audio Pointer to audio class */
+/* audio_sampling Pointer to audio sampling */
+/* alternate_setting Pointer to located alternate */
+/* setting */
+/* */
+/* OUTPUT */
+/* */
+/* Completion Status */
+/* */
+/* CALLS */
+/* */
+/* _ux_utility_descriptor_parse Parse descriptor */
+/* */
+/* CALLED BY */
+/* */
+/* Audio Class */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1 */
@@ -101,23 +101,21 @@ UINT interface_found;
ULONG lower_frequency;
ULONG higher_frequency;
UINT specific_frequency_count;
-
+
/* Get the descriptor to the entire configuration. */
descriptor = audio -> ux_host_class_audio_configuration_descriptor;
total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length;
-
- /* Default is Interface descriptor not yet found. */
+
+ /* Default is Interface descriptor not yet found. */
interface_found = UX_FALSE;
-
+
/* Scan the descriptor for the Audio Streaming interface. */
while (total_descriptor_length)
{
/* Gather the length, type and subtype of the descriptor. */
descriptor_length = *descriptor;
- descriptor_type = *(descriptor + 1);
- descriptor_subtype = *(descriptor + 2);
/* Make sure this descriptor has at least the minimum length. */
if (descriptor_length < 3)
@@ -131,6 +129,10 @@ UINT specific_frequency_count;
return(UX_DESCRIPTOR_CORRUPTED);
}
+
+ descriptor_type = *(descriptor + 1);
+ descriptor_subtype = *(descriptor + 2);
+
/* Process relative to descriptor type. */
switch (descriptor_type)
{
@@ -149,7 +151,7 @@ UINT specific_frequency_count;
/* Mark we have found it. */
interface_found = UX_TRUE;
-
+
/* And memorize the alternate setting. */
*alternate_setting = interface_descriptor.bAlternateSetting;
}
@@ -160,8 +162,8 @@ UINT specific_frequency_count;
interface_found = UX_FALSE;
}
break;
-
-
+
+
case UX_HOST_CLASS_AUDIO_CS_INTERFACE:
/* First make sure we have found the correct generic interface descriptor. */
@@ -173,7 +175,7 @@ UINT specific_frequency_count;
UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &audio_interface_descriptor);
/* This descriptor must refer to a PCM audio type. */
- if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I)
+ if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I)
break;
/* The number of channels demanded by the application must match. */
@@ -188,18 +190,30 @@ UINT specific_frequency_count;
as a min and max frequency or an array of specified values. */
if (audio_interface_descriptor.bSamFreqType == 0)
{
-
+
+ if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 6))
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* The declaration of frequency is contiguous, so get the minimum and maximum */
lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2)) << 16;
higher_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 3) |
- ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
+ ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16;
/* Now compare with what is required. */
- if ((audio_sampling -> ux_host_class_audio_sampling_frequency >= lower_frequency) &&
+ if ((audio_sampling -> ux_host_class_audio_sampling_frequency >= lower_frequency) &&
(audio_sampling -> ux_host_class_audio_sampling_frequency <= higher_frequency))
{
@@ -211,6 +225,11 @@ UINT specific_frequency_count;
else
{
+ if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (UINT)(3 * audio_interface_descriptor.bSamFreqType)))
+ {
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* The declaration of the frequency is declared as an array of specific values. */
for (specific_frequency_count = 0; specific_frequency_count < audio_interface_descriptor.bSamFreqType;
specific_frequency_count++)
@@ -229,10 +248,10 @@ UINT specific_frequency_count;
return(UX_SUCCESS);
}
}
- }
+ }
}
break;
- }
+ }
/* Verify if the descriptor is still valid. */
if (descriptor_length > total_descriptor_length)
@@ -243,7 +262,7 @@ UINT specific_frequency_count;
return(UX_DESCRIPTOR_CORRUPTED);
}
-
+
/* Jump to the next descriptor if we have not reached the end. */
descriptor += descriptor_length;
diff --git a/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c
index 6db04dc..3b4aebd 100644
--- a/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c
+++ b/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c
@@ -102,7 +102,7 @@ UINT status;
/* Ensure the instance is valid. */
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS)
- {
+ {
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN);
@@ -134,12 +134,13 @@ UINT status;
/* Gather the length, type and subtype of the descriptor. */
descriptor_length = *descriptor;
- descriptor_type = *(descriptor + 1);
- /* Make sure this descriptor has at least the minimum length. */
+ /* Make sure this descriptor has at least the minimum length. */
if (descriptor_length < 3)
return(UX_DESCRIPTOR_CORRUPTED);
+ descriptor_type = *(descriptor + 1);
+
/* Process relative to descriptor type. */
switch (descriptor_type)
{
@@ -173,7 +174,6 @@ UINT status;
/* Have we found the audio interface yet? */
if (interface_descriptor != UX_NULL)
{
-
/* Yes, parse the audio specific descriptor. */
status = parse_function(arg, interface_descriptor, endpoint_descriptor, descriptor);
diff --git a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c
index ff0fd9a..0a850bd 100644
--- a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c
+++ b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c
@@ -161,6 +161,7 @@ struct UX_HOST_CLASS_AUDIO10_SAM_PARSER *parser = (struct UX_HOST_CLAS
UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr;
ULONG n, offset;
UINT status;
+UINT descriptor_length = packed_audio_descriptor[0];
UX_PARAMETER_NOT_USED(packed_endpoint_descriptor);
@@ -178,10 +179,32 @@ UINT status;
if (packed_audio_descriptor[2] != UX_HOST_CLASS_AUDIO_CS_FORMAT_TYPE)
return(0);
+ if (descriptor_length < 4)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* Check bFormatType @ 3. */
if (packed_audio_descriptor[3] != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I)
return(0);
+ if (descriptor_length < 8)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* Get bNrChannels @ 4. */
sam_attr.ux_host_class_audio_sampling_characteristics_channels = packed_audio_descriptor[4];
@@ -196,6 +219,16 @@ UINT status;
/* Check bSamFreqType @ 7. */
if (packed_audio_descriptor[7] == 0)
{
+ if (descriptor_length < 14)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
/* Continuous, get dLowSamFreq and dHighSamFreq. */
sam_attr.ux_host_class_audio_sampling_characteristics_frequency_low =
@@ -213,6 +246,16 @@ UINT status;
}
else
{
+ if (descriptor_length < (UINT)(8 + (3 * packed_audio_descriptor[7])))
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
/* Parse list of sampling characteristics. */
for (n = 0, offset = 8;
@@ -271,6 +314,7 @@ static UINT _ux_host_class_audio_ac_find_parse(VOID *arg,
UCHAR *packed_audio_descriptor)
{
struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *finder = (struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *)arg;
+UINT descriptor_length = packed_audio_descriptor[0];
UX_PARAMETER_NOT_USED(packed_endpoint_descriptor);
@@ -289,6 +333,17 @@ struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *finder = (struct UX_HOST_CLAS
if (packed_audio_descriptor[2] != finder -> subtype)
return(0);
+ if (descriptor_length < 4)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(0);
+ }
+
/* Check bEntityID @ 3. */
if (packed_audio_descriptor[3] != finder -> id)
return(0);
@@ -332,7 +387,7 @@ UINT status;
if (audio -> ux_host_class_audio_type == UX_HOST_CLASS_AUDIO_INPUT)
{
-
+
/* If audio input, streaming is from output terminal (OT). */
descriptor = _ux_host_class_audio_ac_find(audio,
UX_CLASS_AUDIO20_AC_OUTPUT_TERMINAL,
@@ -546,6 +601,7 @@ UX_TRANSFER *transfer;
UCHAR *buffer;
ULONG n_sub, param_len, offset;
UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr;
+UINT descriptor_length = packed_audio_descriptor[0];
UX_PARAMETER_NOT_USED(packed_endpoint_descriptor);
@@ -571,6 +627,19 @@ UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr;
/* Check bDescriptorSubType@2, bFormatType@3 to confirm FORMAT_TYPE_I. */
if (packed_audio_descriptor[2] != UX_CLASS_AUDIO20_AS_FORMAT_TYPE)
return(0);
+
+ if (descriptor_length < 6)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ parser -> status = UX_DESCRIPTOR_CORRUPTED;
+ return(1);
+ }
+
if (packed_audio_descriptor[3] != UX_CLASS_AUDIO20_FORMAT_TYPE_I)
return(0);
@@ -654,7 +723,7 @@ UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr;
parser -> status = UX_MATH_OVERFLOW;
return(1);
}
-
+
/* Allocate buffer for GET_RANGE. */
buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, param_len);
if (buffer == UX_NULL)
diff --git a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c
index bb3aefb..9cd2025 100644
--- a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c
+++ b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c
@@ -11,8 +11,8 @@
/**************************************************************************/
/**************************************************************************/
-/** */
-/** USBX Component */
+/** */
+/** USBX Component */
/** */
/** Audio Class */
/** */
@@ -29,48 +29,48 @@
#include "ux_host_stack.h"
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _ux_host_class_audio_streaming_sampling_get PORTABLE C */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_host_class_audio_streaming_sampling_get PORTABLE C */
/* 6.1.12 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
-/* */
-/* This function obtains successive sampling characteristics for the */
-/* audio streaming channel. */
+/* */
+/* This function obtains successive sampling characteristics for the */
+/* audio streaming channel. */
/* */
/* Note only Audio 1.0 and RAW (PCM like) format is supported. */
-/* */
-/* INPUT */
-/* */
-/* audio Pointer to audio class */
-/* audio_sampling Pointer to audio sampling */
-/* */
-/* OUTPUT */
-/* */
-/* Completion Status */
-/* */
-/* CALLS */
-/* */
-/* _ux_host_stack_class_instance_verify Verify instance is valid */
-/* _ux_utility_descriptor_parse Parse the descriptor */
+/* */
+/* INPUT */
+/* */
+/* audio Pointer to audio class */
+/* audio_sampling Pointer to audio sampling */
+/* */
+/* OUTPUT */
+/* */
+/* Completion Status */
+/* */
+/* CALLS */
+/* */
+/* _ux_host_stack_class_instance_verify Verify instance is valid */
+/* _ux_utility_descriptor_parse Parse the descriptor */
/* _ux_host_mutex_on Get mutex */
/* _ux_host_mutex_off Put mutex */
-/* */
-/* CALLED BY */
-/* */
-/* Application */
-/* Audio Class */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
+/* */
+/* CALLED BY */
+/* */
+/* Application */
+/* Audio Class */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1 */
@@ -101,13 +101,13 @@ ULONG lower_frequency;
ULONG higher_frequency;
UINT specific_frequency_count;
UINT previous_match_found;
-
+
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_STREAMING_SAMPLING_GET, audio, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
/* Ensure the instance is valid. */
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS)
- {
+ {
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN);
@@ -127,18 +127,16 @@ UINT previous_match_found;
/* Get the descriptor to the entire configuration. */
descriptor = audio -> ux_host_class_audio_configuration_descriptor;
total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length;
-
- /* Default is Interface descriptor not yet found. */
+
+ /* Default is Interface descriptor not yet found. */
interface_found = UX_FALSE;
-
+
/* Scan the descriptor for the Audio Streaming interface. */
while (total_descriptor_length)
{
/* Gather the length, type and subtype of the descriptor. */
descriptor_length = *descriptor;
- descriptor_type = *(descriptor + 1);
- descriptor_subtype = *(descriptor + 2);
/* Make sure this descriptor has at least the minimum length. */
if (descriptor_length < 3)
@@ -156,6 +154,9 @@ UINT previous_match_found;
return(UX_DESCRIPTOR_CORRUPTED);
}
+ descriptor_type = *(descriptor + 1);
+ descriptor_subtype = *(descriptor + 2);
+
/* Process relative to descriptor type. */
switch(descriptor_type)
{
@@ -180,7 +181,7 @@ UINT previous_match_found;
interface_found = UX_FALSE;
}
break;
-
+
case UX_HOST_CLASS_AUDIO_CS_INTERFACE:
@@ -193,12 +194,12 @@ UINT previous_match_found;
UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &audio_interface_descriptor);
/* This descriptor must refer to a PCM audio type. */
- if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I)
+ if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I)
break;
/* If this is the first time we ask for a streaming interface characteristics
we return the first we find. */
- if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_channels == 0) &&
+ if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_channels == 0) &&
(audio_sampling -> ux_host_class_audio_sampling_characteristics_resolution == 0))
{
@@ -207,24 +208,52 @@ UINT previous_match_found;
if (audio_interface_descriptor.bSamFreqType == 0)
{
-
+
+ if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 6))
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Unprotect thread reentry to this instance. */
+ _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* The declaration of frequency is contiguous, so get the minimum and maximum */
- audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low =
+ audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low =
(ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2)) << 16;
- audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high =
+ audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high =
(ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 3) |
- ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
+ ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16;
}
else
{
- /* The declaration of the frequency is declared as an array of specific values.
+ if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (UINT)(3 * audio_interface_descriptor.bSamFreqType)))
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Unprotect thread reentry to this instance. */
+ _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
+ /* The declaration of the frequency is declared as an array of specific values.
We take the first one here. */
- audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low =
+ audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low =
(ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH ) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1 )) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2 )) << 16;
@@ -248,16 +277,30 @@ UINT previous_match_found;
(audio_sampling -> ux_host_class_audio_sampling_characteristics_resolution == audio_interface_descriptor.bBitResolution))
{
- if (audio_interface_descriptor.bSamFreqType == 0)
- {
-
+ if (audio_interface_descriptor.bSamFreqType == 0)
+ {
+
+ if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 6))
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Unprotect thread reentry to this instance. */
+ _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* The declaration of frequency is contiguous, so get the minimum and maximum. */
lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2)) << 16;
higher_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 3) |
- ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
+ ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16;
if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low == lower_frequency) &&
@@ -272,6 +315,20 @@ UINT previous_match_found;
else
{
+ if (descriptor_length < UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (UINT)(3 * audio_interface_descriptor.bSamFreqType))
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Unprotect thread reentry to this instance. */
+ _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex);
+
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* The declaration of the frequency is declared as an array of specific values. */
for (specific_frequency_count = 0; specific_frequency_count < audio_interface_descriptor.bSamFreqType; specific_frequency_count++)
{
@@ -283,7 +340,7 @@ UINT previous_match_found;
/* Compare the frequency. */
if (audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low == lower_frequency)
{
-
+
previous_match_found = UX_TRUE;
}
else
@@ -306,7 +363,7 @@ UINT previous_match_found;
/* Return successful completion. */
return(UX_SUCCESS);
}
- }
+ }
}
}
}
@@ -325,14 +382,14 @@ UINT previous_match_found;
if (audio_interface_descriptor.bSamFreqType == 0)
{
-
+
/* The declaration of frequency is contiguous, so get the minimum and maximum. */
lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2)) << 16;
higher_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 3) |
- ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
+ ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16;
audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low = lower_frequency;
@@ -344,7 +401,7 @@ UINT previous_match_found;
/* Return successful completion. */
return(UX_SUCCESS);
}
- else
+ else
{
lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) |
@@ -362,9 +419,9 @@ UINT previous_match_found;
}
}
}
- }
+ }
}
- }
+ }
/* Verify the descriptor is still valid. */
if (descriptor_length > total_descriptor_length)
@@ -421,8 +478,8 @@ UINT previous_match_found;
/* */
/* INPUT */
/* */
-/* audio Pointer to audio class */
-/* audio_sampling Pointer to audio sampling */
+/* audio Pointer to audio class */
+/* audio_sampling Pointer to audio sampling */
/* */
/* OUTPUT */
/* */
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c
index 8c24bc1..88d0a4c 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c
@@ -1,18 +1,18 @@
/***************************************************************************
- * 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 */
/** */
/** CDC_ECM Class */
/** */
@@ -30,32 +30,32 @@
#if !defined(UX_HOST_STANDALONE)
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _ux_host_class_cdc_ecm_thread PORTABLE C */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_host_class_cdc_ecm_thread PORTABLE C */
/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
-/* */
+/* */
/* This is the CDC ECM thread that monitors the link change flag, */
/* receives data from the device, and passes the data to the NetX-USB */
-/* broker. */
-/* */
-/* INPUT */
-/* */
-/* cdc_ecm CDC ECM instance */
-/* */
-/* OUTPUT */
-/* */
-/* Completion Status */
-/* */
-/* CALLS */
-/* */
+/* broker. */
+/* */
+/* INPUT */
+/* */
+/* cdc_ecm CDC ECM instance */
+/* */
+/* OUTPUT */
+/* */
+/* Completion Status */
+/* */
+/* CALLS */
+/* */
/* _ux_host_class_cdc_ecm_transmit_queue_clean */
/* Clean transmit queue */
/* _ux_host_stack_transfer_request Transfer request */
@@ -67,15 +67,15 @@
/* _ux_network_driver_packet_received Process received packet */
/* nx_packet_allocate Allocate NetX packet */
/* nx_packet_release Free NetX packet */
-/* */
-/* CALLED BY */
-/* */
-/* CDC ECM class initialization */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
+/* */
+/* CALLED BY */
+/* */
+/* CDC ECM class initialization */
+/* */
+/* 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, */
@@ -114,9 +114,9 @@ ULONG packet_buffer_size;
/* Cast the parameter passed in the thread into the cdc_ecm pointer. */
UX_THREAD_EXTENSION_PTR_GET(cdc_ecm, UX_HOST_CLASS_CDC_ECM, parameter)
- /* Loop forever waiting for changes signaled through the semaphore. */
+ /* Loop forever waiting for changes signaled through the semaphore. */
while (1)
- {
+ {
/* Wait for the semaphore to be put by the cdc_ecm interrupt event. */
_ux_host_semaphore_get_norc(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore, UX_WAIT_FOREVER);
@@ -130,10 +130,10 @@ ULONG packet_buffer_size;
/* Communicate the state with the network driver. */
_ux_network_driver_link_up(cdc_ecm -> ux_host_class_cdc_ecm_network_handle);
-
+
/* As long as we are connected, configured and link up ... do some work.... */
while ((cdc_ecm -> ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP) &&
- (cdc_ecm -> ux_host_class_cdc_ecm_device -> ux_device_state == UX_DEVICE_CONFIGURED))
+ (cdc_ecm -> ux_host_class_cdc_ecm_device -> ux_device_state == UX_DEVICE_CONFIGURED))
{
/* Check if we have packet pool available. */
@@ -154,7 +154,7 @@ ULONG packet_buffer_size;
{
/* IP instance is not available, wait for application to attach the interface. */
- _ux_utility_delay_ms(UX_MS_TO_TICK(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT));
+ _ux_utility_delay_ms(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT);
}
continue;
}
@@ -168,7 +168,7 @@ ULONG packet_buffer_size;
/* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
packet -> nx_packet_prepend_ptr += sizeof(USHORT);
-
+
/* We have a packet. Link this packet to the reception transfer request on the bulk in endpoint. */
transfer_request = &cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_endpoint -> ux_endpoint_transfer_request;
@@ -206,18 +206,18 @@ ULONG packet_buffer_size;
#endif
{
- /* Set the data pointer. */
+ /* Set the data pointer. */
transfer_request -> ux_transfer_request_data_pointer = packet -> nx_packet_prepend_ptr;
-
+
}
/* And length. */
transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE;
transfer_request -> ux_transfer_request_actual_length = 0;
-
+
/* Store the packet that owns this transaction. */
transfer_request -> ux_transfer_request_user_specific = packet;
-
+
/* Reset the queue pointer of this packet. */
packet -> nx_packet_queue_next = UX_NULL;
@@ -235,7 +235,7 @@ ULONG packet_buffer_size;
cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_check_and_arm_in_process = UX_FALSE;
if (cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish == UX_TRUE)
_ux_host_semaphore_put(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore);
-
+
/* Check if the transaction was armed successfully. */
if (status == UX_SUCCESS)
{
@@ -280,13 +280,13 @@ ULONG packet_buffer_size;
{
/* Get the packet length. */
- packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length;
-
- /* Adjust the prepend, length, and append fields. */
+ packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length;
+
+ /* Adjust the prepend, length, and append fields. */
packet -> nx_packet_append_ptr =
packet->nx_packet_prepend_ptr + transfer_request -> ux_transfer_request_actual_length;
}
-
+
/* Send that packet to the NetX USB broker. */
_ux_network_driver_packet_received(cdc_ecm -> ux_host_class_cdc_ecm_network_handle, packet);
}
@@ -345,6 +345,6 @@ ULONG packet_buffer_size;
/* Set the link state. */
cdc_ecm -> ux_host_class_cdc_ecm_link_state = UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN;
}
- }
+ }
}
#endif
diff --git a/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c b/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c
index d112510..bb39cfe 100644
--- a/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c
+++ b/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c
@@ -11,8 +11,8 @@
/**************************************************************************/
/**************************************************************************/
-/** */
-/** USBX Component */
+/** */
+/** USBX Component */
/** */
/** HID Class */
/** */
@@ -29,47 +29,47 @@
#include "ux_host_stack.h"
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _ux_host_class_hid_report_descriptor_get PORTABLE C */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_host_class_hid_report_descriptor_get PORTABLE C */
/* 6.1 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
-/* */
-/* This function gets the report descriptor and analyzes it. */
-/* */
-/* INPUT */
-/* */
-/* hid Pointer to HID class */
-/* length Length of descriptor */
-/* */
-/* OUTPUT */
-/* */
-/* Completion Status */
-/* */
-/* CALLS */
-/* */
-/* _ux_host_class_hid_global_item_parse Parse global item */
-/* _ux_host_class_hid_local_item_parse Parse local item */
-/* _ux_host_class_hid_report_item_analyse Analyze report */
-/* _ux_host_class_hid_resources_free Free HID resources */
-/* _ux_host_stack_transfer_request Process transfer request */
-/* _ux_utility_memory_allocate Allocate memory block */
-/* _ux_utility_memory_free Release memory block */
-/* */
-/* CALLED BY */
-/* */
-/* HID Class */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
+/* */
+/* This function gets the report descriptor and analyzes it. */
+/* */
+/* INPUT */
+/* */
+/* hid Pointer to HID class */
+/* length Length of descriptor */
+/* */
+/* OUTPUT */
+/* */
+/* Completion Status */
+/* */
+/* CALLS */
+/* */
+/* _ux_host_class_hid_global_item_parse Parse global item */
+/* _ux_host_class_hid_local_item_parse Parse local item */
+/* _ux_host_class_hid_report_item_analyse Analyze report */
+/* _ux_host_class_hid_resources_free Free HID resources */
+/* _ux_host_stack_transfer_request Process transfer request */
+/* _ux_utility_memory_allocate Allocate memory block */
+/* _ux_utility_memory_free Release memory block */
+/* */
+/* CALLED BY */
+/* */
+/* HID Class */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1 */
@@ -112,14 +112,25 @@ UINT status;
/* Check for correct transfer and entire descriptor returned. */
if ((status == UX_SUCCESS) && (transfer_request -> ux_transfer_request_actual_length == length))
{
-
+ UINT analysis_failure;
/* Parse the report descriptor and build the report items. */
while (length)
{
-
/* Get one item from the report and analyze it. */
- _ux_host_class_hid_report_item_analyse(descriptor, &item);
+ /* Make sure this descriptor has at least the minimum length. */
+ analysis_failure = _ux_host_class_hid_report_item_analyse(descriptor, &item);
+ if (analysis_failure)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+ /* Return error status. */
+ status = (UX_DESCRIPTOR_CORRUPTED);
+ }
+
/* Point the descriptor right after the item identifier. */
descriptor += item.ux_host_class_hid_item_report_format;
@@ -133,7 +144,7 @@ UINT status;
status = _ux_host_class_hid_global_item_parse(hid, &item, descriptor);
break;
-
+
case UX_HOST_CLASS_HID_TYPE_MAIN:
/* This is a main item. */
@@ -145,13 +156,13 @@ UINT status;
/* This is a local item. */
status = _ux_host_class_hid_local_item_parse(hid, &item, descriptor);
- break;
+ break;
default:
/* This is a reserved item, meaning it shouldn't be used! */
- /* Set status to error. The check after this switch statement
+ /* Set status to error. The check after this switch statement
will handle the rest. */
status = UX_DESCRIPTOR_CORRUPTED;
break;
@@ -165,11 +176,17 @@ UINT status;
/* Jump to the next item. */
descriptor += item.ux_host_class_hid_item_report_length;
-
+
/* Verify that the report descriptor is not corrupted. */
- if (length < item.ux_host_class_hid_item_report_length)
+ if (length < (item.ux_host_class_hid_item_report_length + item.ux_host_class_hid_item_report_format))
{
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
/* Return error status. */
status = (UX_DESCRIPTOR_CORRUPTED);
break;
diff --git a/common/usbx_host_classes/src/ux_host_class_hid_report_item_analyse.c b/common/usbx_host_classes/src/ux_host_class_hid_report_item_analyse.c
index 68f0f6a..7ff20bf 100644
--- a/common/usbx_host_classes/src/ux_host_class_hid_report_item_analyse.c
+++ b/common/usbx_host_classes/src/ux_host_class_hid_report_item_analyse.c
@@ -73,7 +73,7 @@ UINT _ux_host_class_hid_report_item_analyse(UCHAR *descriptor, UX_HOST_CLASS_HI
{
UCHAR item_byte;
-
+UINT result = UX_SUCCESS;
/* Get the first byte from the descriptor. */
item_byte = *descriptor;
@@ -89,11 +89,19 @@ UCHAR item_byte;
/* Set the type. */
item -> ux_host_class_hid_item_report_type = (item_byte >> 2) & 3;
- /* Get its length (byte 1). */
- item -> ux_host_class_hid_item_report_length = (USHORT) *(descriptor + 1);
+ /* Make sure descriptor has minimal length.*/
+ if (sizeof(descriptor) >= 3)
+ {
+ /* Get its length (byte 1). */
+ item -> ux_host_class_hid_item_report_length = (USHORT) *(descriptor + 1);
- /* Then the tag (byte 2). */
- item -> ux_host_class_hid_item_report_tag = *(descriptor + 2);
+ /* Then the tag (byte 2). */
+ item -> ux_host_class_hid_item_report_tag = *(descriptor + 2);
+ }
+ else
+ {
+ result = UX_DESCRIPTOR_CORRUPTED;
+ }
}
else
{
@@ -124,6 +132,6 @@ UCHAR item_byte;
}
/* Return successful completion. */
- return(UX_SUCCESS);
+ return(result);
}
diff --git a/ports/cortex_m33/gnu/CMakeLists.txt b/ports/cortex_m33/gnu/CMakeLists.txt
new file mode 100644
index 0000000..75c7953
--- /dev/null
+++ b/ports/cortex_m33/gnu/CMakeLists.txt
@@ -0,0 +1,9 @@
+target_sources(${PROJECT_NAME} PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME} PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/inc
+)
diff --git a/ports/cortex_m33/gnu/inc/ux_port.h b/ports/cortex_m33/gnu/inc/ux_port.h
new file mode 100644
index 0000000..4785f60
--- /dev/null
+++ b/ports/cortex_m33/gnu/inc/ux_port.h
@@ -0,0 +1,262 @@
+/***************************************************************************
+ * 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* ux_port.h Cortex-M33/GNU */
+/* 6.3.0 */
+/* */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make USBX function */
+/* identically on a variety of different processor architectures. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
+/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
+/* resulting in version 6.1 */
+/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* moved tx_api.h include and */
+/* typedefs from ux_api.h, */
+/* resulting in version 6.1.10 */
+/* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
+/* added basic types guards, */
+/* improved SLONG typedef, */
+/* resulting in version 6.3.0 */
+/* */
+/**************************************************************************/
+
+#ifndef UX_PORT_H
+#define UX_PORT_H
+
+
+/* Determine if the optional USBX user define file should be used. */
+
+#ifdef UX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in ux_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "ux_user.h"
+#endif
+
+
+/* Include library header files. */
+
+#include <stdio.h>
+#include <string.h>
+
+
+#if !defined(UX_STANDALONE)
+#include "tx_api.h"
+#else
+
+/* VAR types used in UX,
+ if TX still used, expects tx_api.h included before include this. */
+#if !defined(TX_API_H) && !defined(TX_PORT_H)
+
+#include <stdint.h>
+#ifndef VOID
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+#endif
+
+#ifndef ULONG64_DEFINED
+typedef uint64_t ULONG64;
+#define ULONG64_DEFINED
+#endif
+
+#ifndef ALIGN_TYPE_DEFINED
+#define ALIGN_TYPE ULONG
+#define ALIGN_TYPE_DEFINED
+#endif
+
+#endif
+#endif
+
+
+/* CPU definition for X86 systems without preemptive timer function.
+ This will make USBX uses the controller for the timer. */
+
+#undef THREADX_X86_NO_PTIMER
+
+
+/* For X86 systems, the define #define UX_USE_IO_INSTRUCTIONS should be used. */
+
+
+/* Define additional generic USBX types. */
+
+#ifndef SLONG_DEFINED
+typedef LONG SLONG;
+#define SLONG_DEFINED
+#endif
+
+
+/* Generic USBX Project constants follow. */
+
+#ifndef UX_PERIODIC_RATE
+#define UX_PERIODIC_RATE 100
+#endif
+
+#ifndef UX_MAX_CLASS_DRIVER
+#define UX_MAX_CLASS_DRIVER 2
+#endif
+
+#ifndef UX_MAX_SLAVE_CLASS_DRIVER
+#define UX_MAX_SLAVE_CLASS_DRIVER 2
+#endif
+
+#ifndef UX_MAX_HCD
+#define UX_MAX_HCD 1
+#endif
+
+#ifndef UX_MAX_DEVICES
+#define UX_MAX_DEVICES 2
+#endif
+
+#ifndef UX_MAX_ED
+#define UX_MAX_ED 80
+#endif
+
+#ifndef UX_MAX_TD
+#define UX_MAX_TD 32
+#endif
+
+#ifndef UX_MAX_ISO_TD
+#define UX_MAX_ISO_TD 2
+#endif
+
+#ifndef UX_HOST_ENUM_THREAD_STACK_SIZE
+#define UX_HOST_ENUM_THREAD_STACK_SIZE (2*1024)
+#endif
+
+#ifndef UX_THREAD_STACK_SIZE
+#define UX_THREAD_STACK_SIZE (1*1024)
+#endif
+
+#ifndef UX_THREAD_PRIORITY_ENUM
+#define UX_THREAD_PRIORITY_ENUM 20
+#endif
+
+#ifndef UX_THREAD_PRIORITY_CLASS
+#define UX_THREAD_PRIORITY_CLASS 20
+#endif
+
+#ifndef UX_THREAD_PRIORITY_KEYBOARD
+#define UX_THREAD_PRIORITY_KEYBOARD 20
+#endif
+
+#ifndef UX_THREAD_PRIORITY_HCD
+#define UX_THREAD_PRIORITY_HCD 2
+#endif
+
+#ifndef UX_THREAD_PRIORITY_DCD
+#define UX_THREAD_PRIORITY_DCD 2
+#endif
+
+#ifndef UX_NO_TIME_SLICE
+#define UX_NO_TIME_SLICE 0
+#endif
+
+#ifndef UX_MAX_SLAVE_LUN
+#define UX_MAX_SLAVE_LUN 1
+#endif
+
+#ifndef UX_MAX_HOST_LUN
+#define UX_MAX_HOST_LUN 1
+#endif
+
+#ifndef UX_HOST_CLASS_STORAGE_MAX_MEDIA
+#define UX_HOST_CLASS_STORAGE_MAX_MEDIA 1
+#endif
+
+#ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH
+#define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256
+#endif
+
+
+#ifndef UX_SLAVE_REQUEST_DATA_MAX_LENGTH
+#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH 2048
+#endif
+
+#ifndef UX_USE_IO_INSTRUCTIONS
+
+/* Don't use IO instructions if this define is not set. Default to memory mapped. */
+
+#define inpb(a) *((UCHAR *) (a))
+#define inpw(a) *((USHORT *) (a))
+#define inpl(a) *((ULONG *) (a))
+#define outpb(a, b) *((UCHAR *) (a)) = ((UCHAR) (b))
+#define outpw(a, b) *((USHORT *) (a)) = ((USHORT) (b))
+#define outpl(a, b) *((ULONG *) (a)) = ((ULONG) (b))
+#else
+
+
+/* Define simple prototypes for non-memory mapped hardware access. */
+
+UCHAR inpb(ULONG);
+USHORT inpw(ULONG);
+ULONG inpl(ULONG);
+
+VOID outpb(ULONG,UCHAR);
+VOID outpw(ULONG,USHORT);
+VOID outpl(ULONG,ULONG);
+
+#endif
+
+
+/* Define interrupt lockout constructs to protect the memory allocation/release which could happen
+ under ISR in the device stack. */
+
+#define UX_INT_SAVE_AREA unsigned int old_interrupt_posture;
+#define UX_DISABLE_INTS old_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE);
+#define UX_RESTORE_INTS tx_interrupt_control(old_interrupt_posture);
+
+
+/* Define the version ID of USBX. This may be utilized by the application. */
+
+#ifdef UX_SYSTEM_INIT
+CHAR _ux_version_id[] =
+ "Copyright (c) 2024 Microsoft Corporation. * USBX Cortex-M33/GNU Version 6.4.1 *";
+#else
+extern CHAR _ux_version_id[];
+#endif
+
+#endif
+
diff --git a/ports/cortex_m33/iar/inc/ux_port.h b/ports/cortex_m33/iar/inc/ux_port.h
new file mode 100644
index 0000000..2c95986
--- /dev/null
+++ b/ports/cortex_m33/iar/inc/ux_port.h
@@ -0,0 +1,264 @@
+/***************************************************************************
+ * 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* ux_port.h Cortex-M33/IAR */
+/* 6.3.0 */
+/* */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make USBX function */
+/* identically on a variety of different processor architectures. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
+/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* moved tx_api.h include and */
+/* typedefs from ux_api.h, */
+/* resulting in version 6.1.10 */
+/* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
+/* added basic types guards, */
+/* improved SLONG typedef, */
+/* resulting in version 6.3.0 */
+/* */
+/**************************************************************************/
+
+#ifndef UX_PORT_H
+#define UX_PORT_H
+
+
+/* Determine if the optional USBX user define file should be used. */
+
+#ifdef UX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in ux_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "ux_user.h"
+#endif
+
+
+/* Include library header files. */
+
+#include <stdio.h>
+#include <string.h>
+
+
+#if !defined(UX_STANDALONE)
+#include "tx_api.h"
+#else
+
+/* VAR types used in UX,
+ if TX still used, expects tx_api.h included before include this. */
+#if !defined(TX_API_H) && !defined(TX_PORT_H)
+
+#include <stdint.h>
+#ifndef VOID
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+#endif
+
+#ifndef ULONG64_DEFINED
+typedef uint64_t ULONG64;
+#define ULONG64_DEFINED
+#endif
+
+#ifndef ALIGN_TYPE_DEFINED
+#define ALIGN_TYPE ULONG
+#define ALIGN_TYPE_DEFINED
+#endif
+
+#endif
+#endif
+
+
+/* CPU definition for X86 systems without preemptive timer function.
+ This will make USBX uses the controller for the timer. */
+
+#undef THREADX_X86_NO_PTIMER
+
+
+/* For X86 systems, the define #define UX_USE_IO_INSTRUCTIONS should be used. */
+
+
+/* Define additional generic USBX types. */
+
+#ifndef SLONG_DEFINED
+typedef LONG SLONG;
+#define SLONG_DEFINED
+#endif
+
+
+/* Generic USBX Project constants follow. */
+
+#ifndef UX_PERIODIC_RATE
+#define UX_PERIODIC_RATE 100
+#endif
+
+#ifndef UX_MAX_CLASS_DRIVER
+#define UX_MAX_CLASS_DRIVER 2
+#endif
+
+#ifndef UX_MAX_SLAVE_CLASS_DRIVER
+#define UX_MAX_SLAVE_CLASS_DRIVER 2
+#endif
+
+#ifndef UX_MAX_HCD
+#define UX_MAX_HCD 1
+#endif
+
+#ifndef UX_MAX_DEVICES
+#define UX_MAX_DEVICES 2
+#endif
+
+#ifndef UX_MAX_ED
+#define UX_MAX_ED 80
+#endif
+
+#ifndef UX_MAX_TD
+#define UX_MAX_TD 32
+#endif
+
+#ifndef UX_MAX_ISO_TD
+#define UX_MAX_ISO_TD 2
+#endif
+
+#ifndef UX_HOST_ENUM_THREAD_STACK_SIZE
+#define UX_HOST_ENUM_THREAD_STACK_SIZE (2*1024)
+#endif
+
+#ifndef UX_THREAD_STACK_SIZE
+#define UX_THREAD_STACK_SIZE (1*1024)
+#endif
+
+#ifndef UX_THREAD_PRIORITY_ENUM
+#define UX_THREAD_PRIORITY_ENUM 20
+#endif
+
+#ifndef UX_THREAD_PRIORITY_CLASS
+#define UX_THREAD_PRIORITY_CLASS 20
+#endif
+
+#ifndef UX_THREAD_PRIORITY_KEYBOARD
+#define UX_THREAD_PRIORITY_KEYBOARD 20
+#endif
+
+#ifndef UX_THREAD_PRIORITY_HCD
+#define UX_THREAD_PRIORITY_HCD 2
+#endif
+
+#ifndef UX_THREAD_PRIORITY_DCD
+#define UX_THREAD_PRIORITY_DCD 2
+#endif
+
+#ifndef UX_NO_TIME_SLICE
+#define UX_NO_TIME_SLICE 0
+#endif
+
+#ifndef UX_MAX_SLAVE_LUN
+#define UX_MAX_SLAVE_LUN 1
+#endif
+
+#ifndef UX_MAX_HOST_LUN
+#define UX_MAX_HOST_LUN 1
+#endif
+
+#ifndef UX_HOST_CLASS_STORAGE_MAX_MEDIA
+#define UX_HOST_CLASS_STORAGE_MAX_MEDIA 1
+#endif
+
+#ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH
+#define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256
+#endif
+
+
+#ifndef UX_SLAVE_REQUEST_DATA_MAX_LENGTH
+#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH 2048
+#endif
+
+#ifndef UX_USE_IO_INSTRUCTIONS
+
+/* Don't use IO instructions if this define is not set. Default to memory mapped. */
+
+#define inpb(a) *((UCHAR *) (a))
+#define inpw(a) *((USHORT *) (a))
+#define inpl(a) *((ULONG *) (a))
+#define outpb(a, b) *((UCHAR *) (a)) = ((UCHAR) (b))
+#define outpw(a, b) *((USHORT *) (a)) = ((USHORT) (b))
+#define outpl(a, b) *((ULONG *) (a)) = ((ULONG) (b))
+#else
+
+
+/* Define simple prototypes for non-memory mapped hardware access. */
+
+UCHAR inpb(ULONG);
+USHORT inpw(ULONG);
+ULONG inpl(ULONG);
+
+VOID outpb(ULONG,UCHAR);
+VOID outpw(ULONG,USHORT);
+VOID outpl(ULONG,ULONG);
+
+#endif
+/* Define local delay function for board specific bsps. */
+#ifdef TI_AM335
+ #define UX_BSP_SPECIFIC_DELAY_FUNCTION
+#endif
+
+
+/* Define interrupt lockout constructs to protect the memory allocation/release which could happen
+ under ISR in the device stack. */
+
+#define UX_INT_SAVE_AREA unsigned int old_interrupt_posture;
+#define UX_DISABLE_INTS old_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE);
+#define UX_RESTORE_INTS tx_interrupt_control(old_interrupt_posture);
+
+
+/* Define the version ID of USBX. This may be utilized by the application. */
+
+#ifdef UX_SYSTEM_INIT
+CHAR _ux_version_id[] =
+ "Copyright (c) 2024 Microsoft Corporation. * USBX Cortex-M33/IAR Version 6.4.1 *";
+#else
+extern CHAR _ux_version_id[];
+#endif
+
+#endif
+
diff --git a/test/cmake/usbx/regression/CMakeLists.txt b/test/cmake/usbx/regression/CMakeLists.txt
index 372f235..8d29d43 100644
--- a/test/cmake/usbx/regression/CMakeLists.txt
+++ b/test/cmake/usbx/regression/CMakeLists.txt
@@ -512,6 +512,7 @@ set(ux_utility_test_cases
${SOURCE_DIR}/usbx_ux_utility_pci_class_scan_test.c
${SOURCE_DIR}/usbx_ux_utility_physical_address_test.c
${SOURCE_DIR}/usbx_ux_utility_string_length_check_test.c
+ ${SOURCE_DIR}/usbx_ux_utility_time_elapsed_test.c
${SOURCE_DIR}/usbx_ux_utility_unicode_to_string_test.c
)
set(ux_utility_os_test_cases
diff --git a/test/regression/usbx_ux_utility_time_elapsed_test.c b/test/regression/usbx_ux_utility_time_elapsed_test.c
new file mode 100644
index 0000000..f651867
--- /dev/null
+++ b/test/regression/usbx_ux_utility_time_elapsed_test.c
@@ -0,0 +1,366 @@
+/* This test is designed to test the ux_utility_time_elapsed macro.... */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "ux_api.h"
+#include "ux_system.h"
+#include "ux_utility.h"
+
+#include "ux_host_stack.h"
+#include "ux_device_stack.h"
+
+#include "ux_device_class_cdc_acm.h"
+#include "ux_host_class_cdc_acm.h"
+
+#include "ux_host_class_dpump.h"
+#include "ux_device_class_dpump.h"
+
+#include "ux_host_class_hid.h"
+#include "ux_device_class_hid.h"
+
+#include "ux_host_class_storage.h"
+#include "ux_device_class_storage.h"
+
+#include "ux_test_dcd_sim_slave.h"
+#include "ux_test_hcd_sim_host.h"
+#include "ux_test_utility_sim.h"
+
+
+/* Define USBX test constants. */
+
+#define UX_TEST_STACK_SIZE 4096
+#define UX_TEST_BUFFER_SIZE 2048
+#define UX_TEST_RUN 1
+#define UX_TEST_MEMORY_SIZE (64*1024)
+
+#define LSB(x) ( (x) & 0x00ff)
+#define MSB(x) (((x) & 0xff00) >> 8)
+
+/* Configuration descriptor 9 bytes */
+#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
+ /* Configuration 1 descriptor 9 bytes */\
+ 0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
+ (bNumInterfaces), (bConfigurationValue), 0x00,\
+ 0x40, 0x00,
+#define CFG_DESC_LEN 9
+
+/* DPUMP interface descriptors. */
+#define DPUMP_IFC_DESC(ifc, alt, nb_ep) \
+ /* Interface descriptor */\
+ 0x09, 0x04, (ifc), (alt), (nb_ep), 0x99, 0x99, 0x99, 0x00,
+
+#define DPUMP_IFC_EP_DESC(epaddr, eptype, epsize) \
+ /* Endpoint descriptor */\
+ 0x07, 0x05, (epaddr), (eptype), LSB(epsize), MSB(epsize), 0x01,
+
+#define DPUMP_IFC_DESC_ALL_LEN(nb_ep) (9 + (nb_ep) * 7)
+
+#define CFG_DESC_ALL_LEN (CFG_DESC_LEN + DPUMP_IFC_DESC_ALL_LEN(4))
+
+#define CFG_DESC_ALL \
+ CFG_DESC(CFG_DESC_ALL_LEN, 1, 1)\
+ DPUMP_IFC_DESC(0, 0, 4)\
+ DPUMP_IFC_EP_DESC(0x81, 2, 64)\
+ DPUMP_IFC_EP_DESC(0x02, 2, 64)\
+ DPUMP_IFC_EP_DESC(0x83, 1, 64)\
+ DPUMP_IFC_EP_DESC(0x84, 3, 64)\
+
+/* Define the counters used in the test application... */
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG error_counter;
+
+static UCHAR error_callback_ignore = UX_FALSE;
+static ULONG error_callback_counter;
+
+static UCHAR buffer[UX_TEST_BUFFER_SIZE];
+
+static TX_TIMER test_timer;
+
+/* Define USBX test global variables. */
+
+static UX_HOST_CLASS *class_driver;
+static UX_HOST_CLASS_DPUMP *dpump;
+static UX_SLAVE_CLASS_DPUMP *dpump_slave = UX_NULL;
+
+static UCHAR device_framework_full_speed[] = {
+
+ /* Device descriptor 18 bytes */
+ 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
+ 0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01,
+
+ CFG_DESC_ALL
+};
+#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
+
+static UCHAR device_framework_high_speed[] = {
+
+ /* Device descriptor */
+ 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+ 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
+ 0x03, 0x01,
+
+ /* Device qualifier descriptor */
+ 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x00,
+
+ CFG_DESC_ALL
+};
+#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
+
+/* String Device Framework :
+ Byte 0 and 1 : Word containing the language ID : 0x0904 for US
+ Byte 2 : Byte containing the index of the descriptor
+ Byte 3 : Byte containing the length of the descriptor string
+*/
+
+#define NUM_TEST_VALUES 2
+#define TEST_VALUES_LENGTH 3
+
+static UINT test_values[NUM_TEST_VALUES][TEST_VALUES_LENGTH] =
+{
+ {0xFU, 0x1U, 0xFFFFFFF2U},
+ {0xFFFFFFF0, 0x1U, 0x11U}
+};
+
+static UCHAR string_framework[] = {
+
+ /* Manufacturer string descriptor : Index 1 */
+ 0x09, 0x04, 0x01, 0x0c,
+ 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
+ 0x6f, 0x67, 0x69, 0x63,
+
+ /* Product string descriptor : Index 2 */
+ 0x09, 0x04, 0x02, 0x0c,
+ 0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
+ 0x44, 0x65, 0x6d, 0x6f,
+
+ /* Serial Number string descriptor : Index 3 */
+ 0x09, 0x04, 0x03, 0x04,
+ 0x30, 0x30, 0x30, 0x31
+};
+#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
+
+ /* Multiple languages are supported on the device, to add
+ a language besides English, the unicode language code must
+ be appended to the language_id_framework array and the length
+ adjusted accordingly. */
+static UCHAR language_id_framework[] = {
+
+/* English. */
+ 0x09, 0x04
+};
+#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
+
+/* Define prototypes for external Host Controller's (HCDs), classes and clients. */
+
+static VOID ux_test_instance_activate(VOID *dpump_instance);
+static VOID ux_test_instance_deactivate(VOID *dpump_instance);
+
+UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
+UINT ux_hcd_sim_initialize(UX_HCD *hcd);
+UINT _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
+ ULONG requested_length, ULONG *actual_length);
+UINT _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
+ ULONG requested_length, ULONG *actual_length);
+
+static TX_THREAD ux_test_thread_simulation_0;
+static TX_THREAD ux_test_thread_simulation_1;
+static void ux_test_thread_simulation_0_entry(ULONG);
+static void ux_test_thread_simulation_1_entry(ULONG);
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+/* Simulator actions. */
+
+static UX_TEST_HCD_SIM_ACTION endpoint0x83_create_del_skip[] = {
+/* function, request to match,
+ port action, port status,
+ request action, request EP, request data, request actual length, request status,
+ status, additional callback,
+ no_return */
+{ UX_HCD_CREATE_ENDPOINT, NULL,
+ UX_FALSE, 0,
+ UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0,
+ UX_SUCCESS},
+{ UX_HCD_CREATE_ENDPOINT, NULL,
+ UX_FALSE, 0,
+ UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0,
+ UX_SUCCESS},
+{ 0 }
+};
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* For further expansion of interrupt-level testing. */
+}
+
+
+static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
+{
+
+ error_callback_counter ++;
+
+ if (!error_callback_ignore)
+ {
+ {
+ /* Failed test. */
+ printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
+ // test_control_return(1);
+ }
+ }
+}
+
+static UINT break_on_dpump_ready(VOID)
+{
+
+UINT status;
+UX_HOST_CLASS *class;
+
+ /* Find the main data pump container. */
+ status = ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class);
+ if (status != UX_SUCCESS)
+ /* Do not break. */
+ return UX_SUCCESS;
+
+ /* Find the instance. */
+ status = ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump);
+ if (status != UX_SUCCESS)
+ /* Do not break. */
+ return UX_SUCCESS;
+
+ if (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
+ /* Do not break. */
+ return UX_SUCCESS;
+
+ return 1;
+}
+
+static UINT break_on_removal(VOID)
+{
+
+UINT status;
+UX_DEVICE *device;
+
+ status = ux_host_stack_device_get(0, &device);
+ if (status == UX_SUCCESS)
+ /* Do not break. */
+ return UX_SUCCESS;
+
+ return 1;
+}
+
+
+static UINT test_ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND *command)
+{
+ switch(command->ux_slave_class_command_request)
+ {
+ case UX_SLAVE_CLASS_COMMAND_INITIALIZE:
+ case UX_SLAVE_CLASS_COMMAND_QUERY:
+ case UX_SLAVE_CLASS_COMMAND_CHANGE:
+ return UX_SUCCESS;
+
+ default:
+ return UX_NO_CLASS_MATCH;
+ }
+}
+
+static UINT test_ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command)
+{
+ switch (command -> ux_host_class_command_request)
+ {
+ case UX_HOST_CLASS_COMMAND_QUERY:
+ default:
+ return _ux_host_class_dpump_entry(command);
+ }
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void usbx_ux_utility_timer_test_application_define(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *stack_pointer;
+CHAR *memory_pointer;
+CHAR *rpool_start;
+CHAR *cpool_start;
+const CHAR flags[] = {
+ UX_REGULAR_MEMORY, UX_CACHE_SAFE_MEMORY, 0xFF
+};
+const CHAR expect_error[] = {
+ UX_FALSE, UX_FALSE, UX_TRUE
+};
+
+ /* Inform user. */
+ printf("Running ux_utility_time_elapsed... Test................................... ");
+
+ /* Initialize the free memory pointer. */
+ stack_pointer = (CHAR *) first_unused_memory;
+ memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
+
+ rpool_start = memory_pointer;
+ cpool_start = memory_pointer + UX_TEST_MEMORY_SIZE;
+
+ /* Initialize USBX Memory. */
+ status = ux_system_initialize(rpool_start, UX_TEST_MEMORY_SIZE, cpool_start, UX_TEST_MEMORY_SIZE);
+
+ /* Check for error. */
+ if (status != UX_SUCCESS)
+ {
+
+ printf("ERROR #%d\n", __LINE__);
+ test_control_return(1);
+ }
+
+ /* Register the error callback. */
+ _ux_utility_error_callback_register(error_callback);
+
+ /* Create the simulation thread. */
+ status = tx_thread_create(&ux_test_thread_simulation_0, "test simulation", ux_test_thread_simulation_0_entry, 0,
+ stack_pointer, UX_TEST_STACK_SIZE,
+ 20, 20, 1, TX_AUTO_START);
+
+ /* Check for error. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #%d\n", __LINE__);
+ test_control_return(1);
+ }
+}
+
+static void ux_test_thread_simulation_0_entry(ULONG arg)
+{
+
+
+ for (UINT i = 0; i < NUM_TEST_VALUES; ++i)
+ {
+ if (ux_utility_time_elapsed(test_values[i][0], test_values[i][1]) != test_values[i][2])
+ {
+ printf("ERROR #%d: time elapsed incorrect\n", __LINE__);
+ test_control_return(1);
+ }
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+} \ No newline at end of file
diff --git a/test/regression/ux_test.c b/test/regression/ux_test.c
index aaf845a..b2eeb8e 100644
--- a/test/regression/ux_test.c
+++ b/test/regression/ux_test.c
@@ -2,10 +2,6 @@
#include "ux_test_hcd_sim_host.h"
#include "ux_test_dcd_sim_slave.h"
-#ifndef _ux_utility_time_elapsed
-#define _ux_utility_time_elapsed(t0,t1) ((t1)>=(t0) ? ((t1)-(t0)) : (0xFFFFFFFF - (t0) + (t1)))
-#endif
-
#define UX_TEST_TIMEOUT_MS 3000
static UX_TEST_ACTION ux_test_action_handler_check(UX_TEST_ACTION *action, UX_TEST_FUNCTION usbx_function, void *params, UCHAR advance);