From 0449a4b06b365664674081cf85c9fa0acfba5a56 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Mon, 22 Mar 2021 10:24:28 +1300 Subject: [PATCH 1/3] Initial cleanup --- daemon/src/ctrl_leds.rs | 131 +++++++++++----------------------------- daemon/src/daemon.rs | 8 +-- daemon/src/laptops.rs | 43 ++----------- 3 files changed, 42 insertions(+), 140 deletions(-) diff --git a/daemon/src/ctrl_leds.rs b/daemon/src/ctrl_leds.rs index c5531974..998a8450 100644 --- a/daemon/src/ctrl_leds.rs +++ b/daemon/src/ctrl_leds.rs @@ -4,11 +4,7 @@ static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static KBD_BRIGHT_PATH: &str = "/sys/class/leds/asus::kbd_backlight/brightness"; -use crate::{ - config_aura::AuraConfig, - error::RogError, - laptops::{match_laptop, LaptopLedData, HELP_ADDRESS}, -}; +use crate::{config_aura::AuraConfig, error::RogError, laptops::{ASUS_KEYBOARD_DEVICES, HELP_ADDRESS, LaptopLedData, laptop_data}}; use log::{error, info, warn}; use rog_types::{ aura_modes::{AuraEffect, AuraModeNum}, @@ -37,16 +33,14 @@ impl GetSupported for CtrlKbdBacklight { fn get_supported() -> Self::A { // let mode = <&str>::from(&::from(*mode)); - let mut stock_led_modes = None; let multizone_led_mode = false; let per_key_led_mode = false; - if let Some(laptop) = match_laptop() { - stock_led_modes = if laptop.supported_modes().standard.is_empty() { - None - } else { - Some(laptop.supported_modes().standard.clone()) - }; - } + let laptop = laptop_data(); + let stock_led_modes = if laptop.supported_modes().standard.is_empty() { + None + } else { + Some(laptop.supported_modes().standard.clone()) + }; LedSupportedFunctions { brightness_set: CtrlKbdBacklight::get_kbd_bright_path().is_ok(), @@ -59,8 +53,6 @@ impl GetSupported for CtrlKbdBacklight { pub struct CtrlKbdBacklight { led_node: Option, - #[allow(dead_code)] - kbd_node: Option, pub bright_node: String, supported_modes: LaptopLedData, flip_effect_write: bool, @@ -258,46 +250,39 @@ impl crate::CtrlTask for CtrlKbdBacklight { impl CtrlKbdBacklight { #[inline] - pub fn new( - id_product: &str, - condev_iface: Option<&String>, - supported_modes: LaptopLedData, - config: AuraConfig, - ) -> Result { + pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result { // TODO: return error if *all* nodes are None - let led_node = Self::get_node_failover(id_product, None, Self::scan_led_node).map_or_else( - |err| { - warn!("led_node: {}", err); - None - }, - Some, - ); + let mut led_node = None; + for prod in ASUS_KEYBOARD_DEVICES.iter() { + match Self::get_node_failover(prod, Self::scan_led_node) { + Ok(node) => { + led_node = Some(node); + break; + } + Err(err) => warn!("led_node: {}", err), + } + } - let kbd_node = Self::get_node_failover(id_product, condev_iface, Self::scan_kbd_node) - .map_or_else( - |err| { - warn!("kbd_node: {}", err); - None - }, - Some, - ); + let bright_node = Self::get_kbd_bright_path().map_or_else(|_| None, Some); - let bright_node = Self::get_kbd_bright_path(); - - if led_node.is_none() && kbd_node.is_none() && Self::get_kbd_bright_path().is_err() { + if led_node.is_none() && bright_node.is_none() { return Err(RogError::MissingFunction( "All keyboard features missing, you may require a v5.11 series kernel or newer" .into(), )); } + if bright_node.is_none() { + return Err(RogError::MissingFunction( + "No brightness control, you may require a v5.11 series kernel or newer" + .into(), + )); + } + + let ctrl = CtrlKbdBacklight { - // Using `ok` here so we can continue without keyboard features but - // still get brightness control at least... maybe... led_node, - kbd_node, - // TODO: Check for existance - bright_node: bright_node?.to_owned(), + bright_node: bright_node.unwrap(), // If was none then we already returned above supported_modes, flip_effect_write: false, config, @@ -305,9 +290,9 @@ impl CtrlKbdBacklight { Ok(ctrl) } - fn get_kbd_bright_path() -> Result<&'static str, RogError> { + fn get_kbd_bright_path() -> Result { if Path::new(KBD_BRIGHT_PATH).exists() { - Ok(KBD_BRIGHT_PATH) + Ok(KBD_BRIGHT_PATH.to_string()) } else { Err(RogError::MissingFunction( "Keyboard features missing, you may require a v5.11 series kernel or newer".into(), @@ -348,19 +333,18 @@ impl CtrlKbdBacklight { fn get_node_failover( id_product: &str, - iface: Option<&String>, - fun: fn(&str, Option<&String>) -> Result, + fun: fn(&str) -> Result, ) -> Result { - match fun(id_product, iface) { + match fun(id_product) { Ok(o) => return Ok(o), Err(e) => { warn!("Looking for node: {}", e.to_string()); } } - Err(RogError::NotFound(format!("{}, {:?}", id_product, iface))) + Err(RogError::NotFound(format!("{}", id_product))) } - fn scan_led_node(id_product: &str, _: Option<&String>) -> Result { + fn scan_led_node(id_product: &str) -> Result { let mut enumerator = udev::Enumerator::new().map_err(|err| { warn!("{}", err); RogError::Udev("enumerator failed".into(), err) @@ -399,51 +383,6 @@ impl CtrlKbdBacklight { )) } - fn scan_kbd_node(id_product: &str, iface: Option<&String>) -> Result { - let mut enumerator = udev::Enumerator::new().map_err(|err| { - warn!("{}", err); - RogError::Udev("enumerator failed".into(), err) - })?; - enumerator.match_subsystem("input").map_err(|err| { - warn!("{}", err); - RogError::Udev("match_subsystem failed".into(), err) - })?; - enumerator - .match_property("ID_MODEL_ID", id_product) - .map_err(|err| { - warn!("{}", err); - RogError::Udev("match_property failed".into(), err) - })?; - - for device in enumerator - .scan_devices() - .map_err(|err| { - warn!("{}", err); - err - }) - .map_err(|err| { - warn!("{}", err); - RogError::Udev("scan_devices failed".into(), err) - })? - { - if let Some(dev_node) = device.devnode() { - if let Some(inum) = device.property_value("ID_USB_INTERFACE_NUM") { - if let Some(iface) = iface { - if inum == iface.as_str() { - info!("Using device at: {:?} for keyboard polling", dev_node); - return Ok(dev_node.to_string_lossy().to_string()); - } - } - } - } - } - - warn!("Did not find keyboard consumer device node, if expected functions are missing please file an issue at {}", HELP_ADDRESS); - Err(RogError::MissingFunction( - "ASUS keyboard 'Consumer Device' node not found".into(), - )) - } - pub(crate) fn do_command(&mut self, mode: AuraEffect) -> Result<(), RogError> { self.set_and_save(mode) } diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index 10accc2d..ffab3392 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -1,6 +1,5 @@ -use daemon::ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu}; +use daemon::{ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu}, laptops::laptop_data}; use daemon::ctrl_leds::{CtrlKbdBacklight, DbusKbdBacklight}; -use daemon::laptops::match_laptop; use daemon::{ config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported, }; @@ -136,12 +135,11 @@ fn start_daemon() -> Result<(), Box> { DbusFanAndCpu::new(tmp).add_to_server(&mut object_server); }; - if let Some(laptop) = match_laptop() { + let laptop = laptop_data(); + if !laptop.supported_modes().standard.is_empty() { let aura_config = AuraConfig::load(laptop.supported_modes()); if let Ok(ctrl) = CtrlKbdBacklight::new( - laptop.usb_product(), - laptop.condev_iface(), laptop.supported_modes().to_owned(), aura_config, ) diff --git a/daemon/src/laptops.rs b/daemon/src/laptops.rs index 366f4d0a..499d94ad 100644 --- a/daemon/src/laptops.rs +++ b/daemon/src/laptops.rs @@ -4,63 +4,28 @@ use serde_derive::{Deserialize, Serialize}; use std::fs::OpenOptions; use std::io::Read; -pub static LEDMODE_CONFIG_PATH: &str = "/etc/asusd/asusd-ledmodes.toml"; -pub static HELP_ADDRESS: &str = "https://gitlab.com/asus-linux/asus-nb-ctrl"; -static LAPTOP_DEVICES: [u16; 4] = [0x1866, 0x1869, 0x1854, 0x19b6]; +pub const LEDMODE_CONFIG_PATH: &str = "/etc/asusd/asusd-ledmodes.toml"; +pub const HELP_ADDRESS: &str = "https://gitlab.com/asus-linux/asus-nb-ctrl"; +pub const ASUS_KEYBOARD_DEVICES: [&str; 4] = ["0x1866", "0x1869", "0x1854", "0x19b6"]; /// A helper of sorts specifically for functions tied to laptop models #[derive(Debug)] pub struct LaptopBase { - usb_product: String, - condev_iface: Option, // required for finding the Consumer Device interface led_support: LaptopLedData, } impl LaptopBase { - pub fn usb_product(&self) -> &str { - &self.usb_product - } - pub fn condev_iface(&self) -> Option<&String> { - self.condev_iface.as_ref() - } pub fn supported_modes(&self) -> &LaptopLedData { &self.led_support } } -pub fn match_laptop() -> Option { - for device in rusb::devices().expect("Couldn't get device").iter() { - let device_desc = device - .device_descriptor() - .expect("Couldn't get device descriptor"); - if device_desc.vendor_id() == 0x0b05 && LAPTOP_DEVICES.contains(&device_desc.product_id()) { - let prod_str = format!("{:x?}", device_desc.product_id()); - - if device_desc.product_id() == 0x1854 { - let laptop = laptop(prod_str, None); - return Some(laptop); - } - - let laptop = laptop(prod_str, Some("02".to_owned())); - return Some(laptop); - } - } - warn!( - "Unsupported laptop, please request support at {}", - HELP_ADDRESS - ); - warn!("Continuing with minimal support"); - None -} - -fn laptop(prod: String, condev_iface: Option) -> LaptopBase { +pub fn laptop_data() -> LaptopBase { let dmi = sysfs_class::DmiId::default(); let board_name = dmi.board_name().expect("Could not get board_name"); let prod_family = dmi.product_family().expect("Could not get product_family"); let mut laptop = LaptopBase { - usb_product: prod, - condev_iface, led_support: LaptopLedData { board_names: vec![], prod_family: String::new(), From 7a51cd1c70ef9370c0afb35c58b123c71c918034 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Mon, 22 Mar 2021 10:52:14 +1300 Subject: [PATCH 2/3] Cleaned up --- daemon/src/ctrl_leds.rs | 53 +++++++++++++-------------------- daemon/src/daemon.rs | 12 ++++---- daemon/src/laptops.rs | 66 +++++++++++++---------------------------- 3 files changed, 48 insertions(+), 83 deletions(-) diff --git a/daemon/src/ctrl_leds.rs b/daemon/src/ctrl_leds.rs index 998a8450..3ad7daee 100644 --- a/daemon/src/ctrl_leds.rs +++ b/daemon/src/ctrl_leds.rs @@ -4,7 +4,11 @@ static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static KBD_BRIGHT_PATH: &str = "/sys/class/leds/asus::kbd_backlight/brightness"; -use crate::{config_aura::AuraConfig, error::RogError, laptops::{ASUS_KEYBOARD_DEVICES, HELP_ADDRESS, LaptopLedData, laptop_data}}; +use crate::{ + config_aura::AuraConfig, + error::RogError, + laptops::{LaptopLedData, ASUS_KEYBOARD_DEVICES}, +}; use log::{error, info, warn}; use rog_types::{ aura_modes::{AuraEffect, AuraModeNum}, @@ -35,15 +39,19 @@ impl GetSupported for CtrlKbdBacklight { // let mode = <&str>::from(&::from(*mode)); let multizone_led_mode = false; let per_key_led_mode = false; - let laptop = laptop_data(); - let stock_led_modes = if laptop.supported_modes().standard.is_empty() { - None + let laptop = LaptopLedData::get_data(); + let stock_led_modes = if let Some(data) = laptop { + if data.standard.is_empty() { + None + } else { + Some(data.standard) + } } else { - Some(laptop.supported_modes().standard.clone()) + None }; LedSupportedFunctions { - brightness_set: CtrlKbdBacklight::get_kbd_bright_path().is_ok(), + brightness_set: CtrlKbdBacklight::get_kbd_bright_path().is_some(), stock_led_modes, multizone_led_mode, per_key_led_mode, @@ -254,7 +262,7 @@ impl CtrlKbdBacklight { // TODO: return error if *all* nodes are None let mut led_node = None; for prod in ASUS_KEYBOARD_DEVICES.iter() { - match Self::get_node_failover(prod, Self::scan_led_node) { + match Self::find_led_node(prod) { Ok(node) => { led_node = Some(node); break; @@ -263,7 +271,7 @@ impl CtrlKbdBacklight { } } - let bright_node = Self::get_kbd_bright_path().map_or_else(|_| None, Some); + let bright_node = Self::get_kbd_bright_path(); if led_node.is_none() && bright_node.is_none() { return Err(RogError::MissingFunction( @@ -274,11 +282,9 @@ impl CtrlKbdBacklight { if bright_node.is_none() { return Err(RogError::MissingFunction( - "No brightness control, you may require a v5.11 series kernel or newer" - .into(), + "No brightness control, you may require a v5.11 series kernel or newer".into(), )); } - let ctrl = CtrlKbdBacklight { led_node, @@ -290,14 +296,11 @@ impl CtrlKbdBacklight { Ok(ctrl) } - fn get_kbd_bright_path() -> Result { + fn get_kbd_bright_path() -> Option { if Path::new(KBD_BRIGHT_PATH).exists() { - Ok(KBD_BRIGHT_PATH.to_string()) - } else { - Err(RogError::MissingFunction( - "Keyboard features missing, you may require a v5.11 series kernel or newer".into(), - )) + return Some(KBD_BRIGHT_PATH.to_string()); } + None } pub fn get_brightness(&self) -> Result { @@ -331,20 +334,7 @@ impl CtrlKbdBacklight { Ok(()) } - fn get_node_failover( - id_product: &str, - fun: fn(&str) -> Result, - ) -> Result { - match fun(id_product) { - Ok(o) => return Ok(o), - Err(e) => { - warn!("Looking for node: {}", e.to_string()); - } - } - Err(RogError::NotFound(format!("{}", id_product))) - } - - fn scan_led_node(id_product: &str) -> Result { + fn find_led_node(id_product: &str) -> Result { let mut enumerator = udev::Enumerator::new().map_err(|err| { warn!("{}", err); RogError::Udev("enumerator failed".into(), err) @@ -377,7 +367,6 @@ impl CtrlKbdBacklight { } } } - warn!("Did not find a hidraw node for LED control, your device may be unsupported or require a kernel patch, see: {}", HELP_ADDRESS); Err(RogError::MissingFunction( "ASUS LED device node not found".into(), )) diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index ffab3392..ac5a22a3 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -1,4 +1,4 @@ -use daemon::{ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu}, laptops::laptop_data}; +use daemon::{ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu}, laptops::LaptopLedData}; use daemon::ctrl_leds::{CtrlKbdBacklight, DbusKbdBacklight}; use daemon::{ config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported, @@ -135,12 +135,12 @@ fn start_daemon() -> Result<(), Box> { DbusFanAndCpu::new(tmp).add_to_server(&mut object_server); }; - let laptop = laptop_data(); - if !laptop.supported_modes().standard.is_empty() { - let aura_config = AuraConfig::load(laptop.supported_modes()); + if let Some(laptop) = LaptopLedData::get_data() { + if !laptop.standard.is_empty() { + let aura_config = AuraConfig::load(&laptop); if let Ok(ctrl) = CtrlKbdBacklight::new( - laptop.supported_modes().to_owned(), + laptop, aura_config, ) .map_err(|err| { @@ -151,7 +151,7 @@ fn start_daemon() -> Result<(), Box> { DbusKbdBacklight::new(tmp.clone()).add_to_server(&mut object_server); tasks.push(tmp); } - } + }} // TODO: implement messaging between threads to check fails // These tasks generally read a sys path or file to check for a diff --git a/daemon/src/laptops.rs b/daemon/src/laptops.rs index 499d94ad..b8929a53 100644 --- a/daemon/src/laptops.rs +++ b/daemon/src/laptops.rs @@ -4,45 +4,8 @@ use serde_derive::{Deserialize, Serialize}; use std::fs::OpenOptions; use std::io::Read; -pub const LEDMODE_CONFIG_PATH: &str = "/etc/asusd/asusd-ledmodes.toml"; -pub const HELP_ADDRESS: &str = "https://gitlab.com/asus-linux/asus-nb-ctrl"; -pub const ASUS_KEYBOARD_DEVICES: [&str; 4] = ["0x1866", "0x1869", "0x1854", "0x19b6"]; - -/// A helper of sorts specifically for functions tied to laptop models -#[derive(Debug)] -pub struct LaptopBase { - led_support: LaptopLedData, -} - -impl LaptopBase { - pub fn supported_modes(&self) -> &LaptopLedData { - &self.led_support - } -} - -pub fn laptop_data() -> LaptopBase { - let dmi = sysfs_class::DmiId::default(); - let board_name = dmi.board_name().expect("Could not get board_name"); - let prod_family = dmi.product_family().expect("Could not get product_family"); - - let mut laptop = LaptopBase { - led_support: LaptopLedData { - board_names: vec![], - prod_family: String::new(), - standard: vec![], - multizone: false, - per_key: false, - }, - }; - - if let Some(modes) = LedSupportFile::load_from_config() { - if let Some(led_modes) = modes.matcher(&prod_family, &board_name) { - laptop.led_support = led_modes; - return laptop; - } - } - laptop -} +pub const ASUS_LED_MODE_CONF: &str = "/etc/asusd/asusd-ledmodes.toml"; +pub const ASUS_KEYBOARD_DEVICES: [&str; 4] = ["1866", "1869", "1854", "19b6"]; pub fn print_board_info() { let dmi = sysfs_class::DmiId::default(); @@ -63,8 +26,8 @@ pub fn print_modes(supported_modes: &[u8]) { info!("- {}", mode); } info!( - "If these modes are incorrect or missing please request support at {}", - HELP_ADDRESS + "If these modes are incorrect you can edit {}", + ASUS_LED_MODE_CONF ); } else { info!("No RGB control available"); @@ -85,6 +48,19 @@ pub struct LaptopLedData { pub per_key: bool, } +impl LaptopLedData { + pub fn get_data() -> Option { + let dmi = sysfs_class::DmiId::default(); + let board_name = dmi.board_name().expect("Could not get board_name"); + let prod_family = dmi.product_family().expect("Could not get product_family"); + + if let Some(modes) = LedSupportFile::load_from_config() { + return modes.matcher(&prod_family, &board_name); + } + None + } +} + impl LedSupportFile { /// Consumes the LEDModes fn matcher(self, prod_family: &str, board_name: &str) -> Option { @@ -102,19 +78,19 @@ impl LedSupportFile { } fn load_from_config() -> Option { - if let Ok(mut file) = OpenOptions::new().read(true).open(&LEDMODE_CONFIG_PATH) { + if let Ok(mut file) = OpenOptions::new().read(true).open(&ASUS_LED_MODE_CONF) { let mut buf = String::new(); if let Ok(l) = file.read_to_string(&mut buf) { if l == 0 { - warn!("{} is empty", LEDMODE_CONFIG_PATH); + warn!("{} is empty", ASUS_LED_MODE_CONF); } else { return Some(toml::from_str(&buf).unwrap_or_else(|_| { - panic!("Could not deserialise {}", LEDMODE_CONFIG_PATH) + panic!("Could not deserialise {}", ASUS_LED_MODE_CONF) })); } } } - warn!("Does {} exist?", LEDMODE_CONFIG_PATH); + warn!("Does {} exist?", ASUS_LED_MODE_CONF); None } } From 03b338bdfa66c9b1fe852b7f6aa0ce50f2cbf132 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Mon, 22 Mar 2021 14:09:27 +1300 Subject: [PATCH 3/3] Strongly type the Led brightness --- asusctl/src/aura_cli.rs | 6 +++--- asusctl/src/main.rs | 10 ++-------- daemon/src/config_aura.rs | 32 ++++++++++++++++++++++++++++---- daemon/src/ctrl_leds.rs | 18 ++++++++---------- rog-dbus/src/zbus_led.rs | 6 +++--- rog-types/src/aura_modes.rs | 26 ++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/asusctl/src/aura_cli.rs b/asusctl/src/aura_cli.rs index c0326373..47138b6a 100644 --- a/asusctl/src/aura_cli.rs +++ b/asusctl/src/aura_cli.rs @@ -7,14 +7,14 @@ use std::str::FromStr; #[derive(Options)] pub struct LedBrightness { - level: Option, + level: Option, } impl LedBrightness { - pub fn new(level: Option) -> Self { + pub fn new(level: Option) -> Self { LedBrightness { level } } - pub fn level(&self) -> Option { + pub fn level(&self) -> Option { self.level } } diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index ec0c6ee6..a5dbba59 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -7,13 +7,7 @@ use daemon::{ }; use gumdrop::{Opt, Options}; use rog_dbus::AuraDbusClient; -use rog_types::{ - anime_matrix::{AniMeDataBuffer, FULL_PANE_LEN}, - aura_modes::{AuraEffect, AuraModeNum}, - cli_options::{AniMeActions, AniMeStatusValue}, - gfx_vendors::GfxVendors, - profile::{FanLevel, ProfileCommand, ProfileEvent}, -}; +use rog_types::{anime_matrix::{AniMeDataBuffer, FULL_PANE_LEN}, aura_modes::{self, AuraEffect, AuraModeNum}, cli_options::{AniMeActions, AniMeStatusValue}, gfx_vendors::GfxVendors, profile::{FanLevel, ProfileCommand, ProfileEvent}}; use std::env::args; use yansi_term::Colour::Green; use yansi_term::Colour::Red; @@ -202,7 +196,7 @@ fn main() -> Result<(), Box> { let level = dbus.proxies().led().get_led_brightness()?; println!("Current keyboard led brightness: {}", level.to_string()); } - Some(level) => dbus.proxies().led().set_led_brightness(level)?, + Some(level) => dbus.proxies().led().set_led_brightness(::from(level))?, } } diff --git a/daemon/src/config_aura.rs b/daemon/src/config_aura.rs index 55b6696b..2705bcd0 100644 --- a/daemon/src/config_aura.rs +++ b/daemon/src/config_aura.rs @@ -1,6 +1,6 @@ use crate::laptops::LaptopLedData; -use log::{error, warn}; -use rog_types::aura_modes::{AuraEffect, AuraModeNum, AuraMultiZone, AuraZone}; +use log::{error, info, warn}; +use rog_types::aura_modes::{AuraEffect, AuraModeNum, AuraMultiZone, AuraZone, LedBrightness}; use serde_derive::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::fs::{File, OpenOptions}; @@ -8,9 +8,28 @@ use std::io::{Read, Write}; pub static AURA_CONFIG_PATH: &str = "/etc/asusd/aura.conf"; +#[derive(Deserialize, Serialize)] +pub struct AuraConfigV320 { + pub brightness: u32, + pub current_mode: AuraModeNum, + pub builtins: BTreeMap, + pub multizone: Option, +} + +impl AuraConfigV320 { + pub(crate) fn into_current(self) -> AuraConfig { + AuraConfig { + brightness: ::from(self.brightness), + current_mode: self.current_mode, + builtins: self.builtins, + multizone: self.multizone, + } + } +} + #[derive(Deserialize, Serialize)] pub struct AuraConfig { - pub brightness: u8, + pub brightness: LedBrightness, pub current_mode: AuraModeNum, pub builtins: BTreeMap, pub multizone: Option, @@ -19,7 +38,7 @@ pub struct AuraConfig { impl Default for AuraConfig { fn default() -> Self { AuraConfig { - brightness: 1, + brightness: LedBrightness::Med, current_mode: AuraModeNum::Static, builtins: BTreeMap::new(), multizone: None, @@ -48,6 +67,11 @@ impl AuraConfig { } else { if let Ok(data) = serde_json::from_str(&buf) { return data; + } else if let Ok(data) = serde_json::from_str::(&buf) { + let config = data.into_current(); + config.write(); + info!("Updated AuraConfig version"); + return config; } warn!("Could not deserialise {}", AURA_CONFIG_PATH); panic!("Please remove {} then restart asusd", AURA_CONFIG_PATH); diff --git a/daemon/src/ctrl_leds.rs b/daemon/src/ctrl_leds.rs index 3ad7daee..867ae00f 100644 --- a/daemon/src/ctrl_leds.rs +++ b/daemon/src/ctrl_leds.rs @@ -10,10 +10,7 @@ use crate::{ laptops::{LaptopLedData, ASUS_KEYBOARD_DEVICES}, }; use log::{error, info, warn}; -use rog_types::{ - aura_modes::{AuraEffect, AuraModeNum}, - LED_MSG_LEN, -}; +use rog_types::{LED_MSG_LEN, aura_modes::{AuraEffect, AuraModeNum, LedBrightness}}; use std::fs::OpenOptions; use std::io::{Read, Write}; use std::path::Path; @@ -99,7 +96,7 @@ impl crate::ZbusAdd for DbusKbdBacklight { /// LED commands are split between Brightness, Modes, Per-Key #[dbus_interface(name = "org.asuslinux.Daemon")] impl DbusKbdBacklight { - fn set_brightness(&mut self, brightness: u8) { + fn set_brightness(&mut self, brightness: LedBrightness) { if let Ok(ctrl) = self.inner.try_lock() { ctrl.set_brightness(brightness) .map_err(|err| warn!("{}", err)) @@ -245,9 +242,9 @@ impl crate::CtrlTask for CtrlKbdBacklight { file.read_exact(&mut buf) .map_err(|err| RogError::Read("buffer".into(), err))?; if let Some(num) = char::from(buf[0]).to_digit(10) { - if self.config.brightness != num as u8 { + if self.config.brightness != num.into() { self.config.read(); - self.config.brightness = num as u8; + self.config.brightness = num.into(); self.config.write(); } return Ok(()); @@ -319,17 +316,18 @@ impl CtrlKbdBacklight { Ok(buf[0]) } - pub fn set_brightness(&self, brightness: u8) -> Result<(), RogError> { + pub fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> { + let path = Path::new(&self.bright_node); let mut file = OpenOptions::new() .write(true) - .open(&self.bright_node) + .open(&path) .map_err(|err| match err.kind() { std::io::ErrorKind::NotFound => { RogError::MissingLedBrightNode((&self.bright_node).into(), err) } _ => RogError::Path((&self.bright_node).into(), err), })?; - file.write_all(&[brightness]) + file.write_all(&[brightness.as_char_code()]) .map_err(|err| RogError::Read("buffer".into(), err))?; Ok(()) } diff --git a/rog-dbus/src/zbus_led.rs b/rog-dbus/src/zbus_led.rs index cd016531..37b3c641 100644 --- a/rog-dbus/src/zbus_led.rs +++ b/rog-dbus/src/zbus_led.rs @@ -23,7 +23,7 @@ use std::sync::{Arc, Mutex}; use zbus::{dbus_proxy, Connection, Result}; -use rog_types::{aura_modes::AuraEffect, aura_perkey::KeyColourArray}; +use rog_types::{aura_modes::{AuraEffect, LedBrightness}, aura_perkey::KeyColourArray}; const BLOCKING_TIME: u64 = 40; // 100ms = 10 FPS, max 50ms = 20 FPS, 40ms = 25 FPS @@ -39,7 +39,7 @@ trait Daemon { fn prev_led_mode(&self) -> zbus::Result<()>; /// SetBrightness method - fn set_brightness(&self, brightness: u8) -> zbus::Result<()>; + fn set_brightness(&self, brightness: LedBrightness) -> zbus::Result<()>; /// SetLedMode method fn set_led_mode(&self, effect: &AuraEffect) -> zbus::Result<()>; @@ -80,7 +80,7 @@ impl<'a> LedProxy<'a> { } #[inline] - pub fn set_led_brightness(&self, level: u8) -> Result<()> { + pub fn set_led_brightness(&self, level: LedBrightness) -> Result<()> { self.0.set_brightness(level)?; Ok(()) } diff --git a/rog-types/src/aura_modes.rs b/rog-types/src/aura_modes.rs index 42ed78da..b15ed514 100644 --- a/rog-types/src/aura_modes.rs +++ b/rog-types/src/aura_modes.rs @@ -10,6 +10,32 @@ use serde_derive::{Deserialize, Serialize}; use std::str::FromStr; use zvariant_derive::Type; +#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize, Type)] +pub enum LedBrightness { + Off, + Low, + Med, + High, +} + +impl LedBrightness { + pub fn as_char_code(&self) -> u8 { + std::char::from_digit(*self as u32, 10).unwrap() as u8 + } +} + +impl From for LedBrightness { + fn from(bright: u32) -> Self { + match bright { + 0 => LedBrightness::Off, + 1 => LedBrightness::Low, + 2 => LedBrightness::Med, + 3 => LedBrightness::High, + _ => LedBrightness::Med, + } + } +} + #[derive(Debug, Clone, PartialEq, Copy, Deserialize, Serialize, Type)] pub struct Colour(pub u8, pub u8, pub u8);