diff --git a/daemon/src/ctrl_anime/mod.rs b/daemon/src/ctrl_anime/mod.rs index 44596cfa..f93e270a 100644 --- a/daemon/src/ctrl_anime/mod.rs +++ b/daemon/src/ctrl_anime/mod.rs @@ -15,7 +15,6 @@ use rog_anime::usb::{get_anime_type, pkt_for_flush, pkts_for_init}; use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType, AnimeType}; use rog_platform::hid_raw::HidRaw; use rog_platform::supported::AnimeSupportedFunctions; -use rog_platform::usb_raw::USBRaw; use self::config::{AnimeConfig, AnimeConfigCached}; use crate::error::RogError; @@ -30,7 +29,7 @@ impl GetSupported for CtrlAnime { } pub struct CtrlAnime { - node: USBRaw, + node: HidRaw, anime_type: AnimeType, cache: AnimeConfigCached, config: AnimeConfig, @@ -43,8 +42,8 @@ pub struct CtrlAnime { impl CtrlAnime { #[inline] pub fn new(config: AnimeConfig) -> Result> { - let node = USBRaw::new(0x193b)?; - let anime_type = get_anime_type()?; + let node = HidRaw::new("193b")?; + let anime_type = get_anime_type().unwrap_or(AnimeType::GA401); info!("Device has an AniMe Matrix display"); let mut cache = AnimeConfigCached::default(); diff --git a/rog-anime/Cargo.toml b/rog-anime/Cargo.toml index 787a2ee1..5ac26f2b 100644 --- a/rog-anime/Cargo.toml +++ b/rog-anime/Cargo.toml @@ -17,6 +17,15 @@ default = ["dbus", "detect"] dbus = ["zbus"] detect = ["sysfs-class"] +[lib] +name = "rog_anime" +path = "src/lib.rs" + +[[bin]] +name = "anime_sim" +path = "src/simulator.rs" + + [dependencies] png_pong.workspace = true pix.workspace = true diff --git a/rog-anime/src/simulator.rs b/rog-anime/src/simulator.rs new file mode 100644 index 00000000..b1f04665 --- /dev/null +++ b/rog-anime/src/simulator.rs @@ -0,0 +1,126 @@ +use std::error::Error; + +use log::error; +use rog_anime::usb::{PROD_ID, VENDOR_ID}; +use uhid_virt::{Bus, CreateParams, UHIDDevice}; + +pub struct VirtAnimeMatrix { + device: UHIDDevice, +} + +impl Default for VirtAnimeMatrix { + fn default() -> Self { + Self::new() + } +} + +impl VirtAnimeMatrix { + pub fn new() -> Self { + VirtAnimeMatrix { + device: UHIDDevice::create(CreateParams { + name: String::from("ROG_Virtual Anime Matrix"), + phys: String::from(""), + uniq: String::from(""), + bus: Bus::USB, + vendor: VENDOR_ID as u32, + product: PROD_ID as u32, + version: 0, + country: 0, + // This is a device which emits the usage code as a whole, rather than as bits + rd_data: [ + 0x06, 0x31, 0xff, // Usage Page (Vendor Defined 0xFF31) + 0x09, 0x76, // Usage (0x76) + 0xa1, 0x01, // Collection (Application) + 0x85, 0x5a, // Report ID (90) + 0x19, 0x00, // Usage Minimum (0x00) + 0x2a, 0xff, 0x00, // Usage Maximum (0xFF) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xff, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8) + 0x95, 0x05, // Report Count (5) + 0x81, + 0x00, /* Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null + * Position) */ + 0x19, 0x00, // Usage Minimum (0x00) + 0x2a, 0xff, 0x00, // Usage Maximum (0xFF) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xff, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8) + 0x95, 0x3f, // Report Count (63) + 0xb1, + 0x00, /* Feature (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null + * Position,Non-volatile) */ + 0xc0, // End Collection + 0x06, 0x31, 0xff, // Usage Page (Vendor Defined 0xFF31) + 0x09, 0x80, // Usage (0x80) + 0xa1, 0x01, // Collection (Application) + 0x85, 0x5e, // Report ID (94) + 0x19, 0x00, // Usage Minimum (0x00) + 0x2a, 0xff, 0x00, // Usage Maximum (0xFF) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xff, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8) + 0x95, 0x05, // Report Count (5) + 0x81, + 0x00, /* Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null + * Position) */ + 0x19, 0x00, // Usage Minimum (0x00) + 0x2a, 0xff, 0x00, // Usage Maximum (0xFF) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xff, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8) + 0x96, 0x7f, 0x02, // Report Count (639) + 0xb1, + 0x00, /* Feature (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null + * Position,Non-volatile) */ + 0xc0, /* End Collection */ + + /* 85 bytes */ + ] + .to_vec(), + }) + .map_err(|err| error!("Could not create virtual device: {:?}", err)) + .expect("Could not create virtual device"), + } + } + + /// A single on/off key press + pub fn press(&mut self, input: [u8; 32]) { + self.device.write(&input).unwrap(); + let mut reset = [0u8; 32]; + reset[0] = input[0]; + self.device.write(&reset).unwrap(); + } + + pub fn read(&mut self) { + if let Ok(event) = self.device.read() { + match event { + // uhid_virt::OutputEvent::Start { dev_flags } => todo!(), + // uhid_virt::OutputEvent::Stop => todo!(), + // uhid_virt::OutputEvent::Open => todo!(), + // uhid_virt::OutputEvent::Close => todo!(), + uhid_virt::OutputEvent::Output { data } => { + dbg!(data); + } + uhid_virt::OutputEvent::GetReport { + id, + report_number, + report_type, + } => { + dbg!(id, report_number, report_type); + } + // uhid_virt::OutputEvent::SetReport { id, report_number, report_type, data } => + // todo!(), + _ => {} + } + } + } +} + +fn main() -> Result<(), Box> { + let mut dev = VirtAnimeMatrix::new(); + + loop { + dev.read(); + } +} diff --git a/rog-platform/src/hid_raw.rs b/rog-platform/src/hid_raw.rs index 46fbe994..1ca2bb02 100644 --- a/rog-platform/src/hid_raw.rs +++ b/rog-platform/src/hid_raw.rs @@ -34,11 +34,20 @@ impl HidRaw { if let Some(parent) = parent.attribute_value("idProduct") { if parent == id_product { if let Some(dev_node) = device.devnode() { - info!("Using device at: {:?} for LED control", dev_node); + info!("Using device at: {:?} for hidraw control", dev_node); return Ok(Self(dev_node.to_owned())); } } } + } else { + // Try to see if there is a virtual device created with uhid for testing + let dev_path = device.devpath().to_string_lossy(); + if dev_path.contains("virtual") && dev_path.contains(&id_product.to_uppercase()) { + if let Some(dev_node) = device.devnode() { + info!("Using device at: {:?} for asdfgsadfgh control", dev_node); + return Ok(Self(dev_node.to_owned())); + } + } } } Err(PlatformError::MissingFunction(format!(