From 0d01c406e75cdfa419beef0cdca62210a288a63c Mon Sep 17 00:00:00 2001 From: lennard Date: Fri, 9 Jun 2023 21:09:05 +0200 Subject: [PATCH] Added library crate to interface with headset. --- .gitignore | 5 +++++ Cargo.toml | 10 ++++++++++ src/lib.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore index 6985cf1..196e176 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + + +# Added by cargo + +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a1de77e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "hyper_x_cloud_ii_wireless" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hidapi = "2.3.3" +thiserror = "1.0.40" diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..321d8a0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,53 @@ +use hidapi::{HidApi, HidDevice, HidError}; +use thiserror::Error; + +// Possible vendor IDs [hyperx , HP] +const VENDOR_IDS: [u16; 2] = [0x0951, 0x03F0]; +// Possible Cloud II Wireless product IDs +const PRODUCT_IDS: [u16; 2] = [0x1718, 0x018B]; + +const BATTERY_PACKET: [u8; 20] = { + let mut packet = [0; 20]; + (packet[0], packet[1], packet[2], packet[3]) = (0x06, 0xff, 0xbb, 0x02); + packet +}; + +#[derive(Error, Debug)] +pub enum DeviceError { + #[error("Error: {0}")] + HidError(#[from] HidError), + #[error("Error: No device found.")] + NoDeviceFound(), + #[error("Error: No response. Is the headset turned on?")] + HeadSetOff(), +} + +pub struct Device { + hid_device: HidDevice, +} + +impl Device { + pub fn new() -> Result { + let hid_api = HidApi::new()?; + let hid_device = hid_api.device_list().find_map(|info| { + if PRODUCT_IDS.contains(&info.product_id()) && VENDOR_IDS.contains(&info.vendor_id()) { + Some(hid_api.open(info.vendor_id(), info.product_id())) + } else { + None + } + }).ok_or(DeviceError::NoDeviceFound())??; + Ok(Device { hid_device }) + } + + //TODO: implement charging + pub fn get_battery_level(&self) -> Result<(u8, bool), DeviceError> { + self.hid_device.write(&BATTERY_PACKET)?; + let mut buf = [0u8; 8]; + let res = self.hid_device.read_timeout(&mut buf[..], 1000)?; + if res == 0 { + return Err(DeviceError::HeadSetOff()); + } + println!("Read: {:?}", &buf[..res]); + Ok((buf[7], false)) + } +} \ No newline at end of file