Dbus signals (#28)

* Small rename of dbus args
* Split out parts of main loop to tasks
* Send signals on boot
This commit is contained in:
Luke Jones
2020-07-07 13:33:32 +12:00
committed by GitHub
parent 2dc61fe994
commit 229fa93bc7
6 changed files with 186 additions and 55 deletions

View File

@@ -33,7 +33,7 @@ distclean:
rm -rf .cargo vendor vendor.tar.xz
install: all
install -D -m 04755 "target/release/$(BIN)" "$(DESTDIR)$(bindir)/$(BIN)"
install -D -m 0755 "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"

View File

@@ -131,6 +131,28 @@ When emitted, it will include the integer the charging limit was changed to.
dbus-send --system --type=method_call --dest=org.rogcore.Daemon /org/rogcore/Daemon org.rogcore.Daemon.SetKeyBacklight string:'{"Stable": {"colour": [ 80, 0, 40]}}'
```
```
dbus-send --system --type=method_call --dest=org.rogcore.Daemon /org/rogcore/Daemon org.rogcore.Daemon.SetKeyBacklight string:'{"Star":{"colour":[0,255,255],"colour2":[0,0,0],"speed":"Med"}}'
```
**Note:** setting colour2 to `[0,0,255]` activates random star colour. Colour2 has no effect on the
mode otherwise.
```
dbus-send --system --type=method_call --dest=org.rogcore.Daemon /org/rogcore/Daemon org.rogcore.Daemon.SetKeyBacklight string:'{"Star":{"colour":[0,255,255],"colour2":[0,0,255],"speed":"Med"}}'
```
```
dbus-send --system --type=method_call --dest=org.rogcore.Daemon /org/rogcore/Daemon org.rogcore.Daemon.SetKeyBacklight string:'{"LedBrightness":3}'
```
```
dbus-send --system --type=method_call --dest=org.rogcore.Daemon /org/rogcore/Daemon org.rogcore.Daemon.SetFanMode byte:'2'
```
Monitoring dbus while sending commands via `rog-core` will give you the json structure if you are otherwise unsure, e.g: `dbus-monitor --system |grep -A2 rogcore`.
## Getting an introspection .xml
```
dbus-send --system --print-reply --dest=org.rogcore.Daemon /org/rogcore/Daemon org.freedesktop.DBus.Introspectable.Introspect > xml/dbus-0.14.4.xml
```

View File

@@ -4,6 +4,8 @@ Description=ROG Core Daemon
[Service]
ExecStart=/usr/bin/rog-core -d
Restart=on-failure
Type=dbus
BusName=org.rogcore.Daemon
[Install]
WantedBy=multi-user.target

View File

@@ -24,7 +24,8 @@ impl Ball {
}
}
fn update(&mut self, key_map: &Vec<[Key; 17]>) {
#[allow(clippy::if_same_then_else)]
fn update(&mut self, key_map: &[[Key; 17]]) {
let pos = self.position;
let dir = self.direction;

View File

@@ -7,13 +7,14 @@ use crate::{
rogcore::*,
};
use dbus::{channel::Sender, nonblock::Process};
use dbus::{channel::Sender, nonblock::Process, nonblock::SyncConnection, tree::Signal};
use dbus_tokio::connection;
use log::{error, info, warn};
use rog_client::{aura_modes::AuraModes, DBUS_IFACE, DBUS_NAME, DBUS_PATH};
use std::error::Error;
use std::sync::Arc;
use tokio::sync::Mutex;
pub(super) type DbusU8Type = Arc<Mutex<Option<u8>>>;
@@ -62,6 +63,13 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
laptop.led_endpoint(),
laptop.supported_modes().to_owned(),
);
let keyboard_reader = KeyboardReader::new(
rogcore.get_raw_device_handle(),
laptop.key_endpoint(),
laptop.key_filter().to_owned(),
);
led_writer
.reload_last_builtin(&mut config)
.await
@@ -86,20 +94,33 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
mut animatrix_recv,
fan_mode,
charge_limit,
effect_cancel_signal,
led_changed_signal,
fanmode_signal,
charge_limit_signal,
) = dbus_create_tree(config.clone());
// We add the tree to the connection so that incoming method calls will be handled.
tree.start_receive_send(&*connection);
// Send boot signals
send_boot_signals(
connection.clone(),
config.clone(),
fanmode_signal.clone(),
charge_limit_signal.clone(),
led_changed_signal.clone(),
)
.await?;
// For helping with processing signals
start_signal_task(
connection.clone(),
config.clone(),
fanmode_signal,
charge_limit_signal,
);
// Keyboard reader goes in separate task because we want a high interrupt timeout
// and don't want that to hold up other tasks, or miss keystrokes
let keyboard_reader = KeyboardReader::new(
rogcore.get_raw_device_handle(),
laptop.key_endpoint(),
laptop.key_filter().to_owned(),
);
// Possible Animatrix
if laptop.support_animatrix() {
@@ -117,8 +138,9 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
}
}
let config1 = config.clone();
// start the keyboard reader and laptop-action loop
let config1 = config.clone();
// spawning this in a function causes a segfault for reasons I haven't investigated yet
tokio::spawn(async move {
loop {
// Fan mode
@@ -150,41 +172,6 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
}
});
// For helping with processing signals
let connection1 = connection.clone();
let config1 = config.clone();
tokio::spawn(async move {
// Some small things we need to track, without passing all sorts of stuff around
let mut last_fan_mode = config1.lock().await.fan_mode;
let mut last_charge_limit = config1.lock().await.bat_charge_limit;
loop {
// Use tokio sleep to not hold up other threads
tokio::time::delay_for(std::time::Duration::from_millis(500)).await;
let config = config1.lock().await;
if config.fan_mode != last_fan_mode {
last_fan_mode = config.fan_mode;
connection1
.send(
fanmode_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(last_fan_mode),
)
.unwrap_or_else(|_| 0);
}
if config.bat_charge_limit != last_charge_limit {
last_charge_limit = config.bat_charge_limit;
connection1
.send(
charge_limit_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(last_charge_limit),
)
.unwrap_or_else(|_| 0);
}
}
});
// start the main loop
loop {
connection.process_all();
@@ -206,7 +193,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
.unwrap_or_else(|err| warn!("{}", err));
connection
.send(
effect_cancel_signal
led_changed_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(json),
)
@@ -216,3 +203,122 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
}
}
}
fn start_signal_task(
connection: Arc<SyncConnection>,
config: Arc<Mutex<Config>>,
fanmode_signal: Arc<Signal<()>>,
charge_limit_signal: Arc<Signal<()>>,
) {
tokio::spawn(async move {
// Some small things we need to track, without passing all sorts of stuff around
let mut last_fan_mode = config.lock().await.fan_mode;
let mut last_charge_limit = config.lock().await.bat_charge_limit;
loop {
// Use tokio sleep to not hold up other threads
tokio::time::delay_for(std::time::Duration::from_millis(500)).await;
let config = config.lock().await;
if config.fan_mode != last_fan_mode {
last_fan_mode = config.fan_mode;
connection
.send(
fanmode_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(last_fan_mode),
)
.unwrap_or_else(|_| 0);
}
if config.bat_charge_limit != last_charge_limit {
last_charge_limit = config.bat_charge_limit;
connection
.send(
charge_limit_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(last_charge_limit),
)
.unwrap_or_else(|_| 0);
}
}
});
}
async fn send_boot_signals(
connection: Arc<SyncConnection>,
config: Arc<Mutex<Config>>,
fanmode_signal: Arc<Signal<()>>,
charge_limit_signal: Arc<Signal<()>>,
led_changed_signal: Arc<Signal<()>>,
) -> Result<(), Box<dyn Error>> {
let config = config.lock().await;
if let Some(data) = config.get_led_mode_data(config.current_mode) {
connection
.send(
led_changed_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(serde_json::to_string(data)?),
)
.unwrap_or_else(|_| 0);
}
connection
.send(
fanmode_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(config.fan_mode),
)
.unwrap_or_else(|_| 0);
connection
.send(
charge_limit_signal
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
.append1(config.bat_charge_limit),
)
.unwrap_or_else(|_| 0);
Ok(())
}
// fn start_keyboard_task(
// fan_mode: Arc<Mutex<Option<u8>>>,
// charge_limit: Arc<Mutex<Option<u8>>>,
// config: Arc<Mutex<Config>>,
// aura_command_sender: mpsc::Sender<AuraModes>,
// mut rogcore: RogCore,
// laptop: LaptopBase,
// ) -> tokio::task::JoinHandle<()> {
// let keyboard_reader = KeyboardReader::new(
// rogcore.get_raw_device_handle(),
// laptop.key_endpoint(),
// laptop.key_filter().to_owned(),
// );
//
// tokio::spawn(async move {
// loop {
// // Fan mode
// if let Ok(mut lock) = fan_mode.try_lock() {
// if let Some(n) = lock.take() {
// let mut config = config.lock().await;
// rogcore
// .set_fan_mode(n, &mut config)
// .unwrap_or_else(|err| warn!("{:?}", err));
// }
// }
// // Charge limit
// if let Ok(mut lock) = charge_limit.try_lock() {
// if let Some(n) = lock.take() {
// let mut config = config.lock().await;
// rogcore
// .set_charge_limit(n, &mut config)
// .unwrap_or_else(|err| warn!("{:?}", err));
// }
// }
// // Keyboard reads
// let data = keyboard_reader.poll_keyboard().await;
// if let Some(bytes) = data {
// laptop
// .run(&mut rogcore, &config, bytes, aura_command_sender.clone())
// .await
// .unwrap_or_else(|err| warn!("{}", err));
// }
// }
// })
// }

View File

@@ -55,7 +55,7 @@ fn get_keyboard_backlight(config: Arc<Mutex<Config>>) -> Method<MTSync, ()> {
}
}
})
.outarg::<&str, _>("value")
.outarg::<&str, _>("json")
}
fn get_keyboard_backlight_modes(config: Arc<Mutex<Config>>) -> Method<MTSync, ()> {
@@ -72,7 +72,7 @@ fn get_keyboard_backlight_modes(config: Arc<Mutex<Config>>) -> Method<MTSync, ()
}
}
})
.outarg::<&str, _>("value")
.outarg::<&str, _>("json")
}
fn set_animatrix(
@@ -115,7 +115,7 @@ fn set_fan_mode(data: DbusU8Type) -> Method<MTSync, ()> {
}
}
})
.inarg::<u8, _>("byte")
.inarg::<u8, _>("mode")
.annotate("org.freedesktop.DBus.Method.NoReply", "true")
}
@@ -132,7 +132,7 @@ fn get_fan_mode(config: Arc<Mutex<Config>>) -> Method<MTSync, ()> {
}
}
})
.outarg::<&str, _>("value")
.outarg::<u8, _>("mode")
}
fn get_charge_limit(config: Arc<Mutex<Config>>) -> Method<MTSync, ()> {
@@ -148,7 +148,7 @@ fn get_charge_limit(config: Arc<Mutex<Config>>) -> Method<MTSync, ()> {
}
}
})
.outarg::<&str, _>("value")
.outarg::<u8, _>("limit")
}
fn set_charge_limit(data: DbusU8Type) -> Method<MTSync, ()> {
@@ -167,7 +167,7 @@ fn set_charge_limit(data: DbusU8Type) -> Method<MTSync, ()> {
}
}
})
.inarg::<u8, _>("byte")
.inarg::<u8, _>("limit")
.annotate("org.freedesktop.DBus.Method.NoReply", "true")
}
@@ -195,14 +195,14 @@ pub(super) fn dbus_create_tree(
let key_backlight_changed = Arc::new(
factory
.signal("KeyBacklightChanged", ())
.sarg::<&str, _>("value"),
.sarg::<&str, _>("json"),
);
let chrg_limit_changed = Arc::new(
factory
.signal("ChargeLimitChanged", ())
.sarg::<u8, _>("value"),
.sarg::<u8, _>("limit"),
);
let fanmode_changed = Arc::new(factory.signal("FanModeChanged", ()).sarg::<u8, _>("value"));
let fanmode_changed = Arc::new(factory.signal("FanModeChanged", ()).sarg::<u8, _>("mode"));
let tree = factory
.tree(())