The plain-DualSense transport + report codec under the Edge USB identity (054C:0DF2, verbatim 389-byte real-device descriptor cross-checked against the raw usbmon capture + hhd's production virtual Edge), so the wire back grips (BTN_PADDLE1..4: Deck L4/L5/R4/R5, Elite P1-P4) land on the Edge's NATIVE buttons[2] bits instead of the fold/drop policy: PADDLE1/2 -> the right/left back buttons, PADDLE3/4 -> the right/left Fn buttons (kernel BTN_TRIGGER_HAPPY1..4 on >= 7.2; SDL/Steam read hidraw on any kernel). - proto: Edge descriptor + btn2 bits + edge_paddle_bits(), pinned against hid-playstation DS_EDGE_BUTTONS_* and SDL_hidapi_ps5 (tests). - Linux: DsUhidIdentity parameterizes the UHID create; DsEdgeLinuxProto / DualSenseEdgeManager. Headless-validated on .21 (7.1): driver=playstation binds 0DF2, all 4 input devices created, probe lightbar/player-LED feedback round-trips; dualsense-test grew --edge (cycles all 4 paddles). - Windows: UMDF driver serves device_type=2 (Edge descriptor/attrs/strings, DS feature blobs); WinDsIdentity parameterizes the SwDevice profile + devtype stamp; DsEdgeWinProto / DualSenseEdgeWindowsManager; INF gains pf_dualsenseedge. Driver change => resign + reinstall before on-glass. - Router: DualSenseEdge arms in route_handle/apply_rich/pump/heartbeat; pick_gamepad folds Edge -> itself on linux||windows; degrade_if_no_uhid covers it. - Client (SDL): 054C:0DF2 declares DualSenseEdge (no distinct SDL type); Edge physical pads take the raw DS5 effects path; console-UI glyphs = Shapes. Apple/Android pickers follow separately. Verified: .21 clippy -D warnings + 292/0 host tests + on-box UHID bind smoke; .133 clippy pending in this push. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pf-driver-proto
The shared host ↔ driver binary contract for punktfunk's Windows pf-vdisplay virtual display — the control IOCTLs and the IDD-push frame transport, defined exactly once.
It's a path dependency of both the host workspace (crates/punktfunk-host)
and the out-of-workspace driver workspace (packaging/windows/drivers/),
so it must resolve identically from either build graph. That's why it's deliberately self-contained:
no_std (+ alloc), platform-neutral (GUID/LUID are plain integers each side converts to its own OS
type), and free of *.workspace = true inheritance.
Defining every wire struct here — with const size/offset asserts and bytemuck round-trips — turns
host↔driver ABI drift into a compile error instead of a silent frame or IOCTL corruption.
See the crate root (src/) for the wire types; the Windows virtual-display design is in
the internal planning repo (punktfunk-planning: windows-virtual-display-rust-port.md).