Repository navigation
Conversation
Adds the Nova Pro Omni GameHub (VID 0x1038, PID 0x2290). The Omni's GameHub is a close cousin of the Nova Pro Wireless but its vendor HID interface differs: commands use report ID 0x01 and 64-byte reports, and interface 3 exposes two top-level collections, so the command/response channel (usage page 0xFFC0, report ID 1) must be selected explicitly. Verified empirically on firmware rev 0x0132: - Battery: 01 B0 -> reply[6] battery %, reply[15] status (01 offline / 02 charging / 08 online). - Sidetone: 01 38 <enable> <level>, level 0-10. Write-only (no readable sidetone state exists on this hub), so no getSidetone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sapd
left a comment
There was a problem hiding this comment.
Good writeup in the header - the two-collection detail and why it's a new device rather than a PID are exactly what the next person needs.
Two things:
make format - clang-format 18 wants steelseries_arctis_nova_pro_omni.hpp before ..._wireless.hpp in device_registry.cpp. CI will fail on it.
The battery comment doesn't match the code. Header and inline both say the fuel gauge caps at 99 and you present that as full, but the code is if (level > 100) level = 100, which never maps 99 to 100. Either the comment is wrong or users never see 100%. Which is it on your hardware?
Otherwise builds clean here, tests pass, README matches --readme-helper.
|
Tested this on Linux (CachyOS, hidraw backend) with an Omni GameHub ( 1. Battery reads 0% on Linux: the hub interleaves event reports with the While the headset is connected, the hub pushes unsolicited reports with report ID Skipping anything that isn't // The hub interleaves unsolicited event reports (report ID 0x07) on
// the same collection, so skip anything that isn't the 01 B0 reply.
std::vector<uint8_t> response(STATUS_BUF_SIZE);
bool got_status = false;
for (int attempt = 0; attempt < 8 && !got_status; attempt++) {
auto read_result = this->readHIDTimeout(device_handle, response, hsc_device_timeout);
if (!read_result) {
return read_result.error();
}
got_status = *read_result >= 16 && response[0] == 0x01 && response[1] == 0xb0;
}
if (!got_status) {
return DeviceError::protocolError("No status reply from hub");
}2. Sidetone is readable After writing 3. I think Thanks for the PR, the two-collection notes saved a lot of time. |
Adds support for the SteelSeries Arctis Nova Pro Omni GameHub (VID
0x1038, PID0x2290).Capabilities
01 B0status poll;reply[6]= headset battery %,reply[15]= status (0x01offline,0x02cable charging,0x08online).01 38 <enable> <level>, level 0–10. Write-only: the hub exposes no readable sidetone state (verified against the status poll, the config feature report, and the Nova 7's0x20query), so nogetSidetone.Notes for reviewers
The Omni's GameHub is a close cousin of the Nova Pro Wireless base station, but its vendor HID interface differs in two ways, which is why it's a new device rather than an added PID:
0x01(not0x06) and 64-byte reports (not 31).0xFFC0, report ID 1, selected viagetCapabilityDetail(same pattern as the Nova 7 Gen 2).It extends
SteelSeriesNovaDevice(64-byte packets + usage-page selection) with battery/sidetone overrides for the Omni's report-ID and status-byte layout.Testing
Built on Windows (MSYS2/MinGW, GCC 16) and tested against real hardware (firmware rev
0x0132):headsetcontrol --listdetects the device.headsetcontrol -breturns a correct battery level (verified 93%, matching the OLED).headsetcontrol -s 0/128toggles sidetone audibly.Reverse-engineered by USB capture (USBPcap) of SteelSeries GG traffic plus replay verification. The 1035-byte HID feature report (hardware EQ/preset store) is never written.