94 lines
2.6 KiB
Rust
94 lines
2.6 KiB
Rust
|
|
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<SyncConnection>,
|
||
|
|
daemon: Arc<Daemon>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Endpoint {
|
||
|
|
pub fn new(daemon: Arc<Daemon>) -> 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<S>(&self, signal: S) -> Result<u32, ()>
|
||
|
|
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<Daemon> {
|
||
|
|
fn get_version(&mut self) -> Result<String, MethodErr> {
|
||
|
|
Ok(self.version.clone())
|
||
|
|
}
|
||
|
|
}
|