Skip to content

Port Hurra-v2 review fixes to v3 (desc_capture, act_click, ferrum km.mask) - #5

Merged
ramseymcgrath merged 1 commit into
masterfrom
feat/port-v2-review-fixes
Jul 8, 2026
Merged

Port Hurra-v2 review fixes to v3 (desc_capture, act_click, ferrum km.mask)#5
ramseymcgrath merged 1 commit into
masterfrom
feat/port-v2-review-fixes

Conversation

@ramseymcgrath

Copy link
Copy Markdown
Contributor

Summary

Backports three fixes from Hurra-v2's deferred-review branch that landed after the v3 fork and never made it across. All three touch shared-lineage code; each is host-unit-tested and both firmware profiles build clean.

Fixes

1. desc_capture — descriptor truncation consistency
When a captured descriptor is truncated to fit its buffer, patch the length fields so the replayed descriptor stays internally consistent: config/BOS wTotalLength, the HID wDescriptorLength inside the config descriptor, and string bLength. On a failed HID report-descriptor fetch, set has_hid_desc=false instead of replaying an invalid descriptor. This matters directly for v3's descriptor-passthrough MITM role.

  • Size caps left unchanged (512/128/256). The cap bump from v2 was not ported: captured_descriptors_t is statically allocated in several places and is serialized cross-core over the SPI frame transport (something v2 lacks). RAM and transport headroom were verified to exist, but the patching makes truncation safe at any cap, and v3's real targets sit far under the current caps — so bumping four large statics buys ~nothing. Documented for a future large-composite-device need.

2. act_click — stuck-button fix + unified tick scheduler
Guard invalid button/count==0; when a new click targets a different button while a prior sequence still holds one down, release the old button first. Single- and multi-click now run through act_click_tick(), pumped from kmbox_cmd_poll(). Adds act_kb_mask_get().

  • Dual-core safety: g_click_sched/g_buttons are touched only on V3F (command parse + poll run in the same non-preempted loop, on that image's own copy), so no lock/barrier is needed — same discipline as the existing g_motion path.

3. ferrumkm.mask() read getter
The km.mask(<key>) read path was a stub that always emitted 0. It now reports the real masked state via act_kb_mask_get().

  • lock_* / g_lock_mask left intact (v2 deleted them). They are live in v3's default hurra.c protocol (lock_listener + 7 registered TinyFrame listeners), so v3 intentionally diverges from v2 here.

Tests

Adds test/desc_capture_test.c (ASan), test/actions_test.c, and test/ferrum_mask_test.c to make test, each written TDD-first (red → green).

  • make test → all green, 0 failures
  • make all (Hurra binary) → builds; V3F + V5F + merged image
  • make PROTOCOL=ferrum all → builds clean (exercises the ferrum.c change on-target)

Not included (follow-ups)

  • TF_USE_SOF_BYTE: investigated and deliberately not ported — v3 firmware and hurra-app already agree (both SOF-off, per the TinyFrame default); flipping only the firmware would break interop. Tracked separately as a docs-vs-implementation reconciliation.
  • two_board.c BOARD_ROLE_HOST (non-default build) also pumps the input loop and would want an act_click_tick() call for symmetry.

Copilot AI review requested due to automatic review settings July 8, 2026 04:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Backports three Hurra-v2 fixes into Hurra v3’s shared-lineage code to improve descriptor replay correctness, prevent stuck mouse buttons in click scheduling, and make Ferrum’s km.mask() read path report real state—along with host-native unit tests to lock the behavior in.

Changes:

  • Make captured USB descriptors internally consistent when truncated (patch wTotalLength, HID wDescriptorLength, string bLength; clear invalid HID report descriptors on fetch failure).
  • Rework act_click to cancel/unstick overlapping click sequences and drive all click releases via a unified act_click_tick() pump from kmbox_cmd_poll().
  • Implement Ferrum km.mask(<key>) read getter via act_kb_mask_get(), and add targeted host tests for the new wiring.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/ferrum_mask_test.c Adds host-native coverage for Ferrum km.mask() read/write round-trip.
test/desc_capture_test.c Adds host-native descriptor truncation/consistency tests (includes isolated patch helper tests).
test/actions_test.c Adds host-native tests for click scheduler stuck-button fix and act_kb_mask_get().
src/kmbox_cmd.c Pumps the new click tick scheduler each poll loop iteration (V3F).
src/ferrum.c Implements km.mask(key) read variant using act_kb_mask_get().
src/desc_capture.c Adds truncation-consistency patching for config/BOS/HID/string descriptors and clears invalid HID report descriptors.
src/actions.h Exposes act_click_tick() and act_kb_mask_get().
src/actions.c Implements unified click tick scheduler and adds act_kb_mask_get().
Makefile Wires new tests into make test (including ASan for desc_capture_test).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/actions.c Outdated
Comment thread src/desc_capture.c Outdated
Comment thread src/desc_capture.c Outdated

Copilot AI left a comment

Copy link
Copy Markdown

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 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread src/desc_capture.c

Copilot AI left a comment

Copy link
Copy Markdown

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 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread src/actions.c
…mask)

Backport three fixes from Hurra-v2's deferred-review branch that predated
the v3 fork. Each is host-unit-tested; `make test`, `make all`, and
`make PROTOCOL=ferrum all` all build/pass clean.

desc_capture: patch descriptor length fields (config/BOS wTotalLength, HID
wDescriptorLength, string bLength) when a captured descriptor is truncated
to fit its buffer or the device short-transfers, and set has_hid_desc=false
on a failed HID report fetch
instead of replaying an invalid descriptor. Reject malformed string
descriptors (short or wrong-type) rather than storing them, and bound the
config walk in patch_hid_report_desc_len() so a truncated trailing byte
cannot be read past. Size caps left unchanged: RAM and cross-core
serialize-transport headroom were verified, and the patching makes
truncation internally consistent at any cap.

act_click: cancel an in-flight click sequence and release a still-held
button when a new click targets a different button; unify single- and
multi-click through act_click_tick(), with a wrap-safe deadline check. Both
command pumps (kmbox_cmd_poll and the two_board.c BOARD_ROLE_HOST stage)
step motion+click via a shared act_tick() helper, so neither can drift and
strand a click by pumping only one. Adds act_kb_mask_get().
g_click_sched/g_buttons confirmed single-core (V3F), so no lock is needed.

ferrum: wire the km.mask(<key>) read path to act_kb_mask_get() instead of
the always-0 stub. lock_*/g_lock_mask left intact -- they are live in v3's
default hurra.c protocol, unlike v2 which removed them.

Tests: add test/desc_capture_test.c, test/actions_test.c, and
test/ferrum_mask_test.c to the `make test` target, including wrap-around
and malformed-descriptor regression cases.

Copilot AI left a comment

Copy link
Copy Markdown

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 10 out of 10 changed files in this pull request and generated no new comments.

@ramseymcgrath
ramseymcgrath merged commit 42b8719 into master Jul 8, 2026
2 checks passed
Sign up for free to 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.

2 participants