diff --git a/Cargo.lock b/Cargo.lock index bfab111..b3bb41e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "anyhow" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" + [[package]] name = "dbus" version = "0.8.2" @@ -35,5 +41,6 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" name = "telepathy-delta" version = "0.1.0" dependencies = [ + "anyhow", "dbus", ] diff --git a/Cargo.toml b/Cargo.toml index e756ac6..495ee93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0" dbus = "0.8.2" diff --git a/README.md b/README.md index 44e78b6..61842ae 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ Authored by [Nick Thomas](https://ur.gs) under the [MIT License](LICENSE). over multiple IM protocols. This project glues the two together, allowing Telepathy clients to send/receive Delta messages. +Telepathy CMs should have a name that is not the same as their protocol; so this +CM is hereby named "padfoot". + ## Why Mobile IM, mostly. Desktop IM, also. It's ideal for my pinephone, and lighter diff --git a/src/delta.rs b/src/delta.rs new file mode 100644 index 0000000..3c6feb2 --- /dev/null +++ b/src/delta.rs @@ -0,0 +1,5 @@ +mod connection_manager; +pub use self::connection_manager::*; + +mod protocol; +pub use self::protocol::*; diff --git a/src/delta/connection_manager.rs b/src/delta/connection_manager.rs new file mode 100644 index 0000000..edc2db0 --- /dev/null +++ b/src/delta/connection_manager.rs @@ -0,0 +1,62 @@ +use crate::telepathy; +use dbus::{arg, tree}; +use std::collections::HashMap; + +#[derive(Debug)] +pub struct ConnectionManager {} + +#[derive(Copy, Clone, Default, Debug)] +pub struct CMData; + +impl dbus::tree::DataType for CMData { + type Tree = (); + type Property = (); + type Interface = (); + type Method = (); + type Signal = (); + type ObjectPath = std::sync::Arc; +} + +const PROTO: &'static str = "delta"; + +impl telepathy::ConnectionManager for ConnectionManager { + fn get_parameters( + &self, + protocol: &str, + ) -> Result< + Vec<( + String, + u32, + String, + arg::Variant>, + )>, + tree::MethodErr, + > { + Err(tree::MethodErr::no_arg()) + } + + fn list_protocols(&self) -> Result, tree::MethodErr> { + Ok(vec![PROTO.to_string()]) + } + + fn request_connection( + &self, + protocol: &str, + parameters: HashMap<&str, arg::Variant>>, + ) -> Result<(String, dbus::Path<'static>), tree::MethodErr> { + Err(tree::MethodErr::no_arg()) + } + + fn protocols( + &self, + ) -> Result< + HashMap>>>, + tree::MethodErr, + > { + Err(tree::MethodErr::no_arg()) + } + + fn interfaces(&self) -> Result, tree::MethodErr> { + Err(tree::MethodErr::no_arg()) + } +} diff --git a/src/delta/protocol.rs b/src/delta/protocol.rs new file mode 100644 index 0000000..3dbbcdd --- /dev/null +++ b/src/delta/protocol.rs @@ -0,0 +1 @@ +pub struct Protocol {} diff --git a/src/main.rs b/src/main.rs index e43f084..1449bc5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,73 @@ +mod delta; mod telepathy; -fn main() { - println!("Hello, world!"); +//use dbus::tree::{Interface, MTFn, MethodErr}; +use dbus::{ + blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection}, + tree::{Factory, Interface, MTFn, Tree}, +}; + +use delta::{CMData, ConnectionManager}; + +use std::sync::Arc; +use std::time::Duration; + +use anyhow::{anyhow, Result}; + +const BUS_NAME: &'static str = "org.freedesktop.Telepathy.ConnectionManager.delta"; +const OBJECT_PATH: &'static str = "/org/freedesktop/Telepathy/ConnectionManager/delta"; + +fn create_tree(cm: &Arc) -> Tree, CMData> { + let f = Factory::new_fn(); + let mut tree = f.tree(()); + + let iface = telepathy::connection_manager_server(&f, (), |m| { + let a: &Arc = m.path.get_data(); + let b: &ConnectionManager = &a; + + b + }); + + tree = tree.add( + f.object_path(OBJECT_PATH, cm.clone()) + .introspectable() + .add(iface), + ); + tree = tree.add(f.object_path("/", cm.clone()).introspectable()); + + tree +} + +fn run() -> Result<()> { + let cm: ConnectionManager = ConnectionManager {}; + let tree = create_tree(&Arc::new(cm)); + + // Setup DBus connection + let mut c = LocalConnection::new_session()?; + + let result = c.request_name(BUS_NAME, false, false, true)?; + match result { + RequestNameReply::Exists => { + return Err(anyhow!( + "Another process is already registered on {}", + BUS_NAME + )) + } + _ => {} // All other responses we can get are a success + }; + + println!("Bus registered: {}", BUS_NAME); + tree.start_receive(&c); + + loop { + c.process(Duration::from_secs(1))?; + println!("Tick"); + } +} + +fn main() { + if let Err(e) = run() { + println!("{}", e); + std::process::exit(1); + } }