Skip to content

HID fixture: consumer-control (media key) reports - #1333

Merged
malpern merged 1 commit into
codex/pico-hid-fixturefrom
lab/fixture-consumer-report
Oct 22, 2026
Merged

malpern merged 1 commit into
codex/pico-hid-fixturefrom
lab/fixture-consumer-report

Conversation

@malpern

@malpern malpern commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Stacked on #1238 (codex/pico-hid-fixture). Lets the ESP32 fixture press media keys, which KeyPath's driverless session now reads as inputs (#1332).

What

  • Both targets describe a consumer-control report (ID 2) alongside the boot-keyboard report.
  • Script event lines take an optional ninth field, the consumer usage held; every eight-field script parses unchanged. Each event changes the keyboard state or the consumer state, never both, so it is exactly one USB report. The cycle must end fully released, and abort/unmount releases a held media key before the keyboard.
  • Trace and HTTP trace JSON carry consumer / consumerReport.
  • Client: compile-media --keys mute,volume-up,....
  • README documents the format.

Tests

  • Host core: 4 new (press/release + trace; eight-field scripts never send consumer reports; unsafe consumer scripts refused; abort releases the media key first). Client: 2 new.
  • pico-hid-fixture-tool test passes in full, including the ESP32-S3 QEMU smoke.
  • Flashed over authenticated Wi-Fi OTA (build f97c6911cafc, healthy).

Physical trial (mini, 2026-10-20)

Fixture pressed Mute, Volume Up, Mute into a standalone KeyPath session worker running (defsrc mute)(deflayer base f20):

  • Mute → worker input 0→2, output 0→2 (F20 down/up), system not muted (consumed).
  • Volume Up (unmapped) → no worker input, volume 50→56 (passed through).
  • Control without the worker: the same Mute press mutes the Mac.

Toolchain note

The mini had lost its ESP-IDF checkout and ninja. ESP-IDF v5.5.5 now lives on the external Foot Locker volume (internal disk is close to the CI runners' 40 GiB floor), linked from the default ~/.cache/keypath-esp32/esp-idf, with qemu-xtensa and its Homebrew libraries installed.

🤖 Generated with Claude Code

The fixture could only send a boot-keyboard report, so it could not press
Mute, Volume or Play/Pause — the keys KeyPath's driverless session now reads
as inputs. Both targets now describe a consumer-control report (ID 2)
alongside the keyboard report. A script event line takes an optional ninth
field, the consumer usage held; eight-field scripts are unchanged. Each event
changes the keyboard state or the consumer state, never both, so it is
exactly one USB report; the cycle must end with everything released, and an
abort or unmount releases a held media key before the keyboard. The trace
and the HTTP trace JSON carry the consumer usage. The client gains
`compile-media`.

Tests: four host core tests (press/release and trace, eight-field scripts
never send consumer reports, unsafe consumer scripts refused, abort releases
the media key first) and two client tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T20:10:17.996284Z 9a3e648 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a3e6481ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +202 to 207
fields = sscanf(line, "%" SCNu32 " %u %u %u %u %u %u %u %u %c", &event.at_us,
&values[0], &values[1], &values[2], &values[3], &values[4], &values[5], &values[6],
&consumer, &extra);
if (fields != 8 && fields != 9) {
set_error(error, error_capacity, "event must contain time, modifiers, six key usages, and an optional consumer usage");
return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject trailing garbage on legacy event lines

When an eight-field event is followed by nonnumeric text, such as 0 0 4 0 0 0 0 0 garbage, the optional consumer conversion fails after eight successful assignments, so fields == 8 accepts the line and silently ignores the suffix. Because the CRC covers that malformed payload, it does not protect against this case, allowing a mistyped deterministic fixture script to run with different contents than intended. Treat the consumer field as absent only when the eighth value is followed by end-of-line; otherwise reject the line.

Useful? React with 👍 / 👎.

@malpern
malpern merged commit 44c4195 into codex/pico-hid-fixture Oct 22, 2026
3 checks passed
@malpern
malpern deleted the lab/fixture-consumer-report branch October 22, 2026 03:21
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.

1 participant