Safe get of led devnode

This commit is contained in:
Luke D Jones
2020-08-03 08:08:41 +12:00
parent d757a936e8
commit 16681d03dd
4 changed files with 62 additions and 18 deletions

21
Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -45,14 +45,24 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
.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<dyn Error>> {
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<dyn Error>> {
)
.unwrap_or_else(|_| 0);
}
}
}}
}
}
}

View File

@@ -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<u8>,
@@ -23,12 +18,30 @@ pub struct LedWriter {
impl LedWriter {
#[inline]
pub fn new(dev_node: String, supported_modes: Vec<u8>) -> Self {
LedWriter {
dev_node,
supported_modes,
flip_effect_write: false,
pub fn new(idProduct: &str, supported_modes: Vec<u8>) -> Result<Self, std::io::Error> {
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<u8>]) -> Result<(), RogError> {
if self.flip_effect_write {