mod padfoot; mod telepathy; use anyhow::{anyhow, Result}; use dbus::{ blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection}, channel::Sender, tree::Factory, }; use padfoot::{ ConnectionManager, Protocol, CM_BUS_NAME, CM_CONN_BUS_NAME, CM_OBJECT_PATH, CONN_BUS_NAME, PROTO_BUS_NAME, PROTO_OBJECT_PATH, }; use std::sync::Arc; use std::time::Duration; #[derive(Debug, Default)] struct TData { cm: ConnectionManager, p: Protocol, } impl dbus::tree::DataType for TData { type Interface = Arc; type Tree = (); type Property = (); type ObjectPath = (); type Method = (); type Signal = (); } fn run() -> Result<()> { let (msg_s, msg_r) = std::sync::mpsc::channel::(); let cm = ConnectionManager::new(Some(msg_s)); let proto = Protocol {}; let data = Arc::new(TData { cm: cm, p: proto }); let f = Factory::new_fn::(); let mut tree = f.tree(()); let cm_iface = telepathy::connection_manager_server(&f, Arc::clone(&data), |m| { let a: &Arc = &m.iface.get_data(); let b: &TData = &a; &b.cm }); let proto_iface = telepathy::protocol_server(&f, Arc::clone(&data), |m| { let a: &Arc = &m.iface.get_data(); let b: &TData = &a; &b.p }); tree = tree.add( f.object_path(CM_OBJECT_PATH, ()) .introspectable() .add(cm_iface), ); tree = tree.add( f.object_path(PROTO_OBJECT_PATH, ()) .introspectable() .add(proto_iface), ); tree = tree.add(f.object_path("/", ()).introspectable()); // Setup DBus connection let mut c = LocalConnection::new_session()?; tree.start_receive(&c); for name in vec![CM_BUS_NAME, PROTO_BUS_NAME, CM_CONN_BUS_NAME, CONN_BUS_NAME] { let result = c.request_name(name, false, false, true)?; match result { RequestNameReply::Exists => { return Err(anyhow!("Another process is already registered on {}", name)) } _ => println!("{} listening on {}", c.unique_name(), name), // All other responses we can get are a success } } loop { c.process(Duration::from_millis(100))?; // Spend a bit of time sending any outgoing messages - signals, mostly for msg in msg_r.try_iter().take(10) { print!("Sending message..."); match c.send(msg) { Err(e) => println!("error!"), _ => println!("OK!"), } } } } fn main() { if let Err(e) = run() { println!("{}", e); std::process::exit(1); } }