Check inotify paths are valid. Add dgu/egpu/ac_online checks

This commit is contained in:
Luke D. Jones
2022-09-24 14:34:15 +12:00
parent 30550aaa91
commit 7939b00aa3
17 changed files with 210 additions and 43 deletions

View File

@@ -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
View File

@@ -572,7 +572,7 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
[[package]]
name = "daemon"
version = "4.5.0-rc2"
version = "4.5.0-rc3"
dependencies = [
"async-trait",
"concat-idents",

View File

@@ -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(())

View File

@@ -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>"]

View File

@@ -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(())

View File

@@ -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(())
}

View File

@@ -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);
}
}

View File

@@ -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(())
}

View File

@@ -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,
},

View File

@@ -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);

View File

@@ -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<()>;
}

View File

@@ -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<()>;
}

View File

@@ -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)
}
}

View File

@@ -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))
}
}

View File

@@ -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)]

View File

@@ -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)))
}
});
};

View File

@@ -102,4 +102,5 @@ impl AsusPower {
}
attr_u8!("charge_control_end_threshold", battery);
attr_u8!("online", mains);
}