diff --git a/CHANGELOG.md b/CHANGELOG.md index bd17e882..4b02ddff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [v6.0.6] + +### Added +- Add GX650R laptop to aura DB + +### Changed +- Further tweaks to aura init +- More logging +- Fix TUF laptop led power + ## [v6.0.5] ### Changed diff --git a/asusd/src/ctrl_aura/controller.rs b/asusd/src/ctrl_aura/controller.rs index de187d14..0f8bdfcc 100644 --- a/asusd/src/ctrl_aura/controller.rs +++ b/asusd/src/ctrl_aura/controller.rs @@ -12,11 +12,15 @@ use rog_aura::{ }; use rog_platform::hid_raw::HidRaw; use rog_platform::keyboard_led::KeyboardBacklight; +use udev::Device; use zbus::zvariant::OwnedObjectPath; +use zbus::Connection; use super::config::AuraConfig; -use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf}; +use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf, start_tasks}; +use crate::ctrl_aura::trait_impls::CtrlAuraZbus; use crate::error::RogError; +use crate::CtrlTask; #[derive(Debug)] pub enum LEDNode { @@ -99,10 +103,84 @@ pub struct CtrlKbdLed { } impl CtrlKbdLed { + pub fn add_to_dbus_and_start( + self, + interfaces: &mut HashSet, + conn: Connection, + ) -> Result<(), RogError> { + let dbus_path = self.dbus_path.clone(); + interfaces.insert(dbus_path.clone()); + info!( + "AuraManager starting device at: {:?}, {:?}", + dbus_path, self.led_type + ); + let conn_copy = conn.clone(); + let sig_ctx1 = CtrlAuraZbus::signal_context(&conn_copy)?; + let sig_ctx2 = CtrlAuraZbus::signal_context(&conn_copy)?; + let zbus = CtrlAuraZbus::new(self, sig_ctx1); + tokio::spawn( + async move { start_tasks(zbus, conn_copy.clone(), sig_ctx2, dbus_path).await }, + ); + Ok(()) + } + + /// Build and init a `CtrlKbdLed` from a udev device. Maybe. + /// This will initialise the config also. + pub fn maybe_device( + device: Device, + interfaces: &mut HashSet, + ) -> Result, RogError> { + // usb_device gives us a product and vendor ID + if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? { + let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default(); + if interfaces.contains(&dbus_path) { + debug!("Already a ctrl at {dbus_path:?}"); + return Ok(None); + } + + // The asus_wmi driver latches MCU that controls the USB endpoints + if let Some(parent) = device.parent() { + if let Some(driver) = parent.driver() { + // There is a tree of devices added so filter by driver + if driver != "asus" { + return Ok(None); + } + } else { + return Ok(None); + } + } + // 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 prod_id = String::new(); + if let Some(usb_id) = usb_device.attribute_value("idProduct") { + prod_id = usb_id.to_string_lossy().to_string(); + let aura_device = AuraDeviceType::from(prod_id.as_str()); + if aura_device == AuraDeviceType::Unknown { + log::debug!("Unknown or invalid device: {usb_id:?}, skipping"); + return Ok(None); + } + } + + let dev_node = if let Some(dev_node) = usb_device.devnode() { + dev_node + } else { + debug!("Device has no devnode, skipping"); + return Ok(None); + }; + info!("AuraControl found device at: {:?}", dev_node); + let dev = HidRaw::from_device(device)?; + let mut controller = Self::from_hidraw(dev, dbus_path.clone())?; + controller.config = Self::init_config(&prod_id); + interfaces.insert(dbus_path); + return Ok(Some(controller)); + } + Ok(None) + } + pub fn find_all() -> Result, RogError> { info!("Searching for all Aura devices"); let mut devices = Vec::new(); - let mut found = HashSet::new(); // track and ensure we use only one hidraw per prod_id + let mut interfaces = HashSet::new(); // track and ensure we use only one hidraw per prod_id let mut enumerator = udev::Enumerator::new().map_err(|err| { warn!("{}", err); @@ -115,46 +193,9 @@ impl CtrlKbdLed { })?; for end_point in enumerator.scan_devices()? { - // usb_device gives us a product and vendor ID - if let Some(usb_device) = - end_point.parent_with_subsystem_devtype("usb", "usb_device")? - { - // The asus_wmi driver latches MCU that controls the USB endpoints - if let Some(parent) = end_point.parent() { - if let Some(driver) = parent.driver() { - // There is a tree of devices added so filter by driver - if driver != "asus" { - continue; - } - } else { - continue; - } - } - // 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 prod_id = String::new(); - if let Some(usb_id) = usb_device.attribute_value("idProduct") { - prod_id = usb_id.to_string_lossy().to_string(); - let aura_dev = AuraDeviceType::from(prod_id.as_str()); - if aura_dev == AuraDeviceType::Unknown || found.contains(&aura_dev) { - log::debug!("Unknown or invalid device: {usb_id:?}, skipping"); - continue; - } - found.insert(aura_dev); - } - - let dev_node = if let Some(dev_node) = usb_device.devnode() { - dev_node - } else { - debug!("Device has no devnode, skipping"); - continue; - }; - 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 mut dev = Self::from_hidraw(dev, dbus_path)?; - dev.config = Self::init_config(&prod_id); - devices.push(dev); + // maybe? + if let Some(device) = Self::maybe_device(end_point, &mut interfaces)? { + devices.push(device); } } @@ -264,13 +305,10 @@ impl CtrlKbdLed { /// Set combination state for boot animation/sleep animation/all leds/keys /// leds/side leds LED active pub(super) fn set_power_states(&mut self) -> Result<(), RogError> { - if let LEDNode::KbdLed(_platform) = &mut self.led_node { + if let LEDNode::KbdLed(platform) = &mut self.led_node { // TODO: tuf bool array - // if let Some(pwr) = - // AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) { - // let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8, - // pwr[4] as u8]; platform.set_kbd_rgb_state(&buf)?; - // } + let buf = self.config.enabled.to_bytes(self.led_type); + platform.set_kbd_rgb_state(&buf)?; } else if let LEDNode::Rog(_, hid_raw) = &self.led_node { let bytes = self.config.enabled.to_bytes(self.led_type); let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]]; diff --git a/asusd/src/ctrl_aura/manager.rs b/asusd/src/ctrl_aura/manager.rs index 0bd965ba..212574bb 100644 --- a/asusd/src/ctrl_aura/manager.rs +++ b/asusd/src/ctrl_aura/manager.rs @@ -6,10 +6,8 @@ use std::collections::HashSet; -use log::{debug, error, info, warn}; +use log::{error, info, warn}; use mio::{Events, Interest, Poll, Token}; -use rog_aura::AuraDeviceType; -use rog_platform::hid_raw::HidRaw; use tokio::task::spawn_blocking; use udev::{Device, MonitorBuilder}; use zbus::object_server::SignalContext; @@ -59,93 +57,42 @@ impl AuraManager { continue; } for event in monitor.iter() { - let parent = if let Some(parent) = + let action = event.action().unwrap_or_default(); + + if let Some(parent) = event.parent_with_subsystem_devtype("usb", "usb_device")? { - parent - } else { - continue; - }; - - let action = if let Some(action) = event.action() { - action - } else { - continue; - }; - - let id_product = if let Some(id_product) = parent.attribute_value("idProduct") { - id_product.to_string_lossy() - } else { - continue; - }; - - let path = if let Some(path) = dbus_path_for_dev(&parent) { - path - } else { - continue; - }; - - let aura_device = AuraDeviceType::from(&*id_product); - if aura_device == AuraDeviceType::Unknown { - warn!("idProduct:{id_product:?} is unknown, not using"); - continue; - } - - if action == "remove" { - if interfaces.remove(&path) { - info!("AuraManager removing: {path:?}"); - let conn_copy = conn_copy.clone(); - tokio::spawn(async move { - let res = conn_copy - .object_server() - .remove::(&path) - .await - .map_err(|e| { - error!("Failed to remove {path:?}, {e:?}"); - e - })?; - info!("AuraManager removed: {path:?}, {res}"); - Ok::<(), RogError>(()) - }); - } - } else if action == "add" { - if interfaces.contains(&path) { - debug!("Already a ctrl at {path:?}"); - continue; - } - - // Need to check the driver is asus to prevent using hid_generic - 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" { - debug!("{id_product:?} driver was not asus, skipping"); - continue; - } - } else { - continue; - } - } - - if let Some(dev_node) = event.devnode() { - if let Ok(raw) = HidRaw::from_device(event.device()) - .map_err(|e| error!("device path error: {e:?}")) - { - if let Ok(mut ctrl) = CtrlKbdLed::from_hidraw(raw, path.clone()) { - ctrl.config = CtrlKbdLed::init_config(&id_product); - interfaces.insert(path.clone()); - info!("AuraManager starting device at: {dev_node:?}, {path:?}"); - let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; - let zbus = CtrlAuraZbus::new(ctrl, sig_ctx); - let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?; + if action == "remove" { + if let Some(path) = dbus_path_for_dev(&parent) { + if interfaces.remove(&path) { + info!("AuraManager removing: {path:?}"); let conn_copy = conn_copy.clone(); tokio::spawn(async move { - start_tasks(zbus, conn_copy.clone(), sig_ctx, path).await + let res = conn_copy + .object_server() + .remove::(&path) + .await + .map_err(|e| { + error!("Failed to remove {path:?}, {e:?}"); + e + })?; + info!("AuraManager removed: {path:?}, {res}"); + Ok::<(), RogError>(()) }); } } - } - }; + } else if action == "add" { + if let Ok(Some(ctrl)) = + CtrlKbdLed::maybe_device(event.device(), &mut interfaces) + { + ctrl.add_to_dbus_and_start(&mut interfaces, conn_copy.clone()) + .map_err(|e| { + error!("Couldn't start aura device on dbus: {e:?}") + }) + .ok(); + } + }; + } } } // Required for return type on spawn @@ -169,7 +116,7 @@ pub(crate) fn dbus_path_for_tuf() -> OwnedObjectPath { ObjectPath::from_str_unchecked(&format!("{AURA_ZBUS_PATH}/tuf")).into() } -async fn start_tasks( +pub async fn start_tasks( mut zbus: CtrlAuraZbus, connection: Connection, _signal_ctx: SignalContext<'static>, @@ -180,7 +127,12 @@ async fn start_tasks( zbus.reload() .await .unwrap_or_else(|err| warn!("Controller error: {}", err)); - connection.object_server().at(path, zbus).await.unwrap(); + connection + .object_server() + .at(path.clone(), zbus) + .await + .map_err(|e| error!("Couldn't add server at path: {path}, {e:?}")) + .ok(); // TODO: skip this until we keep handles to tasks so they can be killed // task.create_tasks(signal_ctx).await Ok(()) diff --git a/asusd/src/ctrl_aura/trait_impls.rs b/asusd/src/ctrl_aura/trait_impls.rs index 51855f5f..7c455c25 100644 --- a/asusd/src/ctrl_aura/trait_impls.rs +++ b/asusd/src/ctrl_aura/trait_impls.rs @@ -279,8 +279,10 @@ impl CtrlTask for CtrlAuraZbus { .unwrap() .for_each(|_| async { if let Some(lock) = ctrl2.try_lock() { - load_save(true, lock).unwrap(); // unwrap as we want to - // bomb out of the task + load_save(true, lock).unwrap(); // unwrap as we want + // to + // bomb out of the + // task } }) .await; diff --git a/rog-aura/data/aura_support.ron b/rog-aura/data/aura_support.ron index 5e69671e..18373f96 100644 --- a/rog-aura/data/aura_support.ron +++ b/rog-aura/data/aura_support.ron @@ -746,6 +746,15 @@ advanced_type: PerKey, power_zones: [Keyboard], ), + ( + device_name: "GX650R", + product_id: "", + layout_name: "gx531-per-key", + basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash], + basic_zones: [], + advanced_type: PerKey, + power_zones: [Keyboard], + ), ( device_name: "GX701", product_id: "", diff --git a/rog-aura/src/aura_detection.rs b/rog-aura/src/aura_detection.rs index af947097..65657c52 100644 --- a/rog-aura/src/aura_detection.rs +++ b/rog-aura/src/aura_detection.rs @@ -70,7 +70,9 @@ impl LedSupportData { } } info!("Using generic LED control for keyboard brightness only"); - LedSupportData::default() + let mut data = LedSupportData::default(); + data.power_zones.push(PowerZones::Keyboard); + data } } diff --git a/rog-aura/src/keyboard/power.rs b/rog-aura/src/keyboard/power.rs index 32348b83..1033cafc 100644 --- a/rog-aura/src/keyboard/power.rs +++ b/rog-aura/src/keyboard/power.rs @@ -53,7 +53,8 @@ impl AuraPowerState { } fn tuf_to_bytes(&self) -> Vec { - todo!("0s and 1s for bool array") + // &cmd, &boot, &awake, &sleep, &keyboard + vec![1, self.boot as u8, self.awake as u8, self.sleep as u8, 1] } /// # Bits for older 0x1866 keyboard model