From 09d58154eb9fe01d40949b7469d124b146e46101 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sat, 19 Apr 2025 21:51:44 +0200 Subject: [PATCH] First DBUS server --- Cargo.lock | 265 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 ++ build.rs | 27 ++++ dbus/com.example.mytest.xml | 16 +++ flake.nix | 11 +- src/main.rs | 96 ++++++++++++- src/mytest/mod.rs | 1 + 7 files changed, 419 insertions(+), 6 deletions(-) create mode 100644 build.rs create mode 100644 dbus/com.example.mytest.xml create mode 100644 src/mytest/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 339ebff..d684d08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,271 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys", +] + +[[package]] +name = "clap" +version = "4.5.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "dbus" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +dependencies = [ + "libc", + "libdbus-sys", + "winapi", +] + [[package]] name = "dbus-ai" version = "0.1.0" +dependencies = [ + "dbus", + "dbus-codegen", + "dbus-tree", +] + +[[package]] +name = "dbus-codegen" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf7b8c78e020d2eb0bb7ad986a86c5e5477d66d3cb13ea23a0faf896dd72a1db" +dependencies = [ + "clap", + "dbus", + "xml-rs", +] + +[[package]] +name = "dbus-tree" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f456e698ae8e54575e19ddb1f9b7bce2298568524f215496b248eb9498b4f508" +dependencies = [ + "dbus", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libdbus-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "xml-rs" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" diff --git a/Cargo.toml b/Cargo.toml index 9ac91af..72f93cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,12 @@ version = "0.1.0" edition = "2024" authors = ["Florian RICHER "] publish = false +build = "build.rs" + +[dependencies] +dbus = "0.9" +dbus-codegen = "0.12" +dbus-tree = "0.9" + +[build-dependencies] +dbus-codegen = "0.12" \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..be0ee44 --- /dev/null +++ b/build.rs @@ -0,0 +1,27 @@ +use dbus_codegen::{GenOpts, generate}; +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::Path; + +fn write_to_file(code: &str, path: &Path) { + let mut f = File::create(path).unwrap(); + Write::write_all(&mut f, code.as_bytes()).unwrap(); +} + +fn generate_code(xml: &str, opts: &GenOpts, outfile: &str) { + let code = generate(xml, opts).unwrap(); + let out_dir = env::var("OUT_DIR").unwrap(); + let path = Path::new(&out_dir).join(outfile); + println!("cargo::warning={:?}", path); + write_to_file(&code, &path); +} + +fn main() { + let opts = GenOpts::default(); + generate_code( + include_str!("dbus/com.example.mytest.xml"), + &opts, + "com_example_mytest.rs", + ); +} diff --git a/dbus/com.example.mytest.xml b/dbus/com.example.mytest.xml new file mode 100644 index 0000000..fbad3e3 --- /dev/null +++ b/dbus/com.example.mytest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/flake.nix b/flake.nix index 0511926..740abc7 100644 --- a/flake.nix +++ b/flake.nix @@ -17,13 +17,18 @@ pkgs = import nixpkgs { inherit system overlays; }; - rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + + nativeBuildInputs = with pkgs; [ + pkg-config + dbus + ]; in { devShells = { default = pkgs.mkShell { - nativeBuildInputs = [ - (rust.override { extensions = [ "rust-src" "rust-analyzer" ]; }) + nativeBuildInputs = nativeBuildInputs ++ [ + (rust.override { extensions = [ "rust-src" "rust-analyzer" ]; }) ]; }; }; diff --git a/src/main.rs b/src/main.rs index a2b27c4..8bc979d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,93 @@ -fn main() { - println!("Hello world"); -} \ No newline at end of file +use std::{cell::RefCell, sync::Arc}; + +use dbus::{Path, ffidisp::Connection}; +use dbus_tree::{self as tree, Interface, MTFn}; + +mod mytest; + +#[derive(Debug)] +struct Device { + pub name: RefCell, + pub path: Path<'static>, +} + +impl Device { + pub fn new(index: u32, name: String) -> Self { + Self { + name: RefCell::new(name), + path: format!("/Device{}", index).into(), + } + } +} + +impl mytest::ComExampleMytest for Device { + fn hello(&self, name: &str) -> Result { + Ok(format!("Hello, {}!", name)) + } + + fn name(&self) -> Result { + let name = self.name.borrow(); + + Ok(name.clone()) + } + + fn setname(&self, value: String) -> Result<(), tree::MethodErr> { + self.name.replace(value); + Ok(()) + } +} + +#[derive(Copy, Clone, Default, Debug)] +struct TData; +impl tree::DataType for TData { + type Tree = (); + type ObjectPath = Arc; + type Property = (); + type Interface = (); + type Method = (); + type Signal = (); +} + +fn create_iface() -> Interface, TData> { + let f = tree::Factory::new_fn(); + mytest::com_example_mytest_server(&f, (), |m| { + // Just provide a link from MethodInfo (m) to the &Device + // we should call. + let a: &Arc = m.path.get_data(); + let b: &Device = &a; + b + }) +} + +fn create_tree( + devices: &[Arc], + iface: &Arc, TData>>, +) -> tree::Tree, TData> { + let f = tree::Factory::new_fn(); + let mut tree = f.tree(()); + for dev in devices { + tree = tree.add( + f.object_path(dev.path.clone(), dev.clone()) + .introspectable() + .add(iface.clone()), + ); + } + tree +} + +fn main() -> Result<(), Box> { + let device = Arc::new(Device::new(0, format!("Device{}", 0))); + + // Create tree + let iface = create_iface(); + let tree = create_tree(&[device], &Arc::new(iface)); + + let c = Connection::new_session()?; + c.register_name("com.example.mytest", 0)?; + tree.set_registered(&c, true)?; + + c.add_handler(tree); + loop { + c.incoming(1000).next(); + } +} diff --git a/src/mytest/mod.rs b/src/mytest/mod.rs new file mode 100644 index 0000000..d77ac9c --- /dev/null +++ b/src/mytest/mod.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/com_example_mytest.rs"));