use crate::{dbus::interface::OBJECT_PATH, daemon::Daemon}; use crossroads::Crossroads; use dbus::{ channel::{MatchingReceiver, Sender}, message::MatchRule, nonblock::SyncConnection, Path, }; use dbus_crossroads as crossroads; use dbus_tokio::connection; use dbus_tree::{DataType, MethodErr}; use log::info; use std::{future::Future, sync::Arc, thread}; mod dbus_interface { #![allow(unused)] include!(concat!(env!("OUT_DIR"), "/kordophone-server.rs")); } use dbus_interface::NetBuzzertKordophoneServer; pub struct Endpoint { connection: Arc, daemon: Arc, } impl Endpoint { pub fn new(daemon: Arc) -> Self { let (resource, connection) = connection::new_session_sync().unwrap(); // The resource is a task that should be spawned onto a tokio compatible // reactor ASAP. If the resource ever finishes, you lost connection to D-Bus. // // To shut down the connection, both call _handle.abort() and drop the connection. let _handle = tokio::spawn(async { let err = resource.await; panic!("Lost connection to D-Bus: {}", err); }); Self { connection, daemon } } pub async fn start(&self) { use crate::dbus::interface; self.connection .request_name(interface::NAME, false, true, false) .await .expect("Unable to acquire dbus name"); let mut cr = Crossroads::new(); // Enable async support for the crossroads instance. // (Currently irrelevant since dbus generates sync code) cr.set_async_support(Some(( self.connection.clone(), Box::new(|x| { tokio::spawn(x); }), ))); // Register the daemon as a D-Bus object. let token = dbus_interface::register_net_buzzert_kordophone_server(&mut cr); cr.insert(OBJECT_PATH, &[token], self.daemon.clone()); // Start receiving messages. self.connection.start_receive( MatchRule::new_method_call(), Box::new(move |msg, conn| cr.handle_message(msg, conn).is_ok() ), ); info!(target: "dbus", "DBus server started"); } pub fn send_signal(&self, signal: S) -> Result where S: dbus::message::SignalArgs + dbus::arg::AppendAll, { let message = signal.to_emit_message(&Path::new(OBJECT_PATH).unwrap()); self.connection.send(message) } } impl NetBuzzertKordophoneServer for Arc { fn get_version(&mut self) -> Result { Ok(self.version.clone()) } }