Add initial dbus interface xml descripiton.

Much of this will change, but needed something to start with.
Based on notes at https://gitlab.steamos.cloud/jupiter/tasks/-/issues/894
Use objectserver to get introspection done for us.
Change to session bus for now since system bus will need
a config file to allow us to take the name. Will add later.
Implement one quick say_hello dbus method to start.
Add copyright headers.
This commit is contained in:
Jeremy Whiting 2023-09-22 14:52:07 -06:00
parent 302fe3c063
commit 701ff23987
5 changed files with 347 additions and 31 deletions

View file

@ -9,3 +9,4 @@ edition = "2021"
async-std = { version = "1.12.0", features = ["attributes"] }
serde = { version = "1.0.188", features = ["derive"] }
zbus = "3.14.1"
zbus_macros = "3.14.1"

View file

@ -0,0 +1,226 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!--
Copyright © 2023 Collabora Ltd.
SPDX-License-Identifier: MIT
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<!--
com.steampowered.SteamOSManager1
@short_description: Interface to control various aspects of SteamOS
-->
<interface name="com.steampowered.SteamOSManager1">
<!--
Version:
The version of this interface implemented by this object.
This file documents version 1 of the interface.
-->
<property name="Version" type="u" access="read"/>
<!--
FactoryReset:
@success: True on success (should reboot next, to finish the reset.). False otherwise.
Perform factory reset of device.
runs steamos-factory-reset script for now.
Returns true on success, false on failure.
-->
<method name="FactoryReset">
<arg type="b" name="success" direction="out"/>
</method>
<!--
DisableWifiPowerManagement:
Disable wifi chip's powermanagement.
-->
<method name="DisableWifiPowerManagement">
</method>
<!--
EnableFanControl:
@enable: Whether fan control should be enabled.
-->
<method name="EnableFanControl">
<arg type="b" name="enable" direction="in"/>
</method>
<!--
HardwareCheckSupport:
@supported: True if all hardware is supported. False otherwise.
Checks for unsupported hardware.
-->
<method name="HardwareCheckSupport">
<arg type="b" name="supported" direction="out"/>
</method>
<!--
ReadALSCalibration:
@gain: The gain from the ALS calibration, in floating point.
Read ALS calibration value.
Note: Will give -1.0 on error running script.
-->
<method name="ReadALSCalibration">
<arg type="d" name="gain" direction="out"/>
</method>
<!--
UpdateBIOS:
@success: True on bios update success. False otherwise.
Perform a bios update.
-->
<method name="UpdateBIOS">
<arg type="b" name="success" direction="out"/>
</method>
<!--
UpdateDock:
@success: True on dock update script success. False otherwise.
Perform a dock firmware update.
-->
<method name="UpdateDock">
<arg type="b" name="success" direction="out"/>
</method>
<!--
TrimDevices:
@success: True on script success. False otherwise.
Perform fstrim on disk devices.
-->
<method name="TrimDevices">
<arg type="b" name="success" direction="out"/>
</method>
<!--
FormatSDCard:
@success: True on script success. False otherwise.
Format the inserted sd card.
-->
<method name="FormatSDCard">
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetGPUPerformanceLevel:
@level: The level to use (TODO: Fill in range here and also check it in code?)
@auto: True if we should set back to auto. False to use level above.
@success: True on success. False otherwise.
Set the GPU performance level to the given value.
-->
<method name="SetGPUPerformanceLevel">
<arg type="i" name="level" direction="in"/>
<arg type="b" name="auto" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetGPUClocks:
@clocks: The clocks to use.
@clear: True if we should clear to go back to defaults. False to use clocks above.
@success: True on success. False otherwise.
Set the GPU clocks to the given value.
-->
<method name="SetGPUClocks">
<arg type="i" name="clocks" direction="in"/>
<arg type="b" name="clear" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetTDPLimit:
@limit: The upper limit to use.
@success: True on success. False otherwise.
Set the TDP limit to the given value.
-->
<method name="SetTDPLimit">
<arg type="i" name="limit" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetBacklight:
@value: The backlight brightness value to use.
@success: True on success. False otherwise.
Set the backlight brightness to the given value.
-->
<method name="SetBacklight">
<arg type="i" name="value" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetALSIntegrationTime:
@seconds: The number of seconds to use for ALS integration.
@success: True on success. False otherwise.
Set the ALS integration time to the given value.
-->
<method name="SetALSIntegrationTime">
<arg type="i" name="seconds" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetLEDBrightness
@value: The value to usse for LED brightness.
@success: True on success. False otherwise.
Set the LED brightness to the given value.
-->
<method name="SetLEDBrightness">
<arg type="i" name="value" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
<!--
SetContentAdaptiveBrightness
@value: The value to usse for content adaptive brightness.
@success: True on success. False otherwise.
Set the content adaptive brightness to the given value.
-->
<method name="SetContentAdaptiveBrightness">
<arg type="i" name="value" direction="in"/>
<arg type="b" name="success" direction="out"/>
</method>
</interface>
</node>

View file

@ -1,19 +1,47 @@
use std::{fs, io};
/*
* Copyright © 2023 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
use std::fs;
use std::{error::Error, future::pending};
use std::collections::HashMap;
use std::convert::TryFrom;
use serde::{Serialize, Deserialize};
use zbus::{Connection, ConnectionBuilder, Result, dbus_interface, zvariant::Value};
use zbus::{Connection, ConnectionBuilder, Result, dbus_interface, zvariant::{from_slice, to_bytes, EncodingContext, Value}};
pub mod manager;
// We use s(teamos)m(anager) prefix on all types to help avoid conflicts
// Types of api we support, so far only dbus and script.
// For dbus type we call into other dbus apis specified.
// For script type we run a script and provide stdout, stderr, and exitcode back.
// For SysFS type we manipulate sys fs values, on/off or setting a specific value
#[derive(Serialize, Deserialize, Debug)]
pub enum SmApiType {
DBusType = 0,
ScriptType = 1,
SysFSType = 2,
}
// SmDBusApi represents a dbus api to be called
@ -31,13 +59,21 @@ pub struct SmDbusApi {
pub struct SmScript {
path: String
}
// SmSysfs represents a read/write to a sysfs path or paths
#[derive(Serialize, Deserialize, Debug)]
pub struct SmSysfs {
path: String,
// value: zbus::zvariant::Value<'a>
}
// An SmOperation is what happens when an incoming dbus method is called.
// If the SmEntry type is DBusType this should be a DBusApi with the data neede.
// Otherwise it should be a script with the path to execute
#[derive(Serialize, Deserialize, Debug)]
pub enum SmOperation {
SmScript(String),
SmDbusApi(String, String, String)
SmDbusApi(String, String, String),
// SmSysfs(String, zbus::zvariant::Value)
}
// Each api config file contains one or more entries.
@ -48,12 +84,12 @@ pub struct SmEntry {
outgoing: SmOperation, // TBD: Either the outgoing zbus method or a script to run
}
pub fn initialize_apis(path: String) -> Result<(Vec::<SmEntry>)>
pub fn initialize_apis(path: String) -> Result<Vec::<SmEntry>>
{
let res = Vec::<SmEntry>::new();
for file in fs::read_dir(path)? {
// for file in fs::read_dir(path)? {
// Deserialize the file and add SmEntry to res
}
// }
return Ok(res);
}
@ -61,10 +97,10 @@ pub fn create_dbus_apis(connection: zbus::Connection, entries: Vec::<SmEntry>) -
{
// Create each of the given apis as dbus methods that users, etc.
// can use to call into us.
for api in entries
{
// for api in entries
// {
//
}
// }
return true;
}

View file

@ -1,33 +1,48 @@
use std::io::ErrorKind;
/*
* Copyright © 2023 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
use zbus::{ConnectionBuilder, Result};
use steamos_manager::*;
use zbus::{Connection, Result};
#[async_std::main]
async fn main() -> Result<()>
{
// This daemon is responsible for creating a dbus api that steam client can use to do various OS
// level things (change brightness, etc.) In order to do that it reads a folder of dbus api
// configuration files and exposes each configuration with the api in the config file. In order
// to know what to do with each it gets the information from the same config file about whether
// to run a script or call some other dbus api.
// level things. It implements com.steampowered.SteamOSManager1 interface
let session_connection = Connection::session().await?;
session_connection.request_name("com.steampowered.SteamOSManager").await?;
let manager = manager::SMManager {};
let result = initialize_apis("/usr/share/steamos-manager".to_string());
match result {
Ok(manager_apis) => {
let worked: bool = create_dbus_apis(session_connection, manager_apis);
}
Err(error) => {
println!("There was an error reading configuration files, doing nothing. {:?}", error);
}
}
let _system_connection = ConnectionBuilder::session()?
.name("com.steampowered.SteamOSManager1")?
.serve_at("/com/steampowered/SteamOSManager1", manager)?
.build()
.await?;
loop
{
std::future::pending::<()>().await;
}
}

38
src/manager.rs Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright © 2023 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
use zbus_macros::dbus_interface;
use zbus::{ObjectServer, SignalContext, MessageHeader};
pub struct SMManager {
}
#[dbus_interface(name = "com.steampowered.SteamOSManager1")]
impl SMManager {
async fn say_hello(&self, name: &str) -> String {
format!("Hello {}!", name)
}
}