`XBOX_RDESC` is the only report descriptor in `pf-gamepad` that was hand-written rather than
captured off hardware, and its own provenance warning has now come true three times. The fix for
that class of bug is not another careful reading — it is a tool that goes and asks the device.
`tools/hid-descriptor-dump` does that: it dumps a real HID device's report descriptor, decodes it
into an annotated item listing plus a bit-offset LAYOUT TABLE, and can decode a blob we already
ship through the same decoder (`--rust-source <file> --symbol <NAME>`) so the two are diffable
line for line. `--read N` pulls live wire bytes, which is the only ground truth a reconstructed
descriptor cannot give you.
Deliberately NOT a workspace member — it pulls `hidapi`, a C library wanting libudev on Linux,
which has no business in `cargo build --workspace` or on a CI leg with no pad attached. It is a
bring-your-own-hardware tool and it is excluded in the root manifest, so CI never sees it.
The captured Elite disagrees with our blob in four ways, and the dangerous one is field ORDER:
the real pad reports sticks, ONE combined 16-bit Z trigger, then BUTTONS, then the hat, in an
UNNUMBERED 15-byte report; ours declares Report ID 1, two Simulation-page trigger axes, then the
hat, then 15 buttons. Since we claim a genuine Microsoft VID/PID and SDL/Steam/Windows all apply
stock mappings keyed on it, that ordering difference is exactly how every control silently lands
on the wrong action. The driver comment now records the diff and the two blockers that stop the
capture from simply being pasted in.
VERIFIED
* `cargo fmt --check` clean, `cargo clippy --all-targets -- -D warnings` clean (macOS).
* The tool builds and runs on macOS and on .173 (Windows 11 26200, cargo 1.96, MSVC, no WDK).
* TOOL VALIDATED AGAINST A KNOWN-GOOD CONTROL: pointed at the live DualSense on .173, it
reproduces the real `DUALSENSE_RDESC` layout exactly (input 0x01, 64 B, X,Y,Z,Rz,Rx,Ry at
bytes 1..6, hat 8.0, 15 buttons 8.4, output 0x02, the full feature ladder), and `--read`
returned live len=64 reports with sticks centred at 80 80 80 80 and the counter incrementing.
* `cargo metadata` on the root workspace still resolves and does NOT list this crate.
* The Elite capture is reproducible: `--vid 045E --pid 0B22`.
NOT VERIFIED
* That the capture equals the pad's NATIVE report map. Windows exposes no API for a device's
literal descriptor bytes, so hidapi reconstructs from `HidD_GetPreparsedData` — faithful in
structure, item order and bit offsets, not byte-exact (measured: the DualSense's real 273-byte
descriptor reconstructs to 467). `xinputhid` also filters that pad, and the captured shape is
the legacy DirectInput view. A byte-exact answer needs Linux hidraw.
* Why the Elite returned ZERO input reports across two runs (72 s and 90 s) while the DualSense
streamed fine on the same code path — untouched pad, or exclusive claim by the XInput
translator. Unresolved.
* Nothing here was built on Windows as a driver: `XBOX_RDESC` itself is UNCHANGED, so no
behaviour changes. The only edit to the driver is its provenance comment.
28 lines
1.2 KiB
TOML
28 lines
1.2 KiB
TOML
# Capture a real HID device's report descriptor and decode it into something diffable against the
|
|
# blobs `packaging/windows/drivers/pf-gamepad/src/lib.rs` serves. Every descriptor we ship must be
|
|
# CAPTURED, not constructed (see that file's provenance warning, and the three bugs a constructed
|
|
# one already cost us) — this is the tool that captures them.
|
|
#
|
|
# Deliberately NOT a workspace member (see the root `Cargo.toml` `exclude` list): it pulls `hidapi`,
|
|
# a C library needing libudev on Linux, which we do not want in `cargo build --workspace` or on any
|
|
# CI leg. It is a bring-your-own-hardware measurement tool — build it standalone on the box that has
|
|
# the pad:
|
|
#
|
|
# cargo run --manifest-path tools/hid-descriptor-dump/Cargo.toml -- --list
|
|
#
|
|
# Stands alone. Without this, cargo walks up, finds the repo's `[workspace]` and refuses to build a
|
|
# package that root does not list as a member.
|
|
[workspace]
|
|
|
|
[package]
|
|
name = "hid-descriptor-dump"
|
|
description = "Capture and decode a real HID device's report descriptor, for diffing against the ones we synthesize"
|
|
version = "0.26.0"
|
|
edition = "2024"
|
|
rust-version = "1.96.0"
|
|
license = "MIT OR Apache-2.0"
|
|
publish = false
|
|
|
|
[dependencies]
|
|
hidapi = "2.6"
|