Add initial dbus draft of asus_armoury attrs

This commit is contained in:
Luke D. Jones
2024-12-25 20:37:36 +13:00
parent a7b98c67ee
commit 62aa1fe04f
9 changed files with 372 additions and 33 deletions

View File

@@ -0,0 +1,90 @@
use crate::{error::RogError, ASUS_ZBUS_PATH};
use log::error;
use rog_platform::firmware_attributes::{AttrValue, Attribute};
use serde::{Deserialize, Serialize};
use zbus::{
fdo, interface,
zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value},
Connection,
};
const MOD_NAME: &str = "asus_armoury";
#[derive(Debug, Default, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
pub struct PossibleValues {
strings: Vec<String>,
nums: Vec<i32>,
}
fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{attr_name}")).into()
}
pub struct AsusArmouryAttribute(Attribute);
impl AsusArmouryAttribute {
pub fn new(attr: Attribute) -> Self {
Self(attr)
}
pub async fn start_tasks(self, connection: &Connection) -> Result<(), RogError> {
// self.reload()
// .await
// .unwrap_or_else(|err| warn!("Controller error: {}", err));
let path = dbus_path_for_attr(self.0.name());
connection
.object_server()
.at(path.clone(), self)
.await
.map_err(|e| error!("Couldn't add server at path: {path}, {e:?}"))
.ok();
Ok(())
}
}
#[interface(name = "org.asuslinux.AsusArmoury")]
impl AsusArmouryAttribute {
#[zbus(property)]
async fn name(&self) -> String {
self.0.name().to_string()
}
#[zbus(property)]
async fn default_value(&self) -> i32 {
match self.0.default_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
}
#[zbus(property)]
async fn possible_values(&self) -> Vec<i32> {
match self.0.possible_values() {
AttrValue::EnumInt(i) => i.clone(),
_ => Vec::default(),
}
}
#[zbus(property)]
async fn current_value(&self) -> fdo::Result<i32> {
if let Ok(v) = self.0.current_value() {
if let AttrValue::Integer(i) = v {
return Ok(i);
}
}
Err(fdo::Error::Failed(
"Could not read current value".to_string(),
))
}
#[zbus(property)]
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
Ok(self
.0
.set_current_value(AttrValue::Integer(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
e
})?)
}
}

View File

@@ -0,0 +1,95 @@
use crate::{error::RogError, ASUS_ZBUS_PATH};
use log::error;
use rog_platform::firmware_attributes::{AttrType, AttrValue, Attribute};
use serde::{Deserialize, Serialize};
use zbus::{
fdo, interface,
zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value},
Connection,
};
const MOD_NAME: &str = "asus_armoury";
#[derive(Debug, Default, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
pub struct PossibleValues {
strings: Vec<String>,
nums: Vec<i32>,
}
fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{attr_name}")).into()
}
pub struct AsusArmouryAttribute(Attribute);
impl AsusArmouryAttribute {
pub fn new(attr: Attribute) -> Self {
Self(attr)
}
pub async fn start_tasks(self, connection: &Connection) -> Result<(), RogError> {
// self.reload()
// .await
// .unwrap_or_else(|err| warn!("Controller error: {}", err));
let path = dbus_path_for_attr(self.0.name());
connection
.object_server()
.at(path.clone(), self)
.await
.map_err(|e| error!("Couldn't add server at path: {path}, {e:?}"))
.ok();
Ok(())
}
}
#[interface(name = "org.asuslinux.AsusArmoury")]
impl AsusArmouryAttribute {
#[zbus(property)]
async fn name(&self) -> String {
self.0.name().to_string()
}
#[zbus(property)]
fn attribute_type(&self) -> AttrType {
self.0.attribute_type()
}
#[zbus(property)]
async fn default_value(&self) -> i32 {
match self.0.default_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
}
#[zbus(property)]
async fn possible_values(&self) -> Vec<String> {
match self.0.possible_values() {
AttrValue::EnumStr(s) => s.clone(),
_ => Vec::default(),
}
}
#[zbus(property)]
async fn current_value(&self) -> fdo::Result<String> {
if let Ok(v) = self.0.current_value() {
if let AttrValue::String(s) = v {
return Ok(s);
}
}
Err(fdo::Error::Failed(
"Could not read current value".to_string(),
))
}
#[zbus(property)]
async fn set_current_value(&mut self, value: String) -> fdo::Result<()> {
Ok(self
.0
.set_current_value(AttrValue::String(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
e
})?)
}
}

View File

@@ -0,0 +1,105 @@
use crate::{error::RogError, ASUS_ZBUS_PATH};
use log::error;
use rog_platform::firmware_attributes::{AttrValue, Attribute};
use serde::{Deserialize, Serialize};
use zbus::{
fdo, interface,
zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value},
Connection,
};
const MOD_NAME: &str = "asus_armoury";
#[derive(Debug, Default, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
pub struct PossibleValues {
strings: Vec<String>,
nums: Vec<i32>,
}
fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{attr_name}")).into()
}
pub struct AsusArmouryAttribute(Attribute);
impl AsusArmouryAttribute {
pub fn new(attr: Attribute) -> Self {
Self(attr)
}
pub async fn start_tasks(self, connection: &Connection) -> Result<(), RogError> {
// self.reload()
// .await
// .unwrap_or_else(|err| warn!("Controller error: {}", err));
let path = dbus_path_for_attr(self.0.name());
connection
.object_server()
.at(path.clone(), self)
.await
.map_err(|e| error!("Couldn't add server at path: {path}, {e:?}"))
.ok();
Ok(())
}
}
/// If return is `-1` on a property then there is avilable value for that property
#[interface(name = "org.asuslinux.AsusArmoury")]
impl AsusArmouryAttribute {
#[zbus(property)]
async fn name(&self) -> String {
self.0.name().to_string()
}
/// If return is `-1` then there is no default value
#[zbus(property)]
async fn default_value(&self) -> i32 {
match self.0.default_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
}
#[zbus(property)]
async fn min_value(&self) -> i32 {
match self.0.min_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
}
#[zbus(property)]
async fn max_value(&self) -> i32 {
match self.0.max_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
}
#[zbus(property)]
async fn scalar_increment(&self) -> i32 {
self.0.scalar_increment().unwrap_or(1)
}
#[zbus(property)]
async fn current_value(&self) -> fdo::Result<i32> {
if let Ok(v) = self.0.current_value() {
if let AttrValue::Integer(i) = v {
return Ok(i);
}
}
Err(fdo::Error::Failed(
"Could not read current value".to_string(),
))
}
#[zbus(property)]
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
Ok(self
.0
.set_current_value(AttrValue::Integer(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
e
})?)
}
}

View File

@@ -0,0 +1,33 @@
use rog_platform::firmware_attributes::{AttrType, FirmwareAttributes};
use zbus::Connection;
use crate::error::RogError;
pub mod attr_enum_int;
pub mod attr_enum_str;
pub mod attr_int;
pub async fn start_attributes_zbus(server: &Connection) -> Result<(), RogError> {
for attr in FirmwareAttributes::new().attributes() {
match attr.attribute_type() {
AttrType::MinMax => {
attr_int::AsusArmouryAttribute::new(attr.clone())
.start_tasks(server)
.await?;
}
AttrType::EnumInt => {
attr_enum_int::AsusArmouryAttribute::new(attr.clone())
.start_tasks(server)
.await?;
}
AttrType::EnumStr => {
attr_enum_str::AsusArmouryAttribute::new(attr.clone())
.start_tasks(server)
.await?;
}
AttrType::Unbounded => {}
}
}
Ok(())
}

View File

@@ -23,8 +23,9 @@ use crate::aura_scsi::trait_impls::ScsiZbus;
use crate::aura_slash::trait_impls::SlashZbus;
use crate::aura_types::DeviceHandle;
use crate::error::RogError;
use crate::ASUS_ZBUS_PATH;
pub const ASUS_ZBUS_PATH: &str = "/org/asuslinux";
const MOD_NAME: &str = "aura";
/// Returns only the Device details concatenated in a form usable for
/// adding/appending to a filename
@@ -54,26 +55,27 @@ pub fn filename_partial(parent: &Device) -> Option<OwnedObjectPath> {
fn dbus_path_for_dev(parent: &Device) -> Option<OwnedObjectPath> {
if let Some(filename) = filename_partial(parent) {
return Some(
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{filename}")).into(),
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{filename}"))
.into(),
);
}
None
}
fn dbus_path_for_tuf() -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/tuf")).into()
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/tuf")).into()
}
fn dbus_path_for_slash() -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/slash")).into()
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/slash")).into()
}
fn dbus_path_for_anime() -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/anime")).into()
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/anime")).into()
}
fn dbus_path_for_scsi(prod_id: &str) -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{prod_id}_scsi")).into()
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{prod_id}_scsi")).into()
}
fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
@@ -83,15 +85,6 @@ fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
false
}
// TODO:
// - make this the HID manager (and universal)
// - *really* need to make most of this actual kernel drivers
// - LED class
// - RGB modes (how, attribute?)
// - power features (how, attribute?)
// - what about per-key stuff?
// - how would the AniMe be exposed? Just a series of LEDs?
/// A device.
///
/// Each controller within should track its dbus path so it can be removed if

View File

@@ -4,6 +4,7 @@ use std::sync::Arc;
use ::zbus::export::futures_util::lock::Mutex;
use ::zbus::Connection;
use asusd::asus_armoury::start_attributes_zbus;
use asusd::aura_manager::DeviceManager;
use asusd::config::Config;
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
@@ -56,23 +57,20 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
// println!("{:?}", supported.supported_functions());
// Start zbus server
let mut connection = Connection::system().await?;
connection
.object_server()
.at("/", ObjectManager)
.await
.unwrap();
let mut server = Connection::system().await?;
server.object_server().at("/", ObjectManager).await.unwrap();
let config = Config::new().load();
let cfg_path = config.file_path();
let config = Arc::new(Mutex::new(config));
// supported.add_to_server(&mut connection).await;
start_attributes_zbus(&server).await?;
match CtrlFanCurveZbus::new() {
Ok(ctrl) => {
let sig_ctx = CtrlFanCurveZbus::signal_context(&connection)?;
start_tasks(ctrl, &mut connection, sig_ctx).await?;
let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?;
start_tasks(ctrl, &mut server, sig_ctx).await?;
}
Err(err) => {
error!("FanCurves: {}", err);
@@ -82,24 +80,24 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
match CtrlPlatform::new(
config.clone(),
&cfg_path,
CtrlPlatform::signal_context(&connection)?,
CtrlPlatform::signal_context(&server)?,
) {
Ok(ctrl) => {
let sig_ctx = CtrlPlatform::signal_context(&connection)?;
start_tasks(ctrl, &mut connection, sig_ctx).await?;
let sig_ctx = CtrlPlatform::signal_context(&server)?;
start_tasks(ctrl, &mut server, sig_ctx).await?;
}
Err(err) => {
error!("CtrlPlatform: {}", err);
}
}
let _ = DeviceManager::new(connection.clone()).await?;
let _ = DeviceManager::new(server.clone()).await?;
// Request dbus name after finishing initalizing all functions
connection.request_name(DBUS_NAME).await?;
server.request_name(DBUS_NAME).await?;
loop {
// This is just a blocker to idle and ensure the reator reacts
connection.executor().tick().await;
server.executor().tick().await;
}
}

View File

@@ -6,6 +6,7 @@ pub mod ctrl_fancurves;
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
pub mod ctrl_platform;
pub mod asus_armoury;
pub mod aura_anime;
pub mod aura_laptop;
pub mod aura_manager;
@@ -30,6 +31,8 @@ use zbus::Connection;
use crate::error::RogError;
const CONFIG_PATH_BASE: &str = "/etc/asusd/";
pub const ASUS_ZBUS_PATH: &str = "/org/asuslinux";
pub static DBUS_NAME: &str = "org.asuslinux.Daemon";
pub static DBUS_PATH: &str = "/org/asuslinux/Daemon";
pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";

View File

@@ -2,7 +2,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-12-24 22:29+0000\n"
"POT-Creation-Date: 2024-12-25 06:28+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use zbus::zvariant::Type;
use zbus::zvariant::{OwnedValue, Type, Value};
use crate::error::PlatformError;
@@ -31,7 +31,15 @@ fn read_string(path: &Path) -> Result<String, PlatformError> {
Ok(buf.trim().to_string())
}
#[derive(Debug, Default, PartialEq, PartialOrd)]
#[derive(Debug, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
pub enum AttrType {
MinMax = 0,
EnumInt = 1,
EnumStr = 2,
Unbounded = 3,
}
#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
pub enum AttrValue {
Integer(i32),
String(String),
@@ -41,7 +49,7 @@ pub enum AttrValue {
None,
}
#[derive(Debug, Default)]
#[derive(Debug, Default, Clone)]
pub struct Attribute {
name: String,
help: String,
@@ -62,6 +70,20 @@ impl Attribute {
&self.help
}
pub fn attribute_type(&self) -> AttrType {
let mut attr_type = AttrType::Unbounded;
match self.max_value {
AttrValue::Integer(_) => attr_type = AttrType::MinMax,
_ => {}
}
match self.possible_values {
AttrValue::EnumInt(_) => attr_type = AttrType::EnumInt,
AttrValue::EnumStr(_) => attr_type = AttrType::EnumStr,
_ => {}
}
attr_type
}
/// Read the `current_value` directly from the attribute path
pub fn current_value(&self) -> Result<AttrValue, PlatformError> {
match read_string(&self.base_path.join("current_value")) {