mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Add initial dbus draft of asus_armoury attrs
This commit is contained in:
90
asusd/src/asus_armoury/attr_enum_int.rs
Normal file
90
asusd/src/asus_armoury/attr_enum_int.rs
Normal 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
|
||||
})?)
|
||||
}
|
||||
}
|
||||
95
asusd/src/asus_armoury/attr_enum_str.rs
Normal file
95
asusd/src/asus_armoury/attr_enum_str.rs
Normal 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
|
||||
})?)
|
||||
}
|
||||
}
|
||||
105
asusd/src/asus_armoury/attr_int.rs
Normal file
105
asusd/src/asus_armoury/attr_int.rs
Normal 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
|
||||
})?)
|
||||
}
|
||||
}
|
||||
33
asusd/src/asus_armoury/mod.rs
Normal file
33
asusd/src/asus_armoury/mod.rs
Normal 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(())
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
Reference in New Issue
Block a user