mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Partial daemon mode for builtin LED control
This commit is contained in:
22
Cargo.lock
generated
22
Cargo.lock
generated
@@ -42,6 +42,16 @@ dependencies = [
|
|||||||
"cfg-if",
|
"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]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
@@ -80,6 +90,15 @@ version = "0.2.68"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
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]]
|
[[package]]
|
||||||
name = "libflate"
|
name = "libflate"
|
||||||
version = "0.1.27"
|
version = "0.1.27"
|
||||||
@@ -144,8 +163,9 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rog-core"
|
name = "rog-core"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"dbus",
|
||||||
"gumdrop",
|
"gumdrop",
|
||||||
"rusb",
|
"rusb",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rusb = "0.5"
|
rusb = "0.5"
|
||||||
gumdrop = "0.8"
|
gumdrop = "0.8"
|
||||||
|
dbus = "0.7.1"
|
||||||
|
|||||||
59
Makefile
Normal file
59
Makefile
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
prefix ?= /usr
|
||||||
|
sysconfdir ?= /etc
|
||||||
|
exec_prefix = $(prefix)
|
||||||
|
bindir = $(exec_prefix)/bin
|
||||||
|
libdir = $(exec_prefix)/lib
|
||||||
|
includedir = $(prefix)/include
|
||||||
|
datarootdir = $(prefix)/share
|
||||||
|
datadir = $(datarootdir)
|
||||||
|
|
||||||
|
SRC = Cargo.toml Cargo.lock Makefile $(shell find src -type f -wholename '*src/*.rs')
|
||||||
|
|
||||||
|
.PHONY: all clean distclean install uninstall update
|
||||||
|
|
||||||
|
BIN=rog-core
|
||||||
|
|
||||||
|
DEBUG ?= 0
|
||||||
|
ifeq ($(DEBUG),0)
|
||||||
|
ARGS += "--release"
|
||||||
|
TARGET = release
|
||||||
|
endif
|
||||||
|
|
||||||
|
VENDORED ?= 0
|
||||||
|
ifeq ($(VENDORED),1)
|
||||||
|
ARGS += "--frozen"
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: target/release/$(BIN)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cargo clean
|
||||||
|
|
||||||
|
distclean:
|
||||||
|
rm -rf .cargo vendor vendor.tar.xz
|
||||||
|
|
||||||
|
install: all
|
||||||
|
install -D -m 04755 "target/release/$(BIN)" "$(DESTDIR)$(bindir)/$(BIN)"
|
||||||
|
install -D -m 0644 "data/$(BIN).conf" "$(DESTDIR)$(sysconfdir)/dbus-1/system.d/$(BIN).conf"
|
||||||
|
install -D -m 0644 "data/$(BIN).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN).service"
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f "$(DESTDIR)$(bindir)/$(BIN)"
|
||||||
|
rm -f "$(DESTDIR)$(sysconfdir)/dbus-1/system.d/$(BIN).conf"
|
||||||
|
rm -f "$(DESTDIR)$(libdir)/systemd/system/$(BIN).service"
|
||||||
|
|
||||||
|
update:
|
||||||
|
cargo update
|
||||||
|
|
||||||
|
vendor:
|
||||||
|
mkdir -p .cargo
|
||||||
|
cargo vendor | head -n -1 > .cargo/config
|
||||||
|
echo 'directory = "vendor"' >> .cargo/config
|
||||||
|
tar pcfJ vendor.tar.xz vendor
|
||||||
|
rm -rf vendor
|
||||||
|
|
||||||
|
target/release/$(BIN): $(SRC)
|
||||||
|
ifeq ($(VENDORED),1)
|
||||||
|
tar pxf vendor.tar.xz
|
||||||
|
endif
|
||||||
|
cargo build $(ARGS)
|
||||||
18
data/rog-core.conf
Normal file
18
data/rog-core.conf
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE busconfig PUBLIC
|
||||||
|
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
|
<busconfig>
|
||||||
|
<policy group="adm">
|
||||||
|
<allow send_destination="org.rogcore.Daemon"/>
|
||||||
|
<allow receive_sender="org.rogcore.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
<policy group="sudo">
|
||||||
|
<allow send_destination="org.rogcore.Daemon"/>
|
||||||
|
<allow receive_sender="org.rogcore.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
<policy user="root">
|
||||||
|
<allow own="org.rogcore.Daemon"/>
|
||||||
|
<allow send_destination="org.rogcore.Daemon"/>
|
||||||
|
<allow receive_sender="org.rogcore.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
</busconfig>
|
||||||
9
data/rog-core.service
Normal file
9
data/rog-core.service
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=ROG Core Daemon
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/rog-core -d
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
58
src/aura.rs
58
src/aura.rs
@@ -1,45 +1,11 @@
|
|||||||
use crate::core::LED_MSG_LEN;
|
use crate::core::LED_MSG_LEN;
|
||||||
|
use crate::error::AuraError;
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use std::error::Error;
|
use std::fmt::Debug;
|
||||||
use std::fmt;
|
|
||||||
use std::fmt::{Debug, Display};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
pub enum AuraError {
|
|
||||||
ParseColour,
|
|
||||||
ParseSpeed,
|
|
||||||
ParseDirection,
|
|
||||||
ParseBrightness,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for AuraError {
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
Display::fmt(self.description(), f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for AuraError {
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
Display::fmt(self.description(), f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for AuraError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
AuraError::ParseColour => "could not parse colour",
|
|
||||||
AuraError::ParseSpeed => "could not parse speed",
|
|
||||||
AuraError::ParseDirection => "could not parse direction",
|
|
||||||
AuraError::ParseBrightness => "could not parse brightness",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Colour(u8, u8, u8);
|
pub(crate) struct Colour(u8, u8, u8);
|
||||||
impl Default for Colour {
|
impl Default for Colour {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Colour(255, 0, 0)
|
Colour(255, 0, 0)
|
||||||
@@ -60,7 +26,7 @@ impl FromStr for Colour {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Speed {
|
pub(crate) enum Speed {
|
||||||
Low = 0xe1,
|
Low = 0xe1,
|
||||||
Med = 0xeb,
|
Med = 0xeb,
|
||||||
High = 0xf5,
|
High = 0xf5,
|
||||||
@@ -88,7 +54,7 @@ impl FromStr for Speed {
|
|||||||
///
|
///
|
||||||
/// Enum corresponds to the required integer value
|
/// Enum corresponds to the required integer value
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Direction {
|
pub(crate) enum Direction {
|
||||||
Right,
|
Right,
|
||||||
Left,
|
Left,
|
||||||
Up,
|
Up,
|
||||||
@@ -115,7 +81,7 @@ impl FromStr for Direction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Options)]
|
#[derive(Debug, PartialEq, Options)]
|
||||||
pub struct Breathe {
|
pub(crate) struct Breathe {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
#[options(no_long, help = "set the first colour, must be hex string e.g, ff00ff")]
|
#[options(no_long, help = "set the first colour, must be hex string e.g, ff00ff")]
|
||||||
@@ -130,7 +96,7 @@ pub struct Breathe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Options)]
|
#[derive(Debug, PartialEq, Options)]
|
||||||
pub struct SingleSpeed {
|
pub(crate) struct SingleSpeed {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
#[options(no_long, help = "set the speed: low, med, high")]
|
#[options(no_long, help = "set the speed: low, med, high")]
|
||||||
@@ -138,7 +104,7 @@ pub struct SingleSpeed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Options)]
|
#[derive(Debug, PartialEq, Options)]
|
||||||
pub struct SingleColour {
|
pub(crate) struct SingleColour {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
#[options(no_long, help = "set the colour, must be hex string e.g, ff00ff")]
|
#[options(no_long, help = "set the colour, must be hex string e.g, ff00ff")]
|
||||||
@@ -146,7 +112,7 @@ pub struct SingleColour {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Options)]
|
#[derive(Debug, PartialEq, Options)]
|
||||||
pub struct SingleSpeedDirection {
|
pub(crate) struct SingleSpeedDirection {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
#[options(no_long, help = "set the direction: up, down, left, right")]
|
#[options(no_long, help = "set the direction: up, down, left, right")]
|
||||||
@@ -156,7 +122,7 @@ pub struct SingleSpeedDirection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Options)]
|
#[derive(Debug, PartialEq, Options)]
|
||||||
pub struct SingleColourSpeed {
|
pub(crate) struct SingleColourSpeed {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
#[options(no_long, help = "set the colour, must be hex string e.g, ff00ff")]
|
#[options(no_long, help = "set the colour, must be hex string e.g, ff00ff")]
|
||||||
@@ -169,7 +135,7 @@ pub struct SingleColourSpeed {
|
|||||||
///
|
///
|
||||||
/// Enum corresponds to the required integer value
|
/// Enum corresponds to the required integer value
|
||||||
#[derive(Debug, Options)]
|
#[derive(Debug, Options)]
|
||||||
pub enum SetAuraBuiltin {
|
pub(crate) enum SetAuraBuiltin {
|
||||||
#[options(help = "set a single static colour")]
|
#[options(help = "set a single static colour")]
|
||||||
Stable(SingleColour),
|
Stable(SingleColour),
|
||||||
#[options(help = "pulse between one or two colours")]
|
#[options(help = "pulse between one or two colours")]
|
||||||
@@ -247,7 +213,7 @@ impl Default for SetAuraBuiltin {
|
|||||||
/// - 0x03 = downwards
|
/// - 0x03 = downwards
|
||||||
///
|
///
|
||||||
/// Bytes 10, 11, 12 are Red, Green, Blue for second colour if mode supports it
|
/// Bytes 10, 11, 12 are Red, Green, Blue for second colour if mode supports it
|
||||||
pub struct ModeMessage(pub [u8; LED_MSG_LEN]);
|
pub(crate) struct ModeMessage(pub [u8; LED_MSG_LEN]);
|
||||||
|
|
||||||
impl From<SetAuraBuiltin> for ModeMessage {
|
impl From<SetAuraBuiltin> for ModeMessage {
|
||||||
fn from(mode: SetAuraBuiltin) -> Self {
|
fn from(mode: SetAuraBuiltin) -> Self {
|
||||||
|
|||||||
36
src/core.rs
36
src/core.rs
@@ -1,5 +1,7 @@
|
|||||||
use crate::aura::AuraError;
|
use crate::error::AuraError;
|
||||||
use crate::aura::ModeMessage;
|
use crate::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
|
||||||
|
use dbus::Error as DbusError;
|
||||||
|
use dbus::{ffidisp::Connection, Message};
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use rusb::{DeviceHandle, Error};
|
use rusb::{DeviceHandle, Error};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@@ -17,7 +19,7 @@ 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];
|
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)]
|
#[derive(Debug, Options)]
|
||||||
pub struct LedBrightness {
|
pub(crate) struct LedBrightness {
|
||||||
pub level: u8,
|
pub level: u8,
|
||||||
}
|
}
|
||||||
impl FromStr for LedBrightness {
|
impl FromStr for LedBrightness {
|
||||||
@@ -47,7 +49,7 @@ impl FromStr for LedBrightness {
|
|||||||
/// - `LED_INIT4`
|
/// - `LED_INIT4`
|
||||||
/// - `LED_INIT2`
|
/// - `LED_INIT2`
|
||||||
/// - `LED_INIT4`
|
/// - `LED_INIT4`
|
||||||
pub struct RogCore {
|
pub(crate) struct RogCore {
|
||||||
handle: DeviceHandle<rusb::GlobalContext>,
|
handle: DeviceHandle<rusb::GlobalContext>,
|
||||||
initialised: bool,
|
initialised: bool,
|
||||||
led_interface_num: u8,
|
led_interface_num: u8,
|
||||||
@@ -96,7 +98,7 @@ impl RogCore {
|
|||||||
Err(Error::NoDevice)
|
Err(Error::NoDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn aura_write_messages(&mut self, messages: &[[u8; LED_MSG_LEN]]) -> Result<(), Error> {
|
fn aura_write_messages(&mut self, messages: &[&[u8]]) -> Result<(), Error> {
|
||||||
self.handle.claim_interface(self.led_interface_num)?;
|
self.handle.claim_interface(self.led_interface_num)?;
|
||||||
// Declared as a zoomy so that it is hidden
|
// Declared as a zoomy so that it is hidden
|
||||||
let write = |message: &[u8]| {
|
let write = |message: &[u8]| {
|
||||||
@@ -114,7 +116,7 @@ impl RogCore {
|
|||||||
|
|
||||||
for message in messages {
|
for message in messages {
|
||||||
println!("{:x?}", &message);
|
println!("{:x?}", &message);
|
||||||
write(message)?;
|
write(*message)?;
|
||||||
write(&LED_SET)?;
|
write(&LED_SET)?;
|
||||||
}
|
}
|
||||||
// Changes won't persist unless apply is set
|
// Changes won't persist unless apply is set
|
||||||
@@ -124,19 +126,31 @@ impl RogCore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aura_set_brightness(&mut self, brightness: u8) -> Result<(), Error> {
|
pub fn aura_brightness_bytes(brightness: u8) -> Result<[u8; 17], Error> {
|
||||||
let mut bright = [0u8; LED_MSG_LEN];
|
let mut bright = [0u8; LED_MSG_LEN];
|
||||||
bright[0] = 0x5a;
|
bright[0] = 0x5a;
|
||||||
bright[1] = 0xba;
|
bright[1] = 0xba;
|
||||||
bright[2] = 0xc5;
|
bright[2] = 0xc5;
|
||||||
bright[3] = 0xc4;
|
bright[3] = 0xc4;
|
||||||
bright[4] = brightness;
|
bright[4] = brightness;
|
||||||
let messages = [bright];
|
Ok(bright)
|
||||||
self.aura_write_messages(&messages)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aura_set_mode(&mut self, mode: ModeMessage) -> Result<(), Error> {
|
pub fn aura_set_mode(&mut self, mode: &[u8]) -> Result<(), Error> {
|
||||||
let messages = [mode.0];
|
let messages = [mode];
|
||||||
self.aura_write_messages(&messages)
|
self.aura_write_messages(&messages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn dbus_led_builtin_write(bytes: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
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(());
|
||||||
|
}
|
||||||
|
Err(Box::new(DbusError::new_custom("name", "message")))
|
||||||
|
}
|
||||||
|
|||||||
55
src/daemon.rs
Normal file
55
src/daemon.rs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
use crate::{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<dyn Error>> {
|
||||||
|
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_fn::<()>();
|
||||||
|
|
||||||
|
// 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<u8> = 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(_) => {
|
||||||
|
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::<Vec<u8>, _>("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))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/error.rs
Normal file
36
src/error.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub(crate) enum AuraError {
|
||||||
|
ParseColour,
|
||||||
|
ParseSpeed,
|
||||||
|
ParseDirection,
|
||||||
|
ParseBrightness,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for AuraError {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Display::fmt(self.description(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for AuraError {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Display::fmt(self.description(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for AuraError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
AuraError::ParseColour => "could not parse colour",
|
||||||
|
AuraError::ParseSpeed => "could not parse speed",
|
||||||
|
AuraError::ParseDirection => "could not parse direction",
|
||||||
|
AuraError::ParseBrightness => "could not parse brightness",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/main.rs
34
src/main.rs
@@ -1,15 +1,26 @@
|
|||||||
// TODO: use /sys/class/dmi/id/board_name to detect model
|
// TODO: use /sys/class/dmi/id/board_name to detect model
|
||||||
mod aura;
|
mod aura;
|
||||||
mod core;
|
mod core;
|
||||||
|
mod daemon;
|
||||||
|
mod error;
|
||||||
|
|
||||||
use crate::aura::*;
|
use crate::aura::*;
|
||||||
use crate::core::{LedBrightness, RogCore};
|
use crate::core::{dbus_led_builtin_write, LedBrightness, RogCore};
|
||||||
|
use crate::daemon::*;
|
||||||
use gumdrop::Options;
|
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";
|
||||||
|
|
||||||
#[derive(Debug, Options)]
|
#[derive(Debug, Options)]
|
||||||
struct CLIStart {
|
struct CLIStart {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
|
#[options(help = "start daemon")]
|
||||||
|
daemon: bool,
|
||||||
|
#[options(help = "client mode")]
|
||||||
|
client: bool,
|
||||||
#[options(help = "<off, low, med, high>")]
|
#[options(help = "<off, low, med, high>")]
|
||||||
bright: Option<LedBrightness>,
|
bright: Option<LedBrightness>,
|
||||||
#[options(command)]
|
#[options(command)]
|
||||||
@@ -32,12 +43,20 @@ struct LedModeCommand {
|
|||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let parsed = CLIStart::parse_args_default_or_exit();
|
let parsed = CLIStart::parse_args_default_or_exit();
|
||||||
|
if parsed.daemon {
|
||||||
|
start_daemon()?;
|
||||||
|
}
|
||||||
|
|
||||||
match parsed.command {
|
match parsed.command {
|
||||||
Some(Command::LedMode(okk)) => match okk.command {
|
Some(Command::LedMode(okk)) => match okk.command {
|
||||||
Some(command) => {
|
Some(command) => {
|
||||||
let mut core = RogCore::new()?;
|
|
||||||
let mode = ModeMessage::from(command);
|
let mode = ModeMessage::from(command);
|
||||||
core.aura_set_mode(mode)?;
|
if parsed.client {
|
||||||
|
dbus_led_builtin_write(&mode.0)?;
|
||||||
|
} else {
|
||||||
|
let mut core = RogCore::new()?;
|
||||||
|
core.aura_set_mode(&mode.0)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
@@ -45,8 +64,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
match parsed.bright {
|
match parsed.bright {
|
||||||
Some(brightness) => {
|
Some(brightness) => {
|
||||||
let mut core = RogCore::new()?;
|
let bytes = RogCore::aura_brightness_bytes(brightness.level as u8)?;
|
||||||
core.aura_set_brightness(brightness.level as u8)?;
|
if parsed.client {
|
||||||
|
dbus_led_builtin_write(&bytes)?;
|
||||||
|
} else {
|
||||||
|
let mut core = RogCore::new()?;
|
||||||
|
core.aura_set_mode(&bytes)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user