diff --git a/asusd/src/ctrl_aura/config.rs b/asusd/src/ctrl_aura/config.rs index 39676537..09c9e59a 100644 --- a/asusd/src/ctrl_aura/config.rs +++ b/asusd/src/ctrl_aura/config.rs @@ -18,6 +18,12 @@ pub enum AuraPowerConfig { AuraDevRog2(AuraPower), } +impl Default for AuraPowerConfig { + fn default() -> Self { + Self::AuraDevTuf(HashSet::default()) + } +} + impl AuraPowerConfig { /// Invalid for TUF laptops pub fn to_bytes(control: &Self) -> [u8; 4] { @@ -101,7 +107,7 @@ impl From<&AuraPowerConfig> for AuraPowerDev { } } -#[derive(Deserialize, Serialize, Debug, Clone)] +#[derive(Deserialize, Serialize, Default, Debug, Clone)] // #[serde(default)] pub struct AuraConfig { pub config_name: String, diff --git a/asusd/src/ctrl_aura/controller.rs b/asusd/src/ctrl_aura/controller.rs index 2d01bead..37283ab0 100644 --- a/asusd/src/ctrl_aura/controller.rs +++ b/asusd/src/ctrl_aura/controller.rs @@ -62,7 +62,7 @@ impl CtrlKbdLed { pub fn find_all(data: &LaptopLedData) -> Result, RogError> { info!("Searching for all Aura devices"); let mut devices = Vec::new(); - let mut found = HashSet::new(); + let mut found = HashSet::new(); // track and ensure we use only one hidraw per prod_id let mut enumerator = udev::Enumerator::new().map_err(|err| { warn!("{}", err); @@ -92,13 +92,14 @@ impl CtrlKbdLed { } // Device is something like 002, while its parent is the MCU // Think of it like the device is an endpoint of the USB device attached + let mut aura_dev = AuraDevice::Unknown; if let Some(usb_id) = usb_device.attribute_value("idProduct") { - let prod_id = AuraDevice::from(usb_id.to_str().unwrap()); - if prod_id == AuraDevice::Unknown || found.contains(&prod_id) { + aura_dev = AuraDevice::from(usb_id.to_str().unwrap()); + if aura_dev == AuraDevice::Unknown || found.contains(&aura_dev) { log::debug!("Unknown or invalid device: {usb_id:?}, skipping"); continue; } - found.insert(prod_id); + found.insert(aura_dev); } let dev_node = if let Some(dev_node) = usb_device.devnode() { @@ -110,7 +111,8 @@ impl CtrlKbdLed { info!("AuraControl found device at: {:?}", dev_node); let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default(); let dev = HidRaw::from_device(end_point)?; - let dev = Self::from_hidraw(dev, dbus_path, data)?; + let mut dev = Self::from_hidraw(dev, dbus_path, data)?; + dev.config = Self::init_config(aura_dev, data); devices.push(dev); } } @@ -119,6 +121,9 @@ impl CtrlKbdLed { Ok(devices) } + /// The generated data from this function has a default config. This config + /// should be overwritten. The reason for the default config is because + /// of async issues between this and udev/hidraw pub fn from_hidraw( device: HidRaw, dbus_path: OwnedObjectPath, @@ -132,20 +137,20 @@ impl CtrlKbdLed { } // New loads data from the DB also - let config = Self::init_config(prod_id, data); + // let config = Self::init_config(prod_id, data); let ctrl = CtrlKbdLed { led_prod: prod_id, led_node: LEDNode::Rog(rgb_led, device), supported_data: data.clone(), per_key_mode_active: false, - config, + config: AuraConfig::default(), dbus_path, }; Ok(ctrl) } - fn init_config(prod_id: AuraDevice, supported_basic_modes: &LaptopLedData) -> AuraConfig { + pub fn init_config(prod_id: AuraDevice, supported_basic_modes: &LaptopLedData) -> AuraConfig { // New loads data from the DB also let mut config_init = AuraConfig::new_with(prod_id); // config_init.set_filename(prod_id); diff --git a/asusd/src/ctrl_aura/manager.rs b/asusd/src/ctrl_aura/manager.rs index e2dfd6ca..6a518ba3 100644 --- a/asusd/src/ctrl_aura/manager.rs +++ b/asusd/src/ctrl_aura/manager.rs @@ -4,7 +4,7 @@ // - Add it to Zbus server // - If udev sees device removed then remove the zbus path -use std::collections::HashMap; +use std::collections::HashSet; use std::sync::Arc; use log::{debug, error, info, warn}; @@ -26,20 +26,19 @@ use crate::{CtrlTask, Reloadable}; pub struct AuraManager { _connection: Connection, - interfaces: Arc>>, } impl AuraManager { pub async fn new(mut connection: Connection) -> Result { let conn_copy = connection.clone(); let data = LaptopLedData::get_data(); - let mut interfaces = HashMap::new(); + let mut interfaces = HashSet::new(); // Do the initial keyboard detection: let all = CtrlKbdLed::find_all(&data)?; for ctrl in all { let path = ctrl.dbus_path.clone(); - interfaces.insert(ctrl.led_prod, path.clone()); // ensure we record the initial stuff + interfaces.insert(path.clone()); // ensure we record the initial stuff let sig_ctx = CtrlAuraZbus::signal_context(&connection)?; let sig_ctx2 = sig_ctx.clone(); let zbus = CtrlAuraZbus::new(ctrl, sig_ctx); @@ -51,11 +50,10 @@ impl AuraManager { let manager = Self { _connection: connection, - interfaces: Arc::new(Mutex::new(interfaces)), }; - let interfaces_copy = manager.interfaces.clone(); // detect all plugged in aura devices (eventually) + let interfaces = Arc::new(Mutex::new(interfaces)); tokio::spawn(async move { let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?; let mut poll = Poll::new()?; @@ -64,8 +62,13 @@ impl AuraManager { .register(&mut monitor, Token(0), Interest::READABLE)?; loop { - poll.poll(&mut events, None).unwrap(); + if poll.poll(&mut events, None).is_err() { + continue; + } for event in monitor.iter() { + if event.parent_with_subsystem("hidraw").is_err() { + continue; + } if let Some(parent) = event.parent_with_subsystem_devtype("usb", "usb_device")? { @@ -75,51 +78,62 @@ impl AuraManager { continue; }; + let path = if let Some(path) = dbus_path_for_dev(&parent) { + path + } else { + continue; + }; + if action == "remove" { - if let Some(id_product) = parent.attribute_value("idProduct") { - let id_product = AuraDevice::from(id_product.to_str().unwrap()); - let interfaces_copy = interfaces_copy.clone(); + dbg!("REMOVING"); + if let Some(_) = parent.attribute_value("idProduct") { + info!("AuraManager removing: {path:?}"); let conn_copy = conn_copy.clone(); + let interfaces_copy = interfaces.clone(); tokio::spawn(async move { let mut interfaces = interfaces_copy.lock().await; - if let Some(path) = interfaces.remove(&id_product) { - info!("AuraManager removing: {path:?}"); - let res = conn_copy - .object_server() - .remove::(&path) - .await - .map_err(|e| { - error!("Failed to remove {path:?}, {e:?}"); - e - })?; - info!("AuraManager removed: {path:?}, {res}"); - } + let res = conn_copy + .object_server() + .remove::(&path) + .await + .map_err(|e| { + error!("Failed to remove {path:?}, {e:?}"); + e + })?; + info!("AuraManager removed: {path:?}, {res}"); + interfaces.remove(&path); + debug!("Removed {path:?}"); Ok::<(), RogError>(()) }); } - } - - let id_product = - if let Some(id_product) = parent.attribute_value("idProduct") { - id_product.to_string_lossy().to_string() - } else { - continue; - }; - if let Some(p2) = event.parent() { - if let Some(driver) = p2.driver() { - // There is a tree of devices added so filter by driver - if driver != "asus" { + } else if action == "add" { + dbg!("ADDING"); + let id_product = + if let Some(id_product) = parent.attribute_value("idProduct") { + id_product.to_string_lossy().to_string() + } else { + continue; + }; + if let Some(p2) = event.parent() { + if let Some(driver) = p2.driver() { + // There is a tree of devices added so filter by driver + if driver != "asus" { + continue; + } + } else { continue; } - } else { - continue; } - } - // try conversion to known idProduct - let aura_device = AuraDevice::from(id_product.as_str()); - if aura_device != AuraDevice::Unknown { - if action == "add" { + // try conversion to known idProduct + let aura_device = AuraDevice::from(id_product.as_str()); + if aura_device != AuraDevice::Unknown { + let path = if let Some(path) = dbus_path_for_dev(&parent) { + path + } else { + continue; + }; + let dev_node = if let Some(dev_node) = event.devnode() { dev_node } else { @@ -129,26 +143,31 @@ impl AuraManager { if let Ok(raw) = HidRaw::from_device(event.device()) .map_err(|e| error!("device path error: {e:?}")) { - let path = if let Some(path) = dbus_path_for_dev(&parent) { - path - } else { - continue; - }; - if let Ok(ctrl) = + // bah... shitty clone TODO: fix + let data_clone = data.clone(); + if let Ok(mut ctrl) = CtrlKbdLed::from_hidraw(raw, path.clone(), &data) { - info!("AuraManager found device at: {:?}", dev_node); + info!( + "AuraManager found device at: {dev_node:?}, {path:?}" + ); let mut conn_copy = conn_copy.clone(); - let interfaces_copy = interfaces_copy.clone(); + let interfaces_copy = interfaces.clone(); // tokio::spawn(async move { let mut interfaces = interfaces_copy.lock().await; - interfaces.insert(aura_device, path.clone()); + if interfaces.contains(&path) { + debug!("Already a ctrl at {path:?}"); + return Ok(()); + } + debug!("Starting Aura at {path}"); + interfaces.insert(path.clone()); let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; + ctrl.config = + CtrlKbdLed::init_config(aura_device, &data_clone); let zbus = CtrlAuraZbus::new(ctrl, sig_ctx); // Now add it to device list let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; - debug!("Starting Aura at {path}"); start_tasks(zbus, &mut conn_copy, sig_ctx, &path) .await?; Ok::<(), RogError>(()) @@ -156,9 +175,9 @@ impl AuraManager { // MonitorSocket } } + } else { + warn!("idProduct:{id_product:?} is unknown, not using") } - } else { - warn!("idProduct:{id_product:?} is unknown, not using") } } } diff --git a/asusd/src/ctrl_aura/trait_impls.rs b/asusd/src/ctrl_aura/trait_impls.rs index 2f852d61..2f2fa805 100644 --- a/asusd/src/ctrl_aura/trait_impls.rs +++ b/asusd/src/ctrl_aura/trait_impls.rs @@ -210,23 +210,29 @@ impl CtrlTask for CtrlAuraZbus { } async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> { - let load_save = |start: bool, mut lock: MutexGuard<'_, CtrlKbdLed>| { - // If waking up - if !start { - info!("CtrlKbdLedTask reloading brightness and modes"); - lock.led_node - .set_brightness(lock.config.brightness.into()) - .map_err(|e| error!("CtrlKbdLedTask: {e}")) - .ok(); - lock.write_current_config_mode() - .map_err(|e| error!("CtrlKbdLedTask: {e}")) - .ok(); - } else if start { - Self::update_config(&mut lock) - .map_err(|e| error!("CtrlKbdLedTask: {e}")) - .ok(); - } - }; + let load_save = + |start: bool, mut lock: MutexGuard<'_, CtrlKbdLed>| -> Result<(), RogError> { + // If waking up + if !start { + info!("CtrlKbdLedTask reloading brightness and modes"); + lock.led_node + .set_brightness(lock.config.brightness.into()) + .map_err(|e| { + error!("CtrlKbdLedTask: {e}"); + e + })?; + lock.write_current_config_mode().map_err(|e| { + error!("CtrlKbdLedTask: {e}"); + e + })?; + } else if start { + Self::update_config(&mut lock).map_err(|e| { + error!("CtrlKbdLedTask: {e}"); + e + })?; + } + Ok(()) + }; let inner1 = self.0.clone(); let inner3 = self.0.clone(); @@ -235,14 +241,16 @@ impl CtrlTask for CtrlAuraZbus { let inner1 = inner1.clone(); async move { let lock = inner1.lock().await; - load_save(sleeping, lock); + load_save(sleeping, lock).unwrap(); // unwrap as we want to + // bomb out of the task } }, move |_shutting_down| { let inner3 = inner3.clone(); async move { let lock = inner3.lock().await; - load_save(false, lock); + load_save(false, lock).unwrap(); // unwrap as we want to + // bomb out of the task } }, move |_lid_closed| { @@ -266,7 +274,8 @@ impl CtrlTask for CtrlAuraZbus { .unwrap() .for_each(|_| async { if let Some(lock) = ctrl2.try_lock() { - load_save(true, lock); + load_save(true, lock).unwrap(); // unwrap as we want to + // bomb out of the task } }) .await; diff --git a/asusd/src/ctrl_platform.rs b/asusd/src/ctrl_platform.rs index 0184a8b6..6f0060f7 100644 --- a/asusd/src/ctrl_platform.rs +++ b/asusd/src/ctrl_platform.rs @@ -29,7 +29,7 @@ macro_rules! platform_get_value { $self.platform .get() .map_err(|err| { - warn!("RogPlatform: {}: {}", $prop_name, err); + warn!("{}: {}", $prop_name, err); FdoErr::Failed(format!("RogPlatform: {}: {}", $prop_name, err)) }) }) @@ -373,7 +373,7 @@ impl CtrlPlatform { #[zbus(property)] fn gpu_mux_mode(&self) -> Result { self.platform.get_gpu_mux_mode().map_err(|err| { - warn!("RogPlatform: set_gpu_mux_mode {err}"); + warn!("get_gpu_mux_mode {err}"); FdoErr::NotSupported("RogPlatform: set_gpu_mux_mode not supported".to_owned()) }) } @@ -382,7 +382,7 @@ impl CtrlPlatform { async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> { if self.platform.has_gpu_mux_mode() { self.set_gfx_mode(mode.into()).map_err(|err| { - warn!("RogPlatform: set_gpu_mux_mode {}", err); + warn!("set_gpu_mux_mode {}", err); FdoErr::Failed(format!("RogPlatform: set_gpu_mux_mode: {err}")) })?; self.config.lock().await.write(); @@ -412,7 +412,7 @@ impl CtrlPlatform { self.platform .set_throttle_thermal_policy(policy.into()) .map_err(|err| { - warn!("RogPlatform: throttle_thermal_policy {}", err); + warn!("throttle_thermal_policy {}", err); FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}")) })?; Ok(self.throttle_thermal_policy_changed(&ctxt).await?) @@ -440,7 +440,7 @@ impl CtrlPlatform { self.platform .set_throttle_thermal_policy(policy.into()) .map_err(|err| { - warn!("RogPlatform: throttle_thermal_policy {}", err); + warn!("throttle_thermal_policy {}", err); FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}")) }) } else {