Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Merging changes for the v.6.5.1.202602 release - #268

Merged
fdesbiens merged 14 commits into
masterfrom
dev
Jun 8, 2026
Merged

Merging changes for the v.6.5.1.202602 release#268
fdesbiens merged 14 commits into
masterfrom
dev

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

No description provided.

ayedm1and others added 14 commits March 4, 2026 17:37
…t classes
Add preprocessor guards to allow customization of default line coding parameters.
Summary of Changes:
- Wrapped default line coding constants (RATE, STOP_BIT, PARITY, DATA_BIT)
with #ifndef guards in CDC ACM, GSER, and Prolific host class headers
- This allows users to define custom default values before including these headers in (ux_user.h)
- Updated Prolific activation code to use DEFAULT constants instead of hardcoded values
for consistency and better maintainability
Files Modified:
- common/usbx_host_classes/inc/ux_host_class_cdc_acm.h
- common/usbx_host_classes/inc/ux_host_class_gser.h
- common/usbx_host_classes/inc/ux_host_class_prolific.h
- common/usbx_host_classes/src/ux_host_class_prolific_activate.c
Added missing uninitialize macro in simulator host header (HOST SIM)
Added default value protection for line coding parameters in serial Host classes
This commit cleans up header declarations by removing API and test prototypes that have no corresponding implementation in the repository.
Impact:
- No runtime behavior change.
- Compile/link surface is cleaner and more accurate for users and tests.
* No longer using request_value to get request type.
* Removal of shift.
* Fix GET/SET_DESCRIPTOR routing for class-defined descriptor types
When a host sends GET_DESCRIPTOR or SET_DESCRIPTOR with bmRequestType
set to STANDARD but requests a class-defined descriptor type (e.g. HID
Report 0x22 or Physical 0x23), the request must be routed to the class
layer rather than handled as a standard USB request.
Per USB HID 1.11 section 7.1.1, HID stacks legitimately issue
GET_DESCRIPTOR with bmRequestType=STANDARD | INTERFACE | IN for class
descriptors. The previous fix (checking request_type != STANDARD) broke
this path: (0x81 & 0x60) == 0x00 was seen as standard and the request
would be stalled.
The new condition explicitly checks:
1. request is GET_DESCRIPTOR or SET_DESCRIPTOR
2. bmRequestType type field is STANDARD
3. bDescriptorType (high byte of wValue) is in the USB-IF class-reserved
range 0x21..0x2F
Requests with bmRequestType already set to CLASS or VENDOR, and standard
descriptors (bDescriptorType < 0x21, e.g. BOS 0x0F) or vendor descriptors
(>= 0x40), are left unchanged and follow their normal dispatch path.
Also fix (UINT) to (ULONG) cast, matching the declared type of request_type.
Suggested-by: ABOUSTM <https://github.com/ABOUSTM>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…col get/set API (#244)
This pull request adds host-side HID API functions to get and set the HID protocol (boot vs. report mode), and introduces an optional device-sidecallback invoked when the protocol changes.
New features
- Added host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error-checking wrappers (_uxe_ variants).
- Added optional device-side callback ux_device_class_hid_set_protocol_callback, invoked when the host changes the active protocol.
- Added a comprehensive test to verify the new protocol callback functionality.
Bug fixes (host-side protocol get/set)
1. DMA buffer safety (protocol_get): The received byte is now written into a cache-safe allocated buffer instead of the caller's USHORT* directly. Stack memory is not DMA-safe on cache-incoherent embedded targets, and writing 1 byte into a USHORT* yields incorrect results on big-endianplatforms. Follows the same pattern as ux_host_class_hid_idle_get.
2. Missing device protection semaphore (both functions): In RTOS mode, ux_device_protection_semaphore is now acquired before submitting the transfer, in addition to the HID instance semaphore. All other HID control transfer functions (idle_get, idle_set) take both semaphores; omitting it allowed concurrent callers to corrupt the shared transfer_request fields.
3. Missing standalone locking (both functions): Added proper UX_HOST_STANDALONE support using UX_DISABLE/UX_RESTORE to atomically check and setUX_HOST_CLASS_HID_FLAG_LOCK and UX_DEVICE_FLAG_LOCK, and set UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET on the transfer request before initiating. Follows the idle_get inline standalone pattern.
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two issues discovered while reviewing and fixing thread-safety issues in
the new ux_host_class_hid_protocol_get/set functions (PR #244).
1. idle_get.c: wrong operator acquires no lock in standalone mode
Line 104 used '&= ~UX_HOST_CLASS_HID_FLAG_LOCK' (the release/clear
operation) instead of '|= UX_HOST_CLASS_HID_FLAG_LOCK' (acquire/set).
The preceding check correctly returns UX_BUSY when the flag is set,
but the follow-on line then immediately clears it instead of setting it.
The net effect is that the HID instance is never actually locked in
UX_HOST_STANDALONE mode, making the mutual-exclusion check a no-op.
2. idle_set.c: standalone path used a blocking spin-loop
The standalone branch called _ux_host_class_hid_idle_set_run() in a
do/while loop, blocking the caller until the transfer completed. This
is inconsistent with every other inline HID control-transfer function
(idle_get, report_get, report_set, protocol_get, protocol_set) which
all use the direct UX_DISABLE/UX_RESTORE atomic flag pattern and
return UX_BUSY if the instance or device endpoint is already locked.
Replaced with the same inline standalone locking pattern used by the
other functions: atomic HID FLAG_LOCK acquire, atomic DEVICE_FLAG_LOCK
acquire with AUTO_DEVICE_UNLOCK + UX_TRANSFER_STATE_RESET, and an
AUTO_WAIT check at completion consistent with idle_get behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(hid): Store client instance per-device instead of per-class
* Address review feedback on per-instance HID client copy
Three issues fixed, discovered during maintainer review:
1. Memory leak in standalone activation error path (entry.c):
_ux_host_class_hid_client_activate_wait() set hid_client to NULL
without freeing the per-instance copy allocated in client_search.
The HID_ENUM_ERROR handler destroys the hid struct without freeing
hid_client, so the copy was leaked on every standalone activation
failure. Fixed by freeing hid_client before clearing it.
2. Variable declared inside if-block (client_search.c):
hid_client_instance was declared inside the if (status == UX_SUCCESS)
block, which is a C99 feature. USBX targets C89/C90 embedded
toolchains. Moved to the top of the function with other locals.
3. Trailing whitespace throughout both changed files:
The PR introduced trailing spaces on most comment-block lines.
Reverted all affected lines to their original whitespace.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…control client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Updated version number constants
* Updated port version strings
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Applied the standard MIT license header to all project-owned C, header,
assembly, shell, and Python files that were missing a copyright notice.
Third-party, toolchain startup, and auto-generated files were excluded.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@fdesbiens
fdesbiens merged commit 359977d into masterJun 8, 2026
2 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@fdesbiens@ayedm1@SeanHowsonAdvCo@kajteklau