mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Clean up the main loop
This commit is contained in:
@@ -110,7 +110,7 @@ impl RogCore {
|
|||||||
|
|
||||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||||
file.write(format!("{:?}\n", self.config.fan_mode).as_bytes())?;
|
file.write(format!("{:?}\n", self.config.fan_mode).as_bytes())?;
|
||||||
|
info!("Reloaded last saved settings");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ impl RogCore {
|
|||||||
pub(crate) async fn poll_keyboard(
|
pub(crate) async fn poll_keyboard(
|
||||||
handle: &DeviceHandle<rusb::GlobalContext>,
|
handle: &DeviceHandle<rusb::GlobalContext>,
|
||||||
endpoint: u8,
|
endpoint: u8,
|
||||||
report_filter_bytes: Vec<u8>,
|
report_filter_bytes: &[u8],
|
||||||
) -> Option<[u8; 32]> {
|
) -> Option<[u8; 32]> {
|
||||||
let mut buf = [0u8; 32];
|
let mut buf = [0u8; 32];
|
||||||
match handle.read_interrupt(endpoint, &mut buf, Duration::from_millis(200)) {
|
match handle.read_interrupt(endpoint, &mut buf, Duration::from_millis(200)) {
|
||||||
|
|||||||
222
src/daemon.rs
222
src/daemon.rs
@@ -5,7 +5,7 @@ pub static DBUS_IFACE: &'static str = "org.rogcore.Daemon";
|
|||||||
use crate::{core::RogCore, laptops::match_laptop};
|
use crate::{core::RogCore, laptops::match_laptop};
|
||||||
use dbus::{
|
use dbus::{
|
||||||
nonblock::Process,
|
nonblock::Process,
|
||||||
tree::{Factory, MethodErr},
|
tree::{Factory, MTSync, Method, MethodErr, Tree},
|
||||||
};
|
};
|
||||||
use dbus_tokio::connection;
|
use dbus_tokio::connection;
|
||||||
|
|
||||||
@@ -14,6 +14,18 @@ use std::error::Error;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
type LedMsgType = Arc<Mutex<Option<Vec<u8>>>>;
|
||||||
|
type EffectType = Arc<Mutex<Option<Vec<Vec<u8>>>>>;
|
||||||
|
|
||||||
|
// Timing is such that:
|
||||||
|
// - interrupt write is minimum 1ms (sometimes lower)
|
||||||
|
// - read interrupt must timeout, minimum of 1ms
|
||||||
|
// - for a single usb packet, 2ms total.
|
||||||
|
// - to maintain constant times of 1ms, per-key colours should use
|
||||||
|
// the effect endpoint so that the complete colour block is written
|
||||||
|
// as fast as 1ms per row of the matrix inside it. (10ms total time)
|
||||||
|
//
|
||||||
|
// DBUS processing takes 6ms if not tokiod
|
||||||
pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||||
let laptop = match_laptop();
|
let laptop = match_laptop();
|
||||||
let mut rogcore = RogCore::new(&*laptop).map_or_else(
|
let mut rogcore = RogCore::new(&*laptop).map_or_else(
|
||||||
@@ -28,7 +40,6 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
);
|
);
|
||||||
// Reload settings
|
// Reload settings
|
||||||
rogcore.reload().await?;
|
rogcore.reload().await?;
|
||||||
info!("Reloaded last saved settings");
|
|
||||||
|
|
||||||
let (resource, connection) = connection::new_system_sync()?;
|
let (resource, connection) = connection::new_system_sync()?;
|
||||||
tokio::spawn(async {
|
tokio::spawn(async {
|
||||||
@@ -40,125 +51,39 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
.request_name(DBUS_IFACE, false, true, false)
|
.request_name(DBUS_IFACE, false, true, false)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let factory = Factory::new_sync::<()>();
|
let (tree, input, effect) = dbus_create_tree();
|
||||||
|
|
||||||
let input: Arc<Mutex<Option<Vec<u8>>>> = Arc::new(Mutex::new(None));
|
|
||||||
let effect: Arc<Mutex<Option<Vec<Vec<u8>>>>> = Arc::new(Mutex::new(None));
|
|
||||||
|
|
||||||
let tree = factory.tree(()).add(
|
|
||||||
factory.object_path(DBUS_PATH, ()).add(
|
|
||||||
factory
|
|
||||||
.interface(DBUS_IFACE, ())
|
|
||||||
.add_m(
|
|
||||||
factory
|
|
||||||
// method for ledmessage
|
|
||||||
.method("ledmessage", (), {
|
|
||||||
let input = input.clone();
|
|
||||||
|
|
||||||
move |m| {
|
|
||||||
let bytes: Vec<u8> = m.msg.read1()?;
|
|
||||||
if let Ok(mut lock) = input.try_lock() {
|
|
||||||
*lock = Some(bytes.to_vec());
|
|
||||||
let mret = m
|
|
||||||
.msg
|
|
||||||
.method_return()
|
|
||||||
.append1(&format!("Wrote {:x?}", bytes));
|
|
||||||
return Ok(vec![mret]);
|
|
||||||
} else {
|
|
||||||
return Err(MethodErr::failed(
|
|
||||||
"Could not lock daemon for access",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.outarg::<&str, _>("reply")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray"),
|
|
||||||
)
|
|
||||||
.add_m(
|
|
||||||
factory
|
|
||||||
// method for ledmessage
|
|
||||||
.method("ledeffect", (), {
|
|
||||||
let effect = effect.clone();
|
|
||||||
move |m| {
|
|
||||||
if let Ok(mut lock) = effect.try_lock() {
|
|
||||||
let mut iter = m.msg.iter_init();
|
|
||||||
let byte_array: Vec<Vec<u8>> = vec![
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
iter.read()?,
|
|
||||||
];
|
|
||||||
|
|
||||||
*lock = Some(byte_array);
|
|
||||||
let mret =
|
|
||||||
m.msg.method_return().append1(&format!("Got effect part"));
|
|
||||||
return Ok(vec![mret]);
|
|
||||||
} else {
|
|
||||||
return Err(MethodErr::failed(
|
|
||||||
"Could not lock daemon for access",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.outarg::<&str, _>("reply")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray")
|
|
||||||
.inarg::<Vec<u8>, _>("bytearray"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// We add the tree to the connection so that incoming method calls will be handled.
|
// We add the tree to the connection so that incoming method calls will be handled.
|
||||||
tree.start_receive_send(&*connection);
|
tree.start_receive_send(&*connection);
|
||||||
|
|
||||||
let supported = Vec::from(laptop.supported_modes());
|
|
||||||
|
|
||||||
let key_buf: Arc<Mutex<Option<[u8; 32]>>> = Arc::new(Mutex::new(None));
|
let key_buf: Arc<Mutex<Option<[u8; 32]>>> = Arc::new(Mutex::new(None));
|
||||||
let handle = unsafe { &*(rogcore.get_raw_device_handle()) };
|
{
|
||||||
let endpoint = laptop.key_endpoint();
|
let usb_dev_handle = unsafe { &*(rogcore.get_raw_device_handle()) };
|
||||||
let report_filter_bytes = laptop.key_filter().to_owned();
|
let keyboard_endpoint = laptop.key_endpoint();
|
||||||
|
let report_filter_bytes = laptop.key_filter().to_owned();
|
||||||
|
|
||||||
let key_buf1 = key_buf.clone();
|
let key_buf1 = key_buf.clone();
|
||||||
// This is *not* safe
|
// This is *not* safe
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let data = RogCore::poll_keyboard(handle, endpoint, report_filter_bytes.clone()).await;
|
let data =
|
||||||
if let Some(stuff) = data {
|
RogCore::poll_keyboard(usb_dev_handle, keyboard_endpoint, &report_filter_bytes)
|
||||||
if let Ok(mut lock) = key_buf1.lock() {
|
.await;
|
||||||
lock.replace(stuff);
|
if let Some(stuff) = data {
|
||||||
|
// If we have some data to show, we *must* lock
|
||||||
|
if let Ok(mut lock) = key_buf1.lock() {
|
||||||
|
lock.replace(stuff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
let supported = Vec::from(laptop.supported_modes());
|
||||||
// When any action occurs this time is reset
|
// When any action occurs this time is reset
|
||||||
let mut time_mark = Instant::now();
|
let mut time_mark = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
// Timing is such that:
|
|
||||||
// - interrupt write is minimum 1ms (sometimes lower)
|
|
||||||
// - read interrupt must timeout, minimum of 1ms
|
|
||||||
// - for a single usb packet, 2ms total.
|
|
||||||
// - to maintain constant times of 1ms, per-key colours should use
|
|
||||||
// the effect endpoint so that the complete colour block is written
|
|
||||||
// as fast as 1ms per row of the matrix inside it. (10ms total time)
|
|
||||||
|
|
||||||
// DBUS processing takes 6ms....
|
|
||||||
connection.process_all();
|
connection.process_all();
|
||||||
|
|
||||||
// 700u per write
|
|
||||||
if let Ok(mut lock) = input.try_lock() {
|
if let Ok(mut lock) = input.try_lock() {
|
||||||
if let Some(bytes) = &*lock {
|
if let Some(bytes) = &*lock {
|
||||||
// It takes up to 20 milliseconds to write a complete colour block here
|
// It takes up to 20 milliseconds to write a complete colour block here
|
||||||
@@ -202,3 +127,84 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dbus_create_ledmsg_method(msg: LedMsgType) -> Method<MTSync, ()> {
|
||||||
|
let factory = Factory::new_sync::<()>();
|
||||||
|
factory
|
||||||
|
// method for ledmessage
|
||||||
|
.method("ledmessage", (), {
|
||||||
|
move |m| {
|
||||||
|
let bytes: Vec<u8> = m.msg.read1()?;
|
||||||
|
if let Ok(mut lock) = msg.try_lock() {
|
||||||
|
*lock = Some(bytes.to_vec());
|
||||||
|
let mret = m
|
||||||
|
.msg
|
||||||
|
.method_return()
|
||||||
|
.append1(&format!("Wrote {:x?}", bytes));
|
||||||
|
return Ok(vec![mret]);
|
||||||
|
} else {
|
||||||
|
return Err(MethodErr::failed("Could not lock daemon for access"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.outarg::<&str, _>("reply")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dbus_create_ledeffect_method(effect: EffectType) -> Method<MTSync, ()> {
|
||||||
|
let factory = Factory::new_sync::<()>();
|
||||||
|
factory
|
||||||
|
// method for ledmessage
|
||||||
|
.method("ledeffect", (), {
|
||||||
|
move |m| {
|
||||||
|
if let Ok(mut lock) = effect.try_lock() {
|
||||||
|
let mut iter = m.msg.iter_init();
|
||||||
|
let byte_array: Vec<Vec<u8>> = vec![
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
iter.read()?,
|
||||||
|
];
|
||||||
|
|
||||||
|
*lock = Some(byte_array);
|
||||||
|
let mret = m.msg.method_return().append1(&format!("Got effect part"));
|
||||||
|
return Ok(vec![mret]);
|
||||||
|
} else {
|
||||||
|
return Err(MethodErr::failed("Could not lock daemon for access"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.outarg::<&str, _>("reply")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
.inarg::<Vec<u8>, _>("bytearray")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dbus_create_tree() -> (Tree<MTSync, ()>, LedMsgType, EffectType) {
|
||||||
|
let input: LedMsgType = Arc::new(Mutex::new(None));
|
||||||
|
let effect: EffectType = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
|
let factory = Factory::new_sync::<()>();
|
||||||
|
let tree = factory.tree(()).add(
|
||||||
|
factory.object_path(DBUS_PATH, ()).add(
|
||||||
|
factory
|
||||||
|
.interface(DBUS_IFACE, ())
|
||||||
|
.add_m(dbus_create_ledmsg_method(input.clone()))
|
||||||
|
.add_m(dbus_create_ledeffect_method(effect.clone())),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
(tree, input, effect)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user