mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Check inotify paths are valid. Add dgu/egpu/ac_online checks
This commit is contained in:
@@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- `platform_profile`
|
||||
- keyboard brightness
|
||||
- These allow for updating any associated config and sending dbus notifications.
|
||||
- New dbus methods
|
||||
- `DgpuDisable`
|
||||
- `SetDgpuDisable`
|
||||
- `NotifyDgpuDisable`
|
||||
- `EgpuEnable`
|
||||
- `SetEgpuEnable`
|
||||
- `NotifyEgpuEnable`
|
||||
- `MainsOnline` (This is AC, check if plugged in or not)
|
||||
- `NotifyMainsOnline`
|
||||
### Changed
|
||||
- Use loops to ensure that mutex is gained for LED changes.
|
||||
- asusctl now uses tokio for async runtime. This helps simplify some code.
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -572,7 +572,7 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||
|
||||
[[package]]
|
||||
name = "daemon"
|
||||
version = "4.5.0-rc2"
|
||||
version = "4.5.0-rc3"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"concat-idents",
|
||||
|
||||
@@ -54,7 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
p.for_each(|e| {
|
||||
if let Ok(out) = e.args() {
|
||||
if let Ok(ref mut lock) = x.try_lock() {
|
||||
notify!(do_post_sound_notif, lock, &out.sound());
|
||||
notify!(do_post_sound_notif, lock, &out.on());
|
||||
}
|
||||
}
|
||||
future::ready(())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "daemon"
|
||||
version = "4.5.0-rc2"
|
||||
version = "4.5.0-rc3"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -225,7 +225,7 @@ impl CtrlPlatform {
|
||||
.platform
|
||||
.get_panel_od()
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: get panel overdrive {}", err);
|
||||
warn!("CtrlRogBios: get_panel_od {}", err);
|
||||
err
|
||||
})
|
||||
.unwrap_or(false);
|
||||
@@ -239,6 +239,73 @@ impl CtrlPlatform {
|
||||
#[dbus_interface(signal)]
|
||||
async fn notify_panel_od(signal_ctxt: &SignalContext<'_>, overdrive: bool) -> zbus::Result<()> {
|
||||
}
|
||||
|
||||
async fn set_dgpu_disable(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||
disable: bool,
|
||||
) {
|
||||
if self
|
||||
.platform
|
||||
.set_dgpu_disable(disable)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: set_dgpu_disable {}", err);
|
||||
err
|
||||
})
|
||||
.is_ok()
|
||||
{
|
||||
Self::notify_dgpu_disable(&ctxt, disable).await.ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn dgpu_disable(&self) -> bool {
|
||||
self.platform
|
||||
.get_dgpu_disable()
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: get_dgpu_disable {}", err);
|
||||
err
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn notify_dgpu_disable(
|
||||
signal_ctxt: &SignalContext<'_>,
|
||||
disable: bool,
|
||||
) -> zbus::Result<()> {
|
||||
}
|
||||
|
||||
async fn set_egpu_enable(
|
||||
&mut self,
|
||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||
enable: bool,
|
||||
) {
|
||||
if self
|
||||
.platform
|
||||
.set_egpu_enable(enable)
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: set_egpu_enable {}", err);
|
||||
err
|
||||
})
|
||||
.is_ok()
|
||||
{
|
||||
Self::notify_egpu_enable(&ctxt, enable).await.ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn egpu_enable(&self) -> bool {
|
||||
self.platform
|
||||
.get_egpu_enable()
|
||||
.map_err(|err| {
|
||||
warn!("CtrlRogBios: get_egpu_enable {}", err);
|
||||
err
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn notify_egpu_enable(signal_ctxt: &SignalContext<'_>, enable: bool) -> zbus::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -265,6 +332,8 @@ impl crate::Reloadable for CtrlPlatform {
|
||||
|
||||
impl CtrlPlatform {
|
||||
task_watch_item!(panel_od platform);
|
||||
task_watch_item!(dgpu_disable platform);
|
||||
task_watch_item!(egpu_enable platform);
|
||||
task_watch_item!(gpu_mux_mode platform);
|
||||
}
|
||||
|
||||
@@ -312,6 +381,8 @@ impl CtrlTask for CtrlPlatform {
|
||||
.await;
|
||||
|
||||
self.watch_panel_od(signal_ctxt.clone()).await?;
|
||||
self.watch_dgpu_disable(signal_ctxt.clone()).await?;
|
||||
self.watch_egpu_enable(signal_ctxt.clone()).await?;
|
||||
self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -7,6 +7,7 @@ use rog_platform::supported::ChargeSupportedFunctions;
|
||||
use std::sync::Arc;
|
||||
use zbus::dbus_interface;
|
||||
use zbus::export::futures_util::lock::Mutex;
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
use zbus::Connection;
|
||||
use zbus::SignalContext;
|
||||
|
||||
@@ -74,11 +75,23 @@ impl CtrlPower {
|
||||
}
|
||||
}
|
||||
|
||||
fn mains_online(&self) -> bool {
|
||||
if self.power.has_online() {
|
||||
if let Ok(v) = self.power.get_online() {
|
||||
return v == 1;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn notify_charge_control_end_threshold(
|
||||
ctxt: &SignalContext<'_>,
|
||||
limit: u8,
|
||||
) -> zbus::Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn notify_mains_online(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -167,7 +180,29 @@ impl CtrlTask for CtrlPower {
|
||||
)
|
||||
.await;
|
||||
|
||||
self.watch_charge_control_end_threshold(signal_ctxt).await?;
|
||||
self.watch_charge_control_end_threshold(signal_ctxt.clone())
|
||||
.await?;
|
||||
|
||||
let ctrl = self.clone();
|
||||
match ctrl.power.monitor_online() {
|
||||
Ok(mut watch) => {
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
watch
|
||||
.event_stream(&mut buffer)
|
||||
.unwrap()
|
||||
.for_each(|_| async {
|
||||
if let Ok(value) = ctrl.power.get_online() {
|
||||
Self::notify_mains_online(&signal_ctxt, value == 1)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
})
|
||||
.await;
|
||||
});
|
||||
}
|
||||
Err(e) => info!("inotify watch failed: {}", e),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
start_tasks(zbus, &mut connection).await?;
|
||||
}
|
||||
Err(err) => {
|
||||
error!("AniMe control: {}", err);
|
||||
info!("AniMe control: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,16 +56,20 @@ macro_rules! task_watch_item {
|
||||
|
||||
let ctrl = self.clone();
|
||||
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
||||
let mut watch = self.$self_inner.watch_fn()?;
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
watch.event_stream(&mut buffer).unwrap().for_each(|_| async {
|
||||
let value = ctrl.$name();
|
||||
concat_idents::concat_idents!(notif_fn = notify_, $name {
|
||||
Self::notif_fn(&signal_ctxt, value).await.unwrap();
|
||||
match self.$self_inner.watch_fn() {
|
||||
Ok(mut watch) => {
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
watch.event_stream(&mut buffer).unwrap().for_each(|_| async {
|
||||
let value = ctrl.$name();
|
||||
concat_idents::concat_idents!(notif_fn = notify_, $name {
|
||||
Self::notif_fn(&signal_ctxt, value).await.unwrap();
|
||||
});
|
||||
}).await;
|
||||
});
|
||||
}).await;
|
||||
});
|
||||
}
|
||||
Err(e) => info!("inotify watch failed: {}. You can ignore this if your device does not support the feature", e),
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ impl Bios {
|
||||
pub fn gpu_mux_mode(&self) -> Result<i16> {
|
||||
Ok(1)
|
||||
}
|
||||
pub fn panel_overdrive(&self) -> Result<i16> {
|
||||
pub fn panel_od(&self) -> Result<i16> {
|
||||
Ok(1)
|
||||
}
|
||||
pub fn set_post_boot_sound(&self, _b: bool) -> Result<()> {
|
||||
@@ -74,7 +74,7 @@ impl Bios {
|
||||
pub fn set_gpu_mux_mode(&self, _b: bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_panel_overdrive(&self, _b: bool) -> Result<()> {
|
||||
pub fn set_panel_od(&self, _b: bool) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -217,7 +217,7 @@ impl Supported {
|
||||
rog_bios_ctrl: RogBiosSupportedFunctions {
|
||||
post_sound: true,
|
||||
dedicated_gfx: true,
|
||||
panel_overdrive: true,
|
||||
panel_od: true,
|
||||
dgpu_disable: true,
|
||||
egpu_enable: true,
|
||||
},
|
||||
|
||||
@@ -70,7 +70,7 @@ pub fn start_notifications(
|
||||
if let Ok(out) = e.args() {
|
||||
if notifs_enabled1.load(Ordering::SeqCst) {
|
||||
if let Ok(ref mut lock) = last_notif.try_lock() {
|
||||
notify!(do_post_sound_notif, lock, &out.sound());
|
||||
notify!(do_post_sound_notif, lock, &out.on());
|
||||
}
|
||||
}
|
||||
bios_notified1.store(true, Ordering::SeqCst);
|
||||
|
||||
@@ -27,33 +27,53 @@ use zbus_macros::dbus_proxy;
|
||||
default_path = "/org/asuslinux/Platform"
|
||||
)]
|
||||
trait RogBios {
|
||||
/// DedicatedGraphicMode method
|
||||
/// DgpuDisable method
|
||||
fn dgpu_disable(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// EgpuEnable method
|
||||
fn egpu_enable(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// GpuMuxMode method
|
||||
fn gpu_mux_mode(&self) -> zbus::Result<GpuMode>;
|
||||
|
||||
/// PanelOd method
|
||||
fn panel_od(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// PostBootSound method
|
||||
fn post_boot_sound(&self) -> zbus::Result<i16>;
|
||||
|
||||
/// SetDedicatedGraphicMode method
|
||||
/// SetDgpuDisable method
|
||||
fn set_dgpu_disable(&self, disable: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SetEgpuEnable method
|
||||
fn set_egpu_enable(&self, enable: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SetGpuMuxMode method
|
||||
fn set_gpu_mux_mode(&self, mode: GpuMode) -> zbus::Result<()>;
|
||||
|
||||
/// SetPanelOd method
|
||||
fn set_panel_od(&self, overdrive: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SetPostBootSound method
|
||||
fn set_post_boot_sound(&self, on: bool) -> zbus::Result<()>;
|
||||
|
||||
/// PanelOverdrive method
|
||||
fn panel_od(&self) -> zbus::Result<bool>;
|
||||
/// NotifyDgpuDisable signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_dgpu_disable(&self, disable: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SetPanelOverdrive method
|
||||
fn set_panel_od(&self, overdrive: bool) -> zbus::Result<()>;
|
||||
/// NotifyEgpuEnable signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_egpu_enable(&self, enable: bool) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyDedicatedGraphicMode signal
|
||||
/// NotifyGpuMuxMode signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_gpu_mux_mode(&self, mode: GpuMode) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyPostBootSound signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_post_boot_sound(&self, sound: bool) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyPanelOverdrive signal
|
||||
/// NotifyPanelOd signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_panel_od(&self, overdrive: bool) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyPostBootSound signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_post_boot_sound(&self, on: bool) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
@@ -29,10 +29,17 @@ trait Power {
|
||||
/// charge_control_end_threshold method
|
||||
fn charge_control_end_threshold(&self) -> zbus::Result<u8>;
|
||||
|
||||
/// MainsOnline method
|
||||
fn mains_online(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// set_charge_control_end_threshold method
|
||||
fn set_charge_control_end_threshold(&self, limit: u8) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyCharge signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_charge_control_end_threshold(&self, limit: u8) -> zbus::Result<u8>;
|
||||
|
||||
/// NotifyMainsOnline signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_mains_online(&self, on: bool) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ pub enum PlatformError {
|
||||
AttrNotFound(String),
|
||||
MissingFunction(String),
|
||||
MissingLedBrightNode(String, std::io::Error),
|
||||
Io(String, std::io::Error),
|
||||
IoPath(String, std::io::Error),
|
||||
Io(std::io::Error),
|
||||
NoAuraKeyboard,
|
||||
NoAuraNode,
|
||||
}
|
||||
@@ -33,9 +34,10 @@ impl fmt::Display for PlatformError {
|
||||
PlatformError::Write(path, error) => write!(f, "Write {}: {}", path, error),
|
||||
PlatformError::NotSupported => write!(f, "Not supported"),
|
||||
PlatformError::AttrNotFound(deets) => write!(f, "Attribute not found: {}", deets),
|
||||
PlatformError::Io(deets) => write!(f, "std::io error: {}", deets),
|
||||
PlatformError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets),
|
||||
PlatformError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error),
|
||||
PlatformError::Io(path, detail) => write!(f, "std::io error: {} {}", path, detail),
|
||||
PlatformError::IoPath(path, detail) => write!(f, "{} {}", path, detail),
|
||||
PlatformError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"),
|
||||
PlatformError::NoAuraNode => write!(f, "No Aura keyboard node found"),
|
||||
}
|
||||
@@ -49,3 +51,9 @@ impl From<rusb::Error> for PlatformError {
|
||||
PlatformError::USB(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for PlatformError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
PlatformError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@ impl HidRaw {
|
||||
|
||||
for device in enumerator
|
||||
.scan_devices()
|
||||
.map_err(|e| PlatformError::Io("enumerator".to_owned(), e))?
|
||||
.map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))?
|
||||
{
|
||||
if let Some(parent) = device
|
||||
.parent_with_subsystem_devtype("usb", "usb_device")
|
||||
.map_err(|e| PlatformError::Io(device.devpath().to_string_lossy().to_string(), e))?
|
||||
.map_err(|e| {
|
||||
PlatformError::IoPath(device.devpath().to_string_lossy().to_string(), e)
|
||||
})?
|
||||
{
|
||||
if let Some(parent) = parent.attribute_value("idProduct") {
|
||||
if parent == id_product {
|
||||
@@ -47,9 +49,9 @@ impl HidRaw {
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.open(&self.0)
|
||||
.map_err(|e| PlatformError::Io(self.0.to_string_lossy().to_string(), e))?;
|
||||
.map_err(|e| PlatformError::IoPath(self.0.to_string_lossy().to_string(), e))?;
|
||||
// println!("write: {:02x?}", &message);
|
||||
file.write_all(message)
|
||||
.map_err(|e| PlatformError::Io(self.0.to_string_lossy().to_string(), e))
|
||||
.map_err(|e| PlatformError::IoPath(self.0.to_string_lossy().to_string(), e))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ pub fn read_attr_bool(device: &Device, attr_name: &str) -> Result<bool> {
|
||||
pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<()> {
|
||||
device
|
||||
.set_attribute_value(attr, &(value as u8).to_string())
|
||||
.map_err(|e| PlatformError::Io(attr.into(), e))
|
||||
.map_err(|e| PlatformError::IoPath(attr.into(), e))
|
||||
}
|
||||
|
||||
pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> {
|
||||
@@ -59,7 +59,7 @@ pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> {
|
||||
pub fn write_attr_u8(device: &mut Device, attr: &str, value: u8) -> Result<()> {
|
||||
device
|
||||
.set_attribute_value(attr, &(value).to_string())
|
||||
.map_err(|e| PlatformError::Io(attr.into(), e))
|
||||
.map_err(|e| PlatformError::IoPath(attr.into(), e))
|
||||
}
|
||||
|
||||
pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result<Vec<u8>> {
|
||||
@@ -79,7 +79,7 @@ pub fn write_attr_u8_array(device: &mut Device, attr: &str, values: &[u8]) -> Re
|
||||
let tmp = tmp.trim();
|
||||
device
|
||||
.set_attribute_value(attr, &tmp)
|
||||
.map_err(|e| PlatformError::Io(attr.into(), e))
|
||||
.map_err(|e| PlatformError::IoPath(attr.into(), e))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -21,9 +21,19 @@ macro_rules! watch_attr {
|
||||
pub fn fn_name(&self) -> Result<inotify::Inotify> {
|
||||
let mut path = self.$item.clone();
|
||||
path.push($attr_name);
|
||||
let mut inotify = inotify::Inotify::init().unwrap();
|
||||
inotify.add_watch(path.to_str().unwrap(), inotify::WatchMask::MODIFY).unwrap();
|
||||
Ok(inotify)
|
||||
if let Some(path) = path.to_str() {
|
||||
let mut inotify = inotify::Inotify::init()?;
|
||||
inotify.add_watch(path, inotify::WatchMask::MODIFY)
|
||||
.map_err(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
PlatformError::AttrNotFound(format!("{}", $attr_name))
|
||||
} else {
|
||||
PlatformError::IoPath(format!("{}", path), e)
|
||||
}
|
||||
})?;
|
||||
return Ok(inotify);
|
||||
}
|
||||
Err(PlatformError::AttrNotFound(format!("{}", $attr_name)))
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -102,4 +102,5 @@ impl AsusPower {
|
||||
}
|
||||
|
||||
attr_u8!("charge_control_end_threshold", battery);
|
||||
attr_u8!("online", mains);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user