-
Notifications
You must be signed in to change notification settings - Fork 1.4k
applications: nrf_desktop: Fix USB selective HID report subscription #25598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes USB selective HID report subscription by enabling multiple HID subscribers to share the same priority level. The key change replaces the single active subscriber pointer with a priority-based system that tracks the active subscriber priority and allows multiple subscribers at the same priority to subscribe to different HID input reports.
Key Changes:
- Replaced single
active_subscriberpointer withactive_subscriber_prioritytracking to support multiple subscribers at the same priority level - Introduced
get_active_report_state()function to find the active subscriber for a specific report ID - Refactored subscriber activation/deactivation logic to handle priority-based groups of subscribers
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
CI InformationTo view the history of this post, click the 'edited' button above Inputs:Sources:sdk-nrf: PR head: f0a24424f48447d28739eebfb3eb027b546eebf2 more detailssdk-nrf:
Github labels
List of changed files detected by CI (1)Outputs:ToolchainVersion: df3cc9d822 Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped;
|
f930b88 to
3371d07
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| __ASSERT_NO_MSG(!rs->provider || !rs->provider->api || | ||
| (rs->provider->linked_rs == rs)); |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The assertion logic is overly complex with multiple OR conditions. Consider splitting into separate assertions with descriptive messages explaining what each condition validates, improving debuggability when assertions fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already use similar approach (combining multiple OR conditions under an assertion) in other places. As an alternative, we could make it:
if (rs->provider) {
__ASSERT_NO_MSG(!rs->provider->api || (rs->provider->linked_rs == rs));
}
Still, I prefer the existing approach (it's also more consistent with existing codebase).
@alstrzebonski or @kapi-no, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can leave it as is.
| link_providers(state.active_subscriber); | ||
| if (new_priority != state.active_subscriber_priority) { | ||
| update_active_subscriber_priority(new_priority); | ||
| } else { |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic in the else branch is unclear. When new_priority equals active_subscriber_priority and we're disconnecting a subscriber with that priority, only unlinking this specific subscriber's providers may leave other subscribers at the same priority still linked. Consider adding a comment explaining why this partial unlink is correct.
| } else { | |
| } else { | |
| /* | |
| * Only unlink providers for the disconnecting subscriber. | |
| * Other subscribers with the same priority may remain linked. | |
| * This is intentional: each subscriber manages its own provider links, | |
| * and unlinking only the disconnecting subscriber's providers avoids | |
| * disrupting other active subscribers at the same priority. | |
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that introducing the extra comment here might not be necessary (code behavior is quite intuitive).
| } | ||
| if (rs) { | ||
| link_provider_to_rs(provider, rs); | ||
| __ASSERT_NO_MSG(provider->linked_rs == rs); |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The assertion on line 677 checks the result of the function call on line 676, but this validation is redundant since link_provider_to_rs should guarantee this relationship. If this is a critical invariant, consider moving it inside link_provider_to_rs or adding a comment explaining why post-condition verification is needed here.
| __ASSERT_NO_MSG(provider->linked_rs == rs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assertion ensures that link_provider_to_rs does not early return on neither if (!provider->api) { nor if (provider->linked_rs == rs) {. I will add a small comment here.
|
You can find the documentation preview for this PR here. |
3371d07 to
872cb00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Separate `get_input_report_idx` function to avoid code duplication. Jira: NCSDK-35718 Signed-off-by: Marek Pieta <[email protected]>
Change removes the `report_id` field from `struct report_state` (the field is no longer used). Jira: NCSDK-35718 Signed-off-by: Marek Pieta <[email protected]>
Change updates HID state module to allow sharing the same HID subscriber priority among multiple subscribers. The HID subscribers with the same priority cannot simultaneously subscribe for the same HID input report. Change is required to fix USB selective HID report subscription (USB HID instances share the same HID subscriber priority). Jira: NCSDK-35718 Signed-off-by: Marek Pieta <[email protected]>
872cb00 to
ef529f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }; | ||
|
|
||
| #define SUBSCRIBER_COUNT CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT | ||
| #define SUBSCRIBER_COUNT CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment explaining that SUBSCRIBER_PRIORITY_UNUSED (0) is a reserved value and valid subscriber priorities must be non-zero. This would clarify the assertion at line 495.
| #define SUBSCRIBER_COUNT CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT | |
| #define SUBSCRIBER_COUNT CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT | |
| /* | |
| * SUBSCRIBER_PRIORITY_UNUSED (0) is a reserved value. | |
| * Valid subscriber priorities must be non-zero. | |
| * This clarifies the assertion that checks for non-zero priorities. | |
| */ |
| __ASSERT_NO_MSG(!rs->provider || !rs->provider->api || | ||
| (rs->provider->linked_rs == rs)); |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion condition is complex and difficult to parse. Consider adding a comment explaining what invariant is being checked, or split into separate assertions with descriptive messages.
| __ASSERT_NO_MSG(!rs->provider || !rs->provider->api || | |
| (rs->provider->linked_rs == rs)); | |
| /* If provider is set, its API must be set. */ | |
| __ASSERT((!rs->provider) || (rs->provider->api), "Provider is set but API is NULL"); | |
| /* If provider is set and API is set, linked_rs must point to this report_state. */ | |
| __ASSERT((!rs->provider) || (!rs->provider->api) || (rs->provider->linked_rs == rs), | |
| "Provider's linked_rs does not point to this report_state"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| struct subscriber *prev_sub = state.active_subscriber; | ||
|
|
||
| /* The CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT must be large enough to handle all of the | ||
| * simultaneously connected subscribers. |
Copilot
AI
Nov 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should mention the consequence of an insufficient count (assertion failure at line 504) to help developers understand the severity and debugging implications.
| * simultaneously connected subscribers. | |
| * simultaneously connected subscribers. | |
| * If this is insufficient, an assertion failure will occur here (line 504), | |
| * halting execution to aid debugging. |
Change introduces an additional assertion in HID state module to verify if `CONFIG_DESKTOP_HID_STATE_SUBSCRIBER_COUNT` is big enough to handle all of the simultaneously connected HID subscribers. This simplifies debugging improper configuration. Jira: NCSDK-35718 Signed-off-by: Marek Pieta <[email protected]>
90ba6f9 to
f0a2442
Compare
Change updates HID state module to allow sharing the same HID subscriber priority among multiple subscribers. The HID subscribers with the same priority cannot simultaneously subscribe for the same HID input report.
Change is required to fix USB selective HID report subscription (USB HID instances share the same HID subscriber priority).
PR also introduces small HID state improvements.
Jira: NCSDK-35718