Added support for Corsair Virtuoso XT#527
Conversation
Protocol reverse-engineered via hidraw probing on Linux. Battery request: 0x02 0x00 on interface 3 (Usage-Page 0xff42) Response format: [0] = 0x01 (report ID) [1] = status flags (0xf0 = available, 0x00 = offline) [2] = battery percentage (0-100) Charging state is not reported over HID by this headset. Volume events are broadcast unsolicited (0x0E 0x01/0x02/0x00) but are handled by the OS input layer. Tested on: - CORSAIR VIRTUOSO XT Wireless Gaming Receiver (0x0a64) - CORSAIR VIRTUOSO XT USB Gaming Headset (0x0a62) Capabilities: CAP_BATTERY_STATUS
Code reviewBug: Battery level not validated against 0-100File: `lib/devices/corsair_virtuoso_xt.hpp`, lines 98-109 `response[2]` is a `uint8_t` (range 0-255), but `BatteryResult::level_percent` is documented as 0-100 in result_types.hpp. A malformed response could yield 255, which also feeds `time_to_empty_min` with a nonsensical result. Multiple peer devices enforce this bound — `steelseries_arctis_nova_7.hpp` clamps with `if (level > 100) level = 100;`, and `logitech_gpro_x2_lightspeed.hpp` returns `protocolError` if out of range. Suggested fix after line 98: ```cpp CLAUDE.md: Class docblock embeds wire-format table (WHAT not WHY)File: `lib/devices/corsair_virtuoso_xt.hpp`, lines 13-31 — HeadsetControl/lib/devices/corsair_virtuoso_xt.hpp Lines 12 to 32 in 3291423 The `/** @brief */` block embeds a full byte-offset/hex-value protocol table and lists product IDs already in `SUPPORTED_PRODUCT_IDS`. CLAUDE.md says: "Default to writing no comments. Only add one when the WHY is non-obvious." Compared with `corsair_void_v2w.hpp`, whose docblock only documents non-obvious behavioral quirks, the wire-format table belongs in docs/ or the PR description. Keep only the reverse-engineering provenance note. CLAUDE.md: Machine-specific device path in committed sourceFile: `lib/devices/corsair_virtuoso_xt.hpp`, line 70 — HeadsetControl/lib/devices/corsair_virtuoso_xt.hpp Lines 69 to 71 in 3291423 The comment `// Discovered via hidraw probing on /dev/hidraw11 (interface 3, 0xff42)` embeds a machine-specific device node from the author's session. CLAUDE.md says: "Don't reference the current task, fix, or callers... since those belong in the PR description and rot as the codebase evolves." The interface (3) and usage-page (0xff42) are already in `getCapabilityDetail`; remove this line. |
|
Ignore the review about the comments. However the first bug might be relevant. |
|
I'll make the required changes. I will also try and adding more features for this headest after resolving this PR, Thanks. |
Adds support for the Corsair Virtuoso XT — both the wireless receiver (0x0a64) and wired USB (0x0a62).
I reverse-engineered the protocol via hidraw probing on Linux. The Virtuoso XT doesn't use the same protocol as CorsairVoidRich or CorsairVoidV2W — it communicates on interface 3 (Usage-Page 0xff42) and responds to a simple 0x02 0x00 battery request:
Charging state doesn't appear to be reported over HID. Tested on Arch Linux with the wireless receiver — battery percentage matches the headset's LED indicator.
Capabilities: battery status only for now.