diff --git a/Cargo.lock b/Cargo.lock index a81d5e05..a16239fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -374,6 +374,16 @@ dependencies = [ "take_mut", ] +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "libusb1-sys" version = "0.3.7" @@ -648,6 +658,7 @@ dependencies = [ "serde_json", "sysfs-class", "tokio", + "udev", ] [[package]] @@ -869,6 +880,16 @@ dependencies = [ "syn", ] +[[package]] +name = "udev" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24953d50a3bce0f5f5a9a2766567072dc9af8096f8c40ea81815da651066bc9f" +dependencies = [ + "libc", + "libudev-sys", +] + [[package]] name = "unicode-xid" version = "0.2.1" diff --git a/rog-core/Cargo.toml b/rog-core/Cargo.toml index 2665b456..881fcf1f 100644 --- a/rog-core/Cargo.toml +++ b/rog-core/Cargo.toml @@ -20,6 +20,7 @@ path = "src/main.rs" [dependencies] rog-client = { path = "../rog-client" } rusb = "^0.6.0" +udev = "^0.4.0" # cli and logging gumdrop = "^0.8.0" diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs index 9bbe454b..ce00bdf0 100644 --- a/rog-core/src/daemon.rs +++ b/rog-core/src/daemon.rs @@ -45,14 +45,24 @@ pub async fn start_daemon() -> Result<(), Box> { .unwrap_or_else(|err| warn!("Battery charge limit: {}", err)); let mut led_writer = LedWriter::new( - "/dev/hidraw2".to_string(), + "1866", laptop.supported_modes().to_owned(), + ).map_or_else( + |err| { + error!("{}", err); + None + }, + |ledwriter| { + info!("LED Writer loaded"); + Some(ledwriter) + }, ); - led_writer - .reload_last_builtin(&mut config) + if let Some(writer) = led_writer.as_mut() { + writer.reload_last_builtin(&mut config) .await .unwrap_or_else(|err| warn!("Reload settings: {}", err)); + } // Set up the mutexes let config = Arc::new(Mutex::new(config)); @@ -149,17 +159,18 @@ pub async fn start_daemon() -> Result<(), Box> { connection.process_all(); while let Some(command) = aura_command_recv.recv().await { + if let Some(writer) = led_writer.as_mut() { let mut config = config.lock().await; match &command { AuraModes::RGB(_) => { - led_writer + writer .do_command(command, &mut config) .await .unwrap_or_else(|err| warn!("{}", err)); } _ => { let json = serde_json::to_string(&command)?; - led_writer + writer .do_command(command, &mut config) .await .unwrap_or_else(|err| warn!("{}", err)); @@ -171,7 +182,7 @@ pub async fn start_daemon() -> Result<(), Box> { ) .unwrap_or_else(|_| 0); } - } + }} } } } diff --git a/rog-core/src/led_control.rs b/rog-core/src/led_control.rs index a53349a2..981d21e9 100644 --- a/rog-core/src/led_control.rs +++ b/rog-core/src/led_control.rs @@ -10,11 +10,6 @@ use rog_client::{ use std::fs::OpenOptions; use std::io::Write; -/// UNSAFE: Must live as long as RogCore -/// -/// Because we're holding a pointer to something that *may* go out of scope while the -/// pointer is held. We're relying on access to struct to be behind a Mutex, and for behaviour -/// that may cause invalididated pointer to cause the program to panic rather than continue. pub struct LedWriter { dev_node: String, supported_modes: Vec, @@ -23,12 +18,30 @@ pub struct LedWriter { impl LedWriter { #[inline] - pub fn new(dev_node: String, supported_modes: Vec) -> Self { - LedWriter { - dev_node, - supported_modes, - flip_effect_write: false, + pub fn new(idProduct: &str, supported_modes: Vec) -> Result { + let mut enumerator = udev::Enumerator::new()?; + enumerator.match_subsystem("hidraw")?; + + for device in enumerator.scan_devices()? { + if let Some(parent) = device.parent_with_subsystem_devtype("usb", "usb_device")? { + if parent.attribute_value("idProduct").unwrap() == idProduct + // && device.parent().unwrap().sysnum().unwrap() == 3 + { + if let Some(dev_node) = device.devnode() { + info!("Using device at: {:?}", dev_node); + return Ok(LedWriter { + dev_node: dev_node.to_string_lossy().to_string(), + supported_modes, + flip_effect_write: false, + }); + } + } + } } + Err(std::io::Error::new( + std::io::ErrorKind::NotFound, + "Device node not found", + )) } pub async fn do_command( @@ -50,8 +63,6 @@ impl LedWriter { } /// Write an effect block - /// - /// `aura_effect_init` must be called any effect routine, and called only once. #[inline] async fn write_effect(&mut self, effect: &[Vec]) -> Result<(), RogError> { if self.flip_effect_write {