Skip to content

fix: claim a silent verified pad instead of failing the Direct probe - #158

Merged
emir-hasanbegovic merged 1 commit into
mainfrom
fix/usb-probe-silent-verified
Aug 15, 2026
Merged

fix: claim a silent verified pad instead of failing the Direct probe#158
emir-hasanbegovic merged 1 commit into
mainfrom
fix/usb-probe-silent-verified

Conversation

@emir-hasanbegovic

Copy link
Copy Markdown
Contributor

Description

The USB Direct attach probe treated ~320ms of endpoint silence as proof the chosen parser was wrong and released the device back to the framework. That assumption held for every current verified table entry because wired XInput-class pads stream reports at rest. The Amazon Luna Controller (wired USB, 1949:041A, #153) is event-driven: it sends nothing until a button, stick, or trigger changes, so switching an idle Luna to Direct failed unless the user happened to be moving a stick during the probe window, and putting the model on the verified fast lane would make the plug-in auto-claim fail the same way.

probeEndpoint (was probeDecodable) now distinguishes three outcomes, and probePermitsClaim in usb_parsers decides per trust level:

  • A decoded report, or a recognized wireless link event, claims at any trust level.
  • Traffic that never decodes releases at any trust level: bytes in the wrong shape are positive evidence of a wrong parser.
  • Pure silence claims only a model in the hardware-verified kKnown table. Imported and descriptor-sniffed models still require a decoded report, because for them the probe is the only verification.

This mirrors what the reference stacks do with this device class: the Linux xpad driver (5.13+) and SDL both classify the Luna by ID alone and are event-driven end to end, with no idle-traffic requirement. Neither has a wake or init packet we could send instead; none exists for this protocol family.

The steady-state poll loop is already silence-tolerant (interrupt URBs stay pending until data arrives; only ENODEV exits), so a claimed idle pad is healthy. Behavior for every currently verified model is unchanged, since they all stream at rest.

Prepares for #153, which puts the Luna on the verified fast lane.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Documentation update

How Has This Been Tested?

  • Unit tests
  • Instrumented tests
  • Manual testing on device/emulator

Native host suite 321/321 passing, including three new ProbeRule cases covering the outcome/trust truth table. :app:externalNativeBuildDebug compiles clean on both ABIs. clang-format 22.1.4 clean on all touched files.

Hardware verification on an actual Luna is requested in #153 from @MichaelWilsonSNC, who has the device: idle plug-in auto-claim, idle Standard-to-Direct toggle, and toggle while active.

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • Any non-obvious code explains why, not what (no new comments; rationale is in this PR and the commit message)
  • I have made corresponding changes to documentation (CHANGELOG.md)
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

The attach probe treated ~320ms of endpoint silence as proof the chosen
parser was wrong and released the device to the framework. That held
because every verified table entry streams reports at rest. Event-driven
pads like the Amazon Luna Controller (wired USB, 1949:041A) send nothing
until a control changes, so a Direct claim on an idle pad always failed,
and with the model on the verified fast lane (#153) the plug-in
auto-claim would fail the same way.

The probe now reports three outcomes instead of a bool. A decoded
report, or a recognized wireless link event, claims at any trust level.
Traffic that never decodes always releases, since bytes in the wrong
shape are positive evidence of a wrong parser. Pure silence claims only
a model in the hardware-verified kKnown table; imported and
descriptor-sniffed models still require a decoded report because the
probe is their only verification.

This mirrors the reference stacks for this device class: the Linux xpad
driver (5.13+) and SDL both classify the Luna by ID alone, are
event-driven end to end, and have no idle-traffic requirement or wake
packet. The steady-state poll loop is already silence-tolerant
(interrupt URBs stay pending until data arrives), so a claimed idle pad
is healthy. Behavior for every currently verified model is unchanged.
@emir-hasanbegovic
emir-hasanbegovic merged commit 1ec168c into main Aug 15, 2026
10 checks passed
@emir-hasanbegovic
emir-hasanbegovic deleted the fix/usb-probe-silent-verified branch August 15, 2026 19:23
MichaelWilsonSNC added a commit to MichaelWilsonSNC/dish-android that referenced this pull request Aug 16, 2026
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