use serde::{Deserialize, Serialize}; use std::ops::{BitAnd, BitOr}; #[cfg(feature = "dbus")] use zbus::zvariant::Type; pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9]; pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d pub const LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08]; pub const LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e pub const LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08]; // Only these two packets must be 17 bytes pub const LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; pub const LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; /// Writes out the correct byte string for brightness pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] { [ 0x5A, 0xBA, 0xC5, 0xC4, brightness, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } #[cfg_attr(feature = "dbus", derive(Type))] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Serialize, Deserialize, Default)] pub enum AuraDevice { Tuf, X1854, X1869, X1866, #[default] X19B6, Unknown, } impl From<&str> for AuraDevice { fn from(s: &str) -> Self { match s.to_lowercase().as_str() { "tuf" => AuraDevice::Tuf, "1866" | "0x1866" => AuraDevice::X1866, "1869" | "0x1869" => AuraDevice::X1869, "1854" | "0x1854" => AuraDevice::X1854, "19b6" | "0x19b6" => AuraDevice::X19B6, _ => AuraDevice::Unknown, } } } /// This struct is intended as a helper to pass args to generic dbus interface #[cfg_attr(feature = "dbus", derive(Type))] #[derive(Clone, Default, Debug, Serialize, Deserialize)] pub struct AuraPowerDev { pub tuf: Vec, pub x1866: Vec, pub x19b6: Vec, } #[cfg_attr(feature = "dbus", derive(Type))] #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] #[repr(u32)] pub enum AuraDevTuf { Boot, Awake, Sleep, Keyboard, } impl AuraDevTuf { pub const fn dev_id() -> &'static str { "tuf" } } /// # Bits for older 0x1866 keyboard model /// /// Keybord and Lightbar require Awake, Boot and Sleep apply to both /// Keybord and Lightbar regardless of if either are enabled (or Awake is enabled) /// /// | Byte 1 | Byte 2 | Byte 3 | function | hex | /// |------------|------------|------------|----------|----------| /// | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 | /// | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 | /// | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 | /// | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 | /// | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 | /// | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | | /// #[cfg_attr(feature = "dbus", derive(Type))] #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] #[repr(u32)] pub enum AuraDev1866 { Awake = 0x000002, Keyboard = 0x080000, Lightbar = 0x040500, Boot = 0xc31209, Sleep = 0x300804, } impl From for u32 { fn from(a: AuraDev1866) -> Self { a as u32 } } impl AuraDev1866 { pub fn to_bytes(control: &[Self]) -> [u8; 3] { let mut a: u32 = 0; for n in control { a |= *n as u32; } [ ((a & 0xff0000) >> 16) as u8, ((a & 0xff00) >> 8) as u8, (a & 0xff) as u8, ] } pub const fn dev_id() -> &'static str { "0x1866" } } impl BitOr for AuraDev1866 { type Output = u32; fn bitor(self, rhs: AuraDev1866) -> Self::Output { self as u32 | rhs as u32 } } impl BitAnd for AuraDev1866 { type Output = u32; fn bitand(self, rhs: AuraDev1866) -> Self::Output { self as u32 & rhs as u32 } } /// # Bits for 0x19b6 keyboard model /// /// byte 4 in the USB packet is for keyboard + logo power states /// default is on, `ff` /// Keyboard and logo use the full range of bits (almost) /// /// | n1 | n2 | hex | action | bit | /// |------|------|-----|-----------------------|-------| /// | 0000 | 0000 | 00 | all off | | /// | 0000 | 0001 | 01 | logo boot | bit 1 | /// | 0000 | 0010 | 02 | keyboard boot | bit 2 | /// | 0000 | 0100 | 04 | logo awake | bit 3 | /// | 0000 | 1000 | 08 | keyboard awake | bit 4 | /// | 0001 | 0000 | 10 | logo sleep off | bit 5 | /// | 0010 | 0000 | 20 | keyboard sleep | bit 6 | /// | 0100 | 0000 | 40 | logo shutdown off | bit 7 | /// | 1000 | 0000 | 80 | keyboard shutdown off | bit 8 | /// /// byte 5 = lightbar /// /// | 1 | 2 | hex | action | bit | /// |------|------|-----|----------------------|-------| /// | 0000 | 0010 | 02 | lightbar off boot | bit 2 | /// | 0000 | 0100 | 04 | lightbar on | bit 3 | /// | 0000 | 1000 | 08 | lightbar off sleep | bit 4 | /// | 0001 | 0000 | 10 | lightbar shtdn off | bit 5 | /// #[cfg_attr(feature = "dbus", derive(Type))] #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)] #[repr(u32)] pub enum AuraDev19b6 { BootLogo = 1, BootKeyb = 1 << 1, AwakeLogo = 1 << 2, AwakeKeyb = 1 << 3, SleepLogo = 1 << 4, SleepKeyb = 1 << 5, ShutdownLogo = 1 << 6, ShutdownKeyb = 1 << 7, BootBar = 1 << (7 + 2), AwakeBar = 1 << (7 + 3), SleepBar = 1 << (7 + 4), ShutdownBar = 1 << (7 + 5), BootLid = 1 << (15 + 1), AwakeLid = 1 << (15 + 2), SleepLid = 1 << (15 + 3), ShutdownLid = 1 << (15 + 4), } impl From for u32 { fn from(a: AuraDev19b6) -> Self { a as u32 } } impl AuraDev19b6 { pub fn to_bytes(control: &[Self]) -> [u8; 3] { let mut a: u32 = 0; for n in control { a |= *n as u32; } [ (a & 0xff) as u8, ((a & 0xff00) >> 8) as u8, ((a & 0xff0000) >> 16) as u8, ] } pub const fn dev_id() -> &'static str { "0x196b" } } impl BitOr for AuraDev19b6 { type Output = u16; fn bitor(self, rhs: AuraDev19b6) -> Self::Output { self as u16 | rhs as u16 } } impl BitAnd for AuraDev19b6 { type Output = u16; fn bitand(self, rhs: AuraDev19b6) -> Self::Output { self as u16 & rhs as u16 } } #[cfg(test)] mod tests { use crate::usb::AuraDev19b6; use super::AuraDev1866; #[test] fn check_0x1866_control_bytes() { let bytes = [AuraDev1866::Keyboard, AuraDev1866::Awake]; let bytes = AuraDev1866::to_bytes(&bytes); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes, [0x08, 0x00, 0x02]); let bytes = [AuraDev1866::Lightbar, AuraDev1866::Awake]; let bytes = AuraDev1866::to_bytes(&bytes); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes, [0x04, 0x05, 0x02]); let bytes = [AuraDev1866::Sleep]; let bytes = AuraDev1866::to_bytes(&bytes); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes, [0x30, 0x08, 0x04]); let bytes = [AuraDev1866::Boot]; let bytes = AuraDev1866::to_bytes(&bytes); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes, [0xc3, 0x12, 0x09]); let bytes = [ AuraDev1866::Keyboard, AuraDev1866::Lightbar, AuraDev1866::Awake, AuraDev1866::Sleep, AuraDev1866::Boot, ]; let bytes = AuraDev1866::to_bytes(&bytes); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes, [0xff, 0x1f, 0x000f]); } #[test] fn check_0x19b6_control_bytes() { // All on let byte1 = [ AuraDev19b6::BootLogo, AuraDev19b6::BootKeyb, AuraDev19b6::SleepLogo, AuraDev19b6::SleepKeyb, AuraDev19b6::AwakeLogo, AuraDev19b6::AwakeKeyb, AuraDev19b6::ShutdownLogo, AuraDev19b6::ShutdownKeyb, ]; let bytes = AuraDev19b6::to_bytes(&byte1); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[0], 0xff); // let byte1 = [ // AuraControl::BootLogo, AuraDev19b6::BootKeyb, AuraDev19b6::SleepLogo, AuraDev19b6::SleepKeyb, AuraDev19b6::AwakeLogo, AuraDev19b6::AwakeKeyb, AuraDev19b6::ShutdownLogo, AuraDev19b6::ShutdownKeyb, ]; let bytes = AuraDev19b6::to_bytes(&byte1); println!("{:08b}", bytes[0]); assert_eq!(bytes[0], 0xfe); let byte1 = [ AuraDev19b6::BootLogo, // AuraControl::BootKeyb, AuraDev19b6::SleepLogo, AuraDev19b6::SleepKeyb, AuraDev19b6::AwakeLogo, AuraDev19b6::AwakeKeyb, AuraDev19b6::ShutdownLogo, AuraDev19b6::ShutdownKeyb, ]; let bytes = AuraDev19b6::to_bytes(&byte1); println!("{:08b}", bytes[0]); assert_eq!(bytes[0], 0xfd); let byte1 = [ AuraDev19b6::BootLogo, AuraDev19b6::BootKeyb, // AuraControl::SleepLogo, AuraDev19b6::SleepKeyb, AuraDev19b6::AwakeLogo, AuraDev19b6::AwakeKeyb, AuraDev19b6::ShutdownLogo, AuraDev19b6::ShutdownKeyb, ]; let bytes = AuraDev19b6::to_bytes(&byte1); println!("{:08b}", bytes[0]); assert_eq!(bytes[0], 0xef); let byte1 = [ AuraDev19b6::BootLogo, AuraDev19b6::BootKeyb, AuraDev19b6::SleepLogo, // AuraControl::SleepKeyb, AuraDev19b6::AwakeLogo, AuraDev19b6::AwakeKeyb, AuraDev19b6::ShutdownLogo, AuraDev19b6::ShutdownKeyb, ]; let bytes = AuraDev19b6::to_bytes(&byte1); println!("{:08b}", bytes[0]); assert_eq!(bytes[0], 0xdf); let byte2 = [ AuraDev19b6::BootBar, AuraDev19b6::AwakeBar, AuraDev19b6::SleepBar, AuraDev19b6::ShutdownBar, ]; let bytes = AuraDev19b6::to_bytes(&byte2); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[1], 0x1e); let byte2 = [ AuraDev19b6::BootBar, AuraDev19b6::AwakeBar, // AuraControl::SleepBar, AuraDev19b6::ShutdownBar, ]; let bytes = AuraDev19b6::to_bytes(&byte2); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[1], 0x16); let byte3 = [ AuraDev19b6::AwakeLid, AuraDev19b6::BootLid, AuraDev19b6::SleepLid, AuraDev19b6::ShutdownLid, ]; let bytes = AuraDev19b6::to_bytes(&byte3); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[2], 0x0f); let byte3 = [ //AuraDev19b6::AwakeLid, AuraDev19b6::BootLid, AuraDev19b6::SleepLid, AuraDev19b6::ShutdownLid, ]; let bytes = AuraDev19b6::to_bytes(&byte3); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[2], 0x0d); let byte3 = [ AuraDev19b6::AwakeLid, AuraDev19b6::BootLid, // AuraControl::SleepLid, AuraDev19b6::ShutdownLid, ]; let bytes = AuraDev19b6::to_bytes(&byte3); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[2], 0x0b); let byte3 = [ AuraDev19b6::AwakeLid, AuraDev19b6::BootLid, AuraDev19b6::SleepLid, //AuraDev19b6::ShutdownLid, ]; let bytes = AuraDev19b6::to_bytes(&byte3); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[2], 0x07); let byte3 = [ AuraDev19b6::AwakeLid, //AuraDev19b6::BootLid, AuraDev19b6::SleepLid, //AuraDev19b6::ShutdownLid, ]; let bytes = AuraDev19b6::to_bytes(&byte3); println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]); assert_eq!(bytes[2], 0x06); } }