From e49799e4d2fe0fb0bd0c69d5b19fa203d00ea279 Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 17 Apr 2020 12:04:01 +1200 Subject: [PATCH] Polling keyboard in daemon. Split into app/lib --- Cargo.lock | 18 +- Cargo.toml | 31 ++-- Makefile | 2 +- rog-core/Cargo.lock | 283 ++++++++++++++++++++++++++++++++ rog-core/Cargo.toml | 13 ++ {src => rog-core/src}/config.rs | 8 +- rog-core/src/daemon.rs | 112 +++++++++++++ rog-core/src/main.rs | 79 +++++++++ rog-lib/Cargo.lock | 283 ++++++++++++++++++++++++++++++++ rog-lib/Cargo.toml | 11 ++ {src => rog-lib/src}/aura.rs | 24 ++- {src => rog-lib/src}/core.rs | 42 +++-- {src => rog-lib/src}/error.rs | 4 +- rog-lib/src/lib.rs | 3 + src/daemon.rs | 68 -------- src/main.rs | 99 ----------- 16 files changed, 860 insertions(+), 220 deletions(-) create mode 100644 rog-core/Cargo.lock create mode 100644 rog-core/Cargo.toml rename {src => rog-core/src}/config.rs (90%) create mode 100644 rog-core/src/daemon.rs create mode 100644 rog-core/src/main.rs create mode 100644 rog-lib/Cargo.lock create mode 100644 rog-lib/Cargo.toml rename {src => rog-lib/src}/aura.rs (95%) rename {src => rog-lib/src}/core.rs (85%) rename {src => rog-lib/src}/error.rs (88%) create mode 100644 rog-lib/src/lib.rs delete mode 100644 src/daemon.rs delete mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock index b82af6ef..7b126692 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" [[package]] name = "libdbus-sys" @@ -163,14 +163,24 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" [[package]] name = "rog-core" -version = "0.3.0" +version = "0.3.1" dependencies = [ "dbus", + "gumdrop", + "rog-lib", + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "rog-lib" +version = "0.3.1" +dependencies = [ "gumdrop", "rusb", "serde", "serde_derive", - "toml", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ad537753..8e2f8d86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,20 @@ -[package] -name = "rog-core" -version = "0.3.1" -authors = ["Luke "] -edition = "2018" +[workspace] +members = ["rog-core", "rog-lib"] + +[profile.release] +lto = true +debug = false +opt-level = 3 +#panic = "abort" + +[profile.dev] +lto = true +debug = true +opt-level = 2 +#panic = "abort" + +[profile.bench] +lto = true +debug = false +opt-level = 3 -[dependencies] -rusb = "0.5" -gumdrop = "0.8" -dbus = "0.7.1" -serde = "1.0" -serde_derive = "1.0" -toml = "0.5" \ No newline at end of file diff --git a/Makefile b/Makefile index 3504bb51..b8d12bbc 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ includedir = $(prefix)/include datarootdir = $(prefix)/share datadir = $(datarootdir) -SRC = Cargo.toml Cargo.lock Makefile $(shell find src -type f -wholename '*src/*.rs') +SRC = Cargo.toml Cargo.lock Makefile $(shell find src -type f -wholename '*/*src/*.rs') .PHONY: all clean distclean install uninstall update diff --git a/rog-core/Cargo.lock b/rog-core/Cargo.lock new file mode 100644 index 00000000..7a837529 --- /dev/null +++ b/rog-core/Cargo.lock @@ -0,0 +1,283 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adler32" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" + +[[package]] +name = "bit-set" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" + +[[package]] +name = "cc" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "dbus" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add8dd36d6d34a084220eb9fe216d3e230d52b37c31702e1ffda4fb2d4ef950e" +dependencies = [ + "libc", + "libdbus-sys", +] + +[[package]] +name = "filetime" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "gumdrop" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46571f5d540478cf70d2a42dd0d6d8e9f4b9cc7531544b93311e657b86568a0b" +dependencies = [ + "gumdrop_derive", +] + +[[package]] +name = "gumdrop_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libc" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" + +[[package]] +name = "libdbus-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc12a3bc971424edbbf7edaf6e5740483444db63aa8e23d3751ff12a30f306f0" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "libflate" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" +dependencies = [ + "adler32", + "crc32fast", + "rle-decode-fast", + "take_mut", +] + +[[package]] +name = "libusb1-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0318f131edc8211a9a3e40133be6fc93f0b686e14f59c6115eab4e7bd794b34" +dependencies = [ + "cc", + "libc", + "libflate", + "pkg-config", + "tar", + "vcpkg", +] + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" + +[[package]] +name = "proc-macro2" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "rle-decode-fast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" + +[[package]] +name = "rog-core" +version = "0.3.1" +dependencies = [ + "dbus", + "gumdrop", + "rusb", + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "rusb" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d10caa3e5fc7ad1879a679bf16d3304ea10614b8f2f1a1386be4ec942d44062a" +dependencies = [ + "bit-set", + "libc", + "libusb1-sys", +] + +[[package]] +name = "serde" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" + +[[package]] +name = "serde_derive" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "tar" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" +dependencies = [ + "filetime", + "libc", + "redox_syscall", + "xattr", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "vcpkg" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] diff --git a/rog-core/Cargo.toml b/rog-core/Cargo.toml new file mode 100644 index 00000000..7e2b12d5 --- /dev/null +++ b/rog-core/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rog-core" +version = "0.3.1" +authors = ["Luke "] +edition = "2018" + +[dependencies] +gumdrop = "0.8" +dbus = "0.7.1" +serde = "1.0" +serde_derive = "1.0" +toml = "0.5" +rog-lib = { path = "../rog-lib" } diff --git a/src/config.rs b/rog-core/src/config.rs similarity index 90% rename from src/config.rs rename to rog-core/src/config.rs index 3c30ae85..a4c919d9 100644 --- a/src/config.rs +++ b/rog-core/src/config.rs @@ -1,7 +1,5 @@ -use crate::{ - aura::{ModeMessage, SetAuraBuiltin}, - CONFIG_PATH, -}; +use crate::CONFIG_PATH; +use rog_lib::{aura::SetAuraBuiltin, core::LED_MSG_LEN}; use serde_derive::{Deserialize, Serialize}; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; @@ -27,7 +25,7 @@ impl Config { let d = SetAuraBuiltin::default(); let c = Config { brightness: 1u8, - builtin: ModeMessage::from(d).0.to_vec(), + builtin: (<[u8; LED_MSG_LEN]>::from(d)).to_vec(), }; let toml = toml::to_string(&c).unwrap(); file.write_all(toml.as_bytes()) diff --git a/rog-core/src/daemon.rs b/rog-core/src/daemon.rs new file mode 100644 index 00000000..3af31742 --- /dev/null +++ b/rog-core/src/daemon.rs @@ -0,0 +1,112 @@ +use crate::{config::Config, DBUS_IFACE, DBUS_PATH}; +use dbus::{ + blocking::Connection, + tree::{Factory, MethodErr}, +}; +use rog_lib::core::RogCore; +use std::error::Error; +use std::time::Duration; +use std::{cell::RefCell, rc::Rc}; + +pub struct Daemon { + rogcore: RogCore, + config: Config, +} + +impl Daemon { + pub fn new() -> Self { + Daemon { + rogcore: RogCore::new().expect("Could not start RogCore"), + config: Config::default().read(), + } + } + + pub fn load_config(mut self) -> Result> { + self.rogcore.aura_set_mode(&self.config.builtin)?; + let bright = RogCore::aura_brightness_bytes(self.config.brightness)?; + self.rogcore.aura_set_mode(&bright)?; + Ok(self) + } + + pub fn write_config(&mut self, bytes: &[u8]) { + // TODO: create statics out of header bytes + if bytes[0] == 0x5a && bytes[1] == 0xba { + self.config.brightness = bytes[4]; + } else if bytes[0] == 0x5d && bytes[1] == 0xb3 { + self.config.builtin = bytes.to_vec(); + } + self.config.write(); + } + + pub fn start() -> Result<(), Box> { + let mut connection = Connection::new_system().expect("Could not set up dbus system"); + connection.request_name(DBUS_IFACE, false, true, false)?; + let factory = Factory::new_fnmut::<()>(); + + let daemon = Self::new().load_config()?; + let daemon = Rc::new(RefCell::new(daemon)); + + // We create a tree with one object path inside and make that path introspectable. + let tree = factory.tree(()).add( + factory.object_path(DBUS_PATH, ()).introspectable().add( + // We add an interface to the object path... + factory + .interface(DBUS_IFACE, ()) + // ...and a method inside the interface + .add_m( + factory + .method("ledmessage", (), { + let daemon = daemon.clone(); + move |m| { + // Reads the args passed to the method + let bytes: Vec = m.msg.read1()?; + let s = format!("Wrote {:x?}", bytes); + + let mut daemon = daemon.borrow_mut(); + match daemon.rogcore.aura_set_mode(&bytes[..]) { + Ok(_) => { + daemon.write_config(&bytes); + let mret = m.msg.method_return().append1(s); + Ok(vec![mret]) + } + Err(err) => Err(MethodErr::failed(&err)), + } + } + }) + // Input? + .outarg::<&str, _>("reply") + .inarg::, _>("bytearray"), + ), + ), + ); + + // We add the tree to the connection so that incoming method calls will be handled. + tree.start_receive(&connection); + + loop { + connection.process(Duration::from_millis(5))?; + // READ KEYBOARD + // TODO: this needs to move to a thread + match daemon.borrow_mut().rogcore.poll_keyboard() { + Ok(buf) => { + // [5d, 1, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] up + // [5d, 1, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] down + // [5d, 1, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] left + // [5d, 1, 0, 0, 4f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] right + + // [5a, c4, ; 32 bytes long] fn+up + // [5a, c5, ; 32 bytes long] fn+down + // [5a, b2, ; 32 bytes long] fn+left + // [5a, b3, ; 32 bytes long] fn+right + + // To handle keys for aura: + // read config + inc/dec brightness byte + // write to aura + // write config + println!("{:x?}", buf); + } + Err(err) => println!("{:?}", err), + } + } + } +} diff --git a/rog-core/src/main.rs b/rog-core/src/main.rs new file mode 100644 index 00000000..e1ac6fb0 --- /dev/null +++ b/rog-core/src/main.rs @@ -0,0 +1,79 @@ +// TODO: use /sys/class/dmi/id/board_name to detect model +mod config; +mod daemon; + +use crate::daemon::*; +use dbus::Error as DbusError; +use dbus::{ffidisp::Connection, Message}; +use gumdrop::Options; +use rog_lib::aura::*; +use rog_lib::core::{LedBrightness, RogCore, LED_MSG_LEN}; + +pub static DBUS_NAME: &'static str = "org.rogcore.Daemon"; +pub static DBUS_PATH: &'static str = "/org/rogcore/Daemon"; +pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon"; +pub static CONFIG_PATH: &'static str = "/etc/rogcore.conf"; + +#[derive(Debug, Options)] +struct CLIStart { + #[options(help = "print help message")] + help: bool, + #[options(help = "start daemon")] + daemon: bool, + #[options(meta = "VAL", help = "")] + bright: Option, + #[options(command)] + command: Option, +} + +#[derive(Debug, Options)] +enum Command { + #[options(help = "Set the keyboard lighting from built-in modes")] + LedMode(LedModeCommand), +} + +#[derive(Debug, Options)] +struct LedModeCommand { + #[options(help = "print help message")] + help: bool, + #[options(command, required)] + command: Option, +} + +fn main() -> Result<(), Box> { + let parsed = CLIStart::parse_args_default_or_exit(); + if parsed.daemon { + Daemon::start()?; + } + + match parsed.command { + Some(Command::LedMode(mode)) => { + if let Some(command) = mode.command { + let mode = <[u8; LED_MSG_LEN]>::from(command); + dbus_led_builtin_write(&mode)?; + } + } + None => {} + } + match parsed.bright { + Some(brightness) => { + let bytes = RogCore::aura_brightness_bytes(brightness.level())?; + dbus_led_builtin_write(&bytes)?; + } + _ => {} + } + Ok(()) +} + +pub fn dbus_led_builtin_write(bytes: &[u8]) -> Result<(), Box> { + let bus = Connection::new_system()?; + //let proxy = bus.with_proxy(DBUS_IFACE, "/", Duration::from_millis(5000)); + let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")? + .append1(bytes.to_vec()); + let r = bus.send_with_reply_and_block(msg, 5000)?; + if let Some(reply) = r.get1::<&str>() { + println!("Success: {:x?}", reply); + return Ok(()); + } + Err(Box::new(DbusError::new_custom("name", "message"))) +} diff --git a/rog-lib/Cargo.lock b/rog-lib/Cargo.lock new file mode 100644 index 00000000..7a837529 --- /dev/null +++ b/rog-lib/Cargo.lock @@ -0,0 +1,283 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adler32" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" + +[[package]] +name = "bit-set" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" + +[[package]] +name = "cc" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "dbus" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add8dd36d6d34a084220eb9fe216d3e230d52b37c31702e1ffda4fb2d4ef950e" +dependencies = [ + "libc", + "libdbus-sys", +] + +[[package]] +name = "filetime" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi", +] + +[[package]] +name = "gumdrop" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46571f5d540478cf70d2a42dd0d6d8e9f4b9cc7531544b93311e657b86568a0b" +dependencies = [ + "gumdrop_derive", +] + +[[package]] +name = "gumdrop_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libc" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" + +[[package]] +name = "libdbus-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc12a3bc971424edbbf7edaf6e5740483444db63aa8e23d3751ff12a30f306f0" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "libflate" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" +dependencies = [ + "adler32", + "crc32fast", + "rle-decode-fast", + "take_mut", +] + +[[package]] +name = "libusb1-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0318f131edc8211a9a3e40133be6fc93f0b686e14f59c6115eab4e7bd794b34" +dependencies = [ + "cc", + "libc", + "libflate", + "pkg-config", + "tar", + "vcpkg", +] + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" + +[[package]] +name = "proc-macro2" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + +[[package]] +name = "rle-decode-fast" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" + +[[package]] +name = "rog-core" +version = "0.3.1" +dependencies = [ + "dbus", + "gumdrop", + "rusb", + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "rusb" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d10caa3e5fc7ad1879a679bf16d3304ea10614b8f2f1a1386be4ec942d44062a" +dependencies = [ + "bit-set", + "libc", + "libusb1-sys", +] + +[[package]] +name = "serde" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" + +[[package]] +name = "serde_derive" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "tar" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" +dependencies = [ + "filetime", + "libc", + "redox_syscall", + "xattr", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "vcpkg" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] diff --git a/rog-lib/Cargo.toml b/rog-lib/Cargo.toml new file mode 100644 index 00000000..3ff790a0 --- /dev/null +++ b/rog-lib/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rog-lib" +version = "0.3.1" +authors = ["Luke "] +edition = "2018" + +[dependencies] +rusb = "0.5" +gumdrop = "0.8" +serde = "1.0" +serde_derive = "1.0" diff --git a/src/aura.rs b/rog-lib/src/aura.rs similarity index 95% rename from src/aura.rs rename to rog-lib/src/aura.rs index b87c7025..f2882c65 100644 --- a/src/aura.rs +++ b/rog-lib/src/aura.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use std::str::FromStr; #[derive(Debug, PartialEq)] -pub(crate) struct Colour(u8, u8, u8); +pub struct Colour(u8, u8, u8); impl Default for Colour { fn default() -> Self { Colour(255, 0, 0) @@ -26,7 +26,7 @@ impl FromStr for Colour { } #[derive(Debug, PartialEq)] -pub(crate) enum Speed { +pub enum Speed { Low = 0xe1, Med = 0xeb, High = 0xf5, @@ -54,7 +54,7 @@ impl FromStr for Speed { /// /// Enum corresponds to the required integer value #[derive(Debug, PartialEq)] -pub(crate) enum Direction { +pub enum Direction { Right, Left, Up, @@ -81,7 +81,7 @@ impl FromStr for Direction { } #[derive(Debug, PartialEq, Options)] -pub(crate) struct TwoColourSpeed { +pub struct TwoColourSpeed { #[options(help = "print help message")] help: bool, #[options(no_long, meta = "HEX", help = "set the first RGB value e.g, ff00ff")] @@ -93,7 +93,7 @@ pub(crate) struct TwoColourSpeed { } #[derive(Debug, PartialEq, Options)] -pub(crate) struct SingleSpeed { +pub struct SingleSpeed { #[options(help = "print help message")] help: bool, #[options(no_long, meta = "WORD", help = "set the speed: low, med, high")] @@ -101,7 +101,7 @@ pub(crate) struct SingleSpeed { } #[derive(Debug, PartialEq, Options)] -pub(crate) struct SingleColour { +pub struct SingleColour { #[options(help = "print help message")] help: bool, #[options(no_long, meta = "HEX", help = "set the RGB value e.g, ff00ff")] @@ -109,7 +109,7 @@ pub(crate) struct SingleColour { } #[derive(Debug, PartialEq, Options)] -pub(crate) struct SingleSpeedDirection { +pub struct SingleSpeedDirection { #[options(help = "print help message")] help: bool, #[options( @@ -123,7 +123,7 @@ pub(crate) struct SingleSpeedDirection { } #[derive(Debug, PartialEq, Options)] -pub(crate) struct SingleColourSpeed { +pub struct SingleColourSpeed { #[options(help = "print help message")] help: bool, #[options(no_long, meta = "HEX", help = "set the RGB value e.g, ff00ff")] @@ -136,7 +136,7 @@ pub(crate) struct SingleColourSpeed { /// /// Enum corresponds to the required integer value #[derive(Debug, Options)] -pub(crate) enum SetAuraBuiltin { +pub enum SetAuraBuiltin { #[options(help = "set a single static colour")] Stable(SingleColour), #[options(help = "pulse between one or two colours")] @@ -214,9 +214,7 @@ impl Default for SetAuraBuiltin { /// - 0x03 = downwards /// /// Bytes 10, 11, 12 are Red, Green, Blue for second colour if mode supports it -pub(crate) struct ModeMessage(pub [u8; LED_MSG_LEN]); - -impl From for ModeMessage { +impl From for [u8; LED_MSG_LEN] { fn from(mode: SetAuraBuiltin) -> Self { let mut msg = [0u8; LED_MSG_LEN]; msg[0] = 0x5d; @@ -293,6 +291,6 @@ impl From for ModeMessage { msg[6] = settings.colour.2; } } - ModeMessage(msg) + msg } } diff --git a/src/core.rs b/rog-lib/src/core.rs similarity index 85% rename from src/core.rs rename to rog-lib/src/core.rs index a9b8d120..0d69bd9f 100644 --- a/src/core.rs +++ b/rog-lib/src/core.rs @@ -1,7 +1,4 @@ use crate::error::AuraError; -use crate::{DBUS_IFACE, DBUS_NAME, DBUS_PATH}; -use dbus::Error as DbusError; -use dbus::{ffidisp::Connection, Message}; use gumdrop::Options; use rusb::{DeviceHandle, Error}; use std::str::FromStr; @@ -19,8 +16,13 @@ static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; #[derive(Debug, Options)] -pub(crate) struct LedBrightness { - pub level: u8, +pub struct LedBrightness { + level: u8, +} +impl LedBrightness { + pub fn level(&self) -> u8 { + self.level + } } impl FromStr for LedBrightness { type Err = AuraError; @@ -49,7 +51,7 @@ impl FromStr for LedBrightness { /// - `LED_INIT4` /// - `LED_INIT2` /// - `LED_INIT4` -pub(crate) struct RogCore { +pub struct RogCore { handle: DeviceHandle, initialised: bool, led_interface_num: u8, @@ -141,17 +143,23 @@ impl RogCore { let messages = [mode]; self.aura_write_messages(&messages) } -} -pub(super) fn dbus_led_builtin_write(bytes: &[u8]) -> Result<(), Box> { - let bus = Connection::new_system()?; - //let proxy = bus.with_proxy(DBUS_IFACE, "/", Duration::from_millis(5000)); - let msg = Message::new_method_call(DBUS_NAME, DBUS_PATH, DBUS_IFACE, "ledmessage")? - .append1(bytes.to_vec()); - let r = bus.send_with_reply_and_block(msg, 5000)?; - if let Some(reply) = r.get1::<&str>() { - println!("Daemon sez: {}", reply); - return Ok(()); + pub fn poll_keyboard(&mut self) -> Result<[u8; 32], Error> { + self.handle.claim_interface(self.keys_interface_num)?; + + let mut buf = [0; 32]; + match self + .handle + .read_interrupt(0x83, &mut buf, Duration::from_micros(10)) + { + Ok(_) => { + self.handle.release_interface(self.keys_interface_num)?; + Ok(buf) + } + Err(err) => match err { + //Error::Timeout => {} + _ => return Err(err), + }, + } } - Err(Box::new(DbusError::new_custom("name", "message"))) } diff --git a/src/error.rs b/rog-lib/src/error.rs similarity index 88% rename from src/error.rs rename to rog-lib/src/error.rs index b49d61ef..d514a4a6 100644 --- a/src/error.rs +++ b/rog-lib/src/error.rs @@ -3,11 +3,12 @@ use std::fmt; use std::fmt::{Debug, Display}; #[derive(PartialEq)] -pub(crate) enum AuraError { +pub enum AuraError { ParseColour, ParseSpeed, ParseDirection, ParseBrightness, + PollKeyboard, } impl Debug for AuraError { @@ -31,6 +32,7 @@ impl Error for AuraError { AuraError::ParseSpeed => "could not parse speed", AuraError::ParseDirection => "could not parse direction", AuraError::ParseBrightness => "could not parse brightness", + AuraError::PollKeyboard => "failed to poll keyboard", } } } diff --git a/rog-lib/src/lib.rs b/rog-lib/src/lib.rs new file mode 100644 index 00000000..82caced1 --- /dev/null +++ b/rog-lib/src/lib.rs @@ -0,0 +1,3 @@ +pub mod aura; +pub mod core; +mod error; diff --git a/src/daemon.rs b/src/daemon.rs deleted file mode 100644 index f3324e21..00000000 --- a/src/daemon.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::{config::Config, core::RogCore, DBUS_IFACE, DBUS_PATH}; -use dbus::{ - blocking::Connection, - tree::{Factory, MethodErr}, -}; -use std::error::Error; -use std::time::Duration; - -pub fn start_daemon() -> Result<(), Box> { - let mut config = Config::default().read(); - let mut core = RogCore::new()?; - core.aura_set_mode(&config.builtin)?; - let bright = RogCore::aura_brightness_bytes(config.brightness)?; - core.aura_set_mode(&bright)?; - - let mut c = Connection::new_system()?; - c.request_name(DBUS_IFACE, false, true, false)?; - - // The choice of factory tells us what type of tree we want, - // and if we want any extra data inside. We pick the simplest variant. - let f = Factory::new_fnmut::<()>(); - - // We create a tree with one object path inside and make that path introspectable. - let tree = f.tree(()).add( - f.object_path(DBUS_PATH, ()).introspectable().add( - // We add an interface to the object path... - f.interface(DBUS_IFACE, ()) - // ...and a method inside the interface - .add_m( - f.method("ledmessage", (), move |m| { - // Reads the args passed to the method - // Reads the args passed to the method - let bytes: Vec = m.msg.read1()?; - let s = format!("Shoving {:x?} in to keyboard!", bytes); - - if let Ok(mut core) = RogCore::new() { - match core.aura_set_mode(&bytes[..]) { - Ok(_) => { - // TODO: create statics out of header bytes - if bytes[0] == 0x5a && bytes[1] == 0xba { - config.brightness = bytes[4]; - } else if bytes[0] == 0x5d && bytes[1] == 0xb3 { - config.builtin = bytes; - } - config.write(); - let mret = m.msg.method_return().append1(s); - Ok(vec![mret]) - } - Err(err) => Err(MethodErr::failed(&err)), - } - } else { - Err(MethodErr::failed("Failed to start RogCore")) - } - }) - // Input? - .outarg::<&str, _>("reply") - .inarg::, _>("bytearray"), - ), - ), - ); - - // We add the tree to the connection so that incoming method calls will be handled. - tree.start_receive(&c); - - loop { - c.process(Duration::from_secs(1))?; - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 38a1978d..00000000 --- a/src/main.rs +++ /dev/null @@ -1,99 +0,0 @@ -// TODO: use /sys/class/dmi/id/board_name to detect model -mod aura; -mod config; -mod core; -mod daemon; -mod error; - -use crate::aura::*; -use crate::core::{dbus_led_builtin_write, LedBrightness, RogCore}; -use crate::daemon::*; -use gumdrop::Options; - -pub static DBUS_NAME: &'static str = "org.rogcore.Daemon"; -pub static DBUS_PATH: &'static str = "/org/rogcore/Daemon"; -pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon"; -pub static CONFIG_PATH: &'static str = "/etc/rogcore.conf"; - -#[derive(Debug, Options)] -struct CLIStart { - #[options(help = "print help message")] - help: bool, - #[options(help = "start daemon")] - daemon: bool, - #[options(help = "client mode")] - client: bool, - #[options(meta = "VAL", help = "")] - bright: Option, - #[options(command)] - command: Option, -} - -#[derive(Debug, Options)] -enum Command { - #[options(help = "Set the keyboard lighting from built-in modes")] - LedMode(LedModeCommand), -} - -#[derive(Debug, Options)] -struct LedModeCommand { - #[options(help = "print help message")] - help: bool, - #[options(command, required)] - command: Option, -} - -fn main() -> Result<(), Box> { - let parsed = CLIStart::parse_args_default_or_exit(); - if parsed.daemon { - start_daemon()?; - } - - match parsed.command { - Some(Command::LedMode(okk)) => match okk.command { - Some(command) => { - let mode = ModeMessage::from(command); - if parsed.client { - dbus_led_builtin_write(&mode.0)?; - } else { - let mut core = RogCore::new()?; - core.aura_set_mode(&mode.0)?; - } - } - _ => {} - }, - _ => {} - } - match parsed.bright { - Some(brightness) => { - let bytes = RogCore::aura_brightness_bytes(brightness.level as u8)?; - if parsed.client { - dbus_led_builtin_write(&bytes)?; - } else { - let mut core = RogCore::new()?; - core.aura_set_mode(&bytes)?; - } - } - _ => {} - } - - //core.aura_set_brightness(3)?; - - // core.test_builtins(aura::LED_SPEED_BYTES[2])?; - - // std::thread::sleep(std::time::Duration::from_secs(5)); - // core.aura_set_rainbow(aura::LED_SPEED_BYTES[2])?; - - // // READ KEYBOARD - // let mut buf = [0; 32]; - // loop { - // match handle.read_interrupt(0x83, &mut buf, Duration::new(0, 5)) { - // Ok(_) => println!("{:?}", buf), - // Err(err) => match err { - // Error::Timeout => {} - // _ => return Err(Box::new(err)), - // }, - // } - // } - Ok(()) -}