Add support for HyperX Cloud Flight S

- Add PRODUCT_ID 0x16EA to Cloud II Wireless device support
- Cloud Flight S uses the same protocol as Cloud II Wireless
- Update README.md with Cloud Flight S in supported devices list
- Add udev rules for Cloud Flight S (idProduct=16ea)
- Fix prepare_write() to handle devices that don't support get_input_report
- Fix is_none_or compatibility issue for older Rust versions
This commit is contained in:
simyrik
2025-12-12 12:02:52 +07:00
parent 1eb46435ff
commit ea0ced003b
5 changed files with 40 additions and 11 deletions

13
99-HyperHeadset.rules Normal file
View File

@@ -0,0 +1,13 @@
SUBSYSTEMS=="usb", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"

View File

@@ -15,6 +15,7 @@ Although it was only tested on Manjaro and Kubuntu with KDE, it should also work
- HyperX Cloud II Wireless HyperX vendorID - HyperX Cloud II Wireless HyperX vendorID
- HyperX Cloud III Wireless - HyperX Cloud III Wireless
- HyperX Cloud Stinger 2 Wireless - HyperX Cloud Stinger 2 Wireless
- HyperX Cloud Flight S
It should be possible to add support for other HyperX headsets. It should be possible to add support for other HyperX headsets.
@@ -62,12 +63,14 @@ SUBSYSTEMS=="usb", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666
SUBSYSTEMS=="usb", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666" SUBSYSTEMS=="usb", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666" SUBSYSTEMS=="usb", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666" SUBSYSTEMS=="usb", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666" KERNEL=="hidraw*", ATTRS{idProduct}=="0d93", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666" KERNEL=="hidraw*", ATTRS{idProduct}=="018b", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666" KERNEL=="hidraw*", ATTRS{idProduct}=="0696", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666" KERNEL=="hidraw*", ATTRS{idProduct}=="1718", ATTRS{idVendor}=="0951", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666" KERNEL=="hidraw*", ATTRS{idProduct}=="05b7", ATTRS{idVendor}=="03f0", MODE="0666"
KERNEL=="hidraw*", ATTRS{idProduct}=="16ea", ATTRS{idVendor}=="0951", MODE="0666"
``` ```
Once created, replug the wireless dongle. Once created, replug the wireless dongle.

10
hyper-headset.desktop Normal file
View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=HyperHeadset
Comment=Monitor and manage HyperX headsets
Exec=/usr/local/bin/hyper_headset
Icon=audio-card
Terminal=false
Categories=AudioVideo;Audio;
StartupNotify=false
X-GNOME-Autostart-enabled=true

View File

@@ -6,8 +6,8 @@ use std::time::Duration;
const HYPERX: u16 = 0x0951; const HYPERX: u16 = 0x0951;
pub const VENDOR_IDS: [u16; 1] = [HYPERX]; pub const VENDOR_IDS: [u16; 1] = [HYPERX];
// Possible Cloud II Wireless product IDs // Possible Cloud II Wireless product IDs (and Cloud Flight S)
pub const PRODUCT_IDS: [u16; 3] = [0x1718, 0x018B, 0x0b92]; pub const PRODUCT_IDS: [u16; 4] = [0x1718, 0x018B, 0x0b92, 0x16EA];
const BASE_PACKET: [u8; 62] = { const BASE_PACKET: [u8; 62] = {
let mut tmp = [0u8; 62]; let mut tmp = [0u8; 62];
@@ -266,12 +266,15 @@ impl Device for CloudIIWireless {
} }
fn prepare_write(&mut self) { fn prepare_write(&mut self) {
// Attempt to read input report before writing
// This may not work for all devices (e.g., Cloud Flight S),
// so we ignore the error
let mut input_report_buffer = [0u8; 64]; let mut input_report_buffer = [0u8; 64];
input_report_buffer[0] = 6; input_report_buffer[0] = 6;
self.state let _ = self
.state
.hid_device .hid_device
.get_input_report(&mut input_report_buffer) .get_input_report(&mut input_report_buffer);
.unwrap();
} }
fn allow_passive_refresh(&mut self) -> bool { fn allow_passive_refresh(&mut self) -> bool {

View File

@@ -16,7 +16,7 @@ use thistermination::TerminationFull;
// Possible vendor IDs [HyperX, HP] // Possible vendor IDs [HyperX, HP]
const VENDOR_IDS: [u16; 2] = [0x0951, 0x03F0]; const VENDOR_IDS: [u16; 2] = [0x0951, 0x03F0];
// All supported product IDs // All supported product IDs
const PRODUCT_IDS: [u16; 6] = [0x1718, 0x018B, 0x0D93, 0x0696, 0x0b92, 0x05B7]; const PRODUCT_IDS: [u16; 7] = [0x1718, 0x018B, 0x0D93, 0x0696, 0x0b92, 0x05B7, 0x16EA];
const RESPONSE_BUFFER_SIZE: usize = 256; const RESPONSE_BUFFER_SIZE: usize = 256;
const RESPONSE_DELAY: Duration = Duration::from_millis(50); const RESPONSE_DELAY: Duration = Duration::from_millis(50);
@@ -518,7 +518,7 @@ pub trait Device {
} }
responded = true; responded = true;
} }
if !self.get_device_state().connected.is_none_or(|c| c) { if !matches!(self.get_device_state().connected, Some(true)) {
break; break;
} }
} }