A bit more progress on channels

This commit is contained in:
2020-05-17 00:49:46 +01:00
parent 09afdf51a4
commit 7003b56ce6
9 changed files with 224 additions and 162 deletions

View File

@@ -13,13 +13,12 @@ use crate::telepathy;
// FIXME: I'm assuming that all channels will be of type text and 1-1 for now.
#[derive(Debug)]
pub struct Channel {
pub path: dbus::Path<'static>,
}
// "This SHOULD NOT include the channel type and channel interface itself"
pub fn channel_interfaces() -> Vec<String> {
vec![
"org.freedesktop.Telepathy.Channel.Interface.Messages".to_string(),
]
vec!["org.freedesktop.Telepathy.Channel.Interface.Messages".to_string()]
}
type Result<T> = std::result::Result<T, dbus::tree::MethodErr>;
@@ -37,8 +36,7 @@ impl Channel {
let messages_iface =
telepathy::channel_interface_messages_server(&f, (), move |_| c_rc2.clone());
let type_text_iface =
telepathy::channel_type_text_server(&f, (), move |_| c_rc.clone());
let type_text_iface = telepathy::channel_type_text_server(&f, (), move |_| c_rc.clone());
tree = tree.add(
f.object_path("", ())

View File

@@ -14,39 +14,44 @@ impl AsRef<dyn telepathy::ChannelInterfaceMessages + 'static> for std::rc::Rc<Ch
impl telepathy::ChannelInterfaceMessages for Channel {
fn send_message(&self, message: Vec<HashMap<&str, VarArg>>, flags: u32) -> Result<String> {
println!("Channel::send_message({:?}, {})", message, flags);
Err(MethodErr::no_arg())
println!("Channel::send_message({:?}, {})", message, flags);
Err(MethodErr::no_arg())
}
fn get_pending_message_content(&self, message_id: u32, parts: Vec<u32>) -> Result<HashMap<u32, VarArg>> {
println!("Channel::get_pending_message_content({}, {:?})", message_id, parts);
Err(MethodErr::no_arg())
fn get_pending_message_content(
&self,
message_id: u32,
parts: Vec<u32>,
) -> Result<HashMap<u32, VarArg>> {
println!(
"Channel::get_pending_message_content({}, {:?})",
message_id, parts
);
Err(MethodErr::no_arg())
}
fn supported_content_types(&self) -> Result<Vec<String>> {
println!("Channel::supported_content_types()");
Err(MethodErr::no_arg())
println!("Channel::supported_content_types()");
Err(MethodErr::no_arg())
}
fn message_types(&self) -> Result<Vec<u32>> {
println!("Channel::message_types()");
Err(MethodErr::no_arg())
println!("Channel::message_types()");
Err(MethodErr::no_arg())
}
fn message_part_support_flags(&self) -> Result<u32> {
println!("Channel::message_part_support_flags()");
Err(MethodErr::no_arg())
println!("Channel::message_part_support_flags()");
Err(MethodErr::no_arg())
}
fn pending_messages(&self) -> Result<Vec<Vec<HashMap<String, VarArg>>>> {
println!("Channel::pending_messages()");
Err(MethodErr::no_arg())
println!("Channel::pending_messages()");
Err(MethodErr::no_arg())
}
fn delivery_reporting_support(&self) -> Result<u32> {
println!("Channel::delivery_reporting_support()");
Err(MethodErr::no_arg())
println!("Channel::delivery_reporting_support()");
Err(MethodErr::no_arg())
}
}

View File

@@ -10,11 +10,11 @@ impl AsRef<dyn telepathy::ChannelTypeText + 'static> for std::rc::Rc<Channel> {
}
type PendingMessagesSpec = (
u32, // numeric identifier
u32, // Unix timestamp indicating when the message was received
u32, // contact handle for the contact who sent the message
u32, // message type, taken from ChannelTextMessageType
u32, // bitwise-OR of the message flags from ChannelTextMessageFlags
u32, // numeric identifier
u32, // Unix timestamp indicating when the message was received
u32, // contact handle for the contact who sent the message
u32, // message type, taken from ChannelTextMessageType
u32, // bitwise-OR of the message flags from ChannelTextMessageFlags
String, // text of the message
);

View File

@@ -20,7 +20,7 @@ pub use self::requests::*;
mod simple_presence;
pub use self::simple_presence::*;
use crate::padfoot::VarArg;
use crate::padfoot::{Channel, VarArg};
use crate::telepathy;
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
@@ -39,18 +39,30 @@ use std::time::Duration;
pub const CONN_BUS_NAME: &str = "org.freedesktop.Telepathy.Connection.padfoot.delta";
pub const CONN_OBJECT_PATH: &str = "/org/freedesktop/Telepathy/Connection/padfoot/delta";
// Only the main loop has access to the DBUS connection. Interacting with DBUS
// outside of method return values requires one of these to be added to actq
#[derive(Debug)]
// A Deltachast connection uses email addresses as handles, and delta's Db IDs
enum DbusAction {
Signal(dbus::Message), // Generic signal to send
NewChannel(Channel), // Add this channel
CloseChannel(dbus::Path<'static>), // Close this channel
}
#[derive(Debug)]
// A connection uses delta database IDs as handles, and email addresses as IDs
pub struct Connection {
// Remove ourselves from this when done
// Used for sending out messages
actq: Arc<Mutex<VecDeque<DbusAction>>>,
// Channels we own
channels: Arc<RwLock<HashMap<dbus::Path<'static>, Channel>>>,
// Owned by the CM. Remove ourselves from this when done
conns: Arc<Mutex<HashSet<String>>>,
ctx: Arc<RwLock<Context>>,
settings: ConnSettings,
state: Arc<RwLock<ConnState>>,
// Used for sending out messages
msgq: Arc<Mutex<VecDeque<dbus::Message>>>,
}
#[derive(Debug)]
@@ -115,11 +127,11 @@ impl Connection {
dbfile.push("db.sqlite3");
// FIXME: how to give it access to the connection (initialized later)?
let msgq = Arc::new(Mutex::new(VecDeque::<dbus::Message>::new()));
let actq = Arc::new(Mutex::new(VecDeque::<DbusAction>::new()));
let id = settings.id();
// Use this if we need to send messages in response to DC events:
// let msgq2 = msgq.clone();
// let acqt2 = actq.clone();
let f = move |_c: &Context, e: Event| {
match e {
Event::Info(msg) => println!("Connection<{}>: INFO: {}", id, msg),
@@ -181,7 +193,8 @@ impl Connection {
Ok(Connection {
conns,
settings,
msgq,
actq,
channels: Arc::new(RwLock::new(HashMap::<dbus::Path<'static>, Channel>::new())),
ctx: Arc::new(RwLock::new(ctx)),
state: Arc::new(RwLock::new(ConnState::Initial)),
})
@@ -198,7 +211,8 @@ impl Connection {
let path = self.path();
let conns = self.conns.clone();
let msgq = self.msgq.clone();
let chans = self.channels.clone();
let actq = self.actq.clone();
let state = self.state.clone();
let tree = self.build_tree();
@@ -242,12 +256,31 @@ impl Connection {
};
// Spend a bit of time sending any outgoing messages - signals, mostly
while let Some(msg) = msgq.lock().unwrap().pop_front() {
print!("Connection<{}>: Sending message...", id);
while let Some(act) = actq.lock().unwrap().pop_front() {
match act {
DbusAction::Signal(msg) => {
print!("Connection<{}>: Sending message...", id);
match c.send(msg) {
Err(e) => println!("error! {:?}", e), // FIXME: handle error better?
_ => println!("OK!"),
match c.send(msg) {
Err(e) => println!("error! {:?}", e), // FIXME: handle error better?
_ => println!("OK!"),
}
}
DbusAction::NewChannel(channel) => {
Arc::clone(&chans)
.write()
.unwrap()
.insert(channel.path.clone(), channel);
// TODO: add channel to tree
// TODO: emit signals
}
DbusAction::CloseChannel(path) => {
let _chan = Arc::clone(&chans).write().unwrap().remove(&path);
// TODO: add channel to tree
// TODO: emit signals
}
}
}
}

View File

@@ -5,7 +5,7 @@ use dbus::tree::MethodErr;
use deltachat as dc;
use std::thread;
use super::Connection;
use super::{Connection, DbusAction};
#[derive(Debug, PartialEq, Eq)]
pub enum ConnState {
@@ -112,10 +112,10 @@ impl telepathy::Connection for Connection {
let dbus_conn_path = dbus::strings::Path::new(self.path())
.expect("Object path should meet DBUS requirements");
self.msgq
self.actq
.lock()
.unwrap()
.push_back(sig.to_emit_message(&dbus_conn_path));
.push_back(DbusAction::Signal(sig.to_emit_message(&dbus_conn_path)));
Ok(())
}
@@ -225,9 +225,10 @@ impl telepathy::Connection for Connection {
Ok(())
}
// RequestChannel is deprecated in favour of the Requests interface.
fn request_channel(
&self,
type_: &str,
channel_type: &str,
handle_type: u32,
handle: u32,
suppress_handler: bool,
@@ -235,7 +236,7 @@ impl telepathy::Connection for Connection {
println!(
"Connection<{}>::request_channel({}, {}, {}, {})",
self.id(),
type_,
channel_type,
handle_type,
handle,
suppress_handler

View File

@@ -6,21 +6,26 @@ use std::collections::HashMap;
use super::Connection;
type ChannelSpec = (
dbus::Path<'static>, // Object path on this connection
HashMap<String, VarArg>, // Map of channel property -> value
);
type RequestableChannelSpec = (HashMap<String, VarArg>, Vec<String>);
type Result<T> = std::result::Result<T, MethodErr>;
impl AsRef<dyn telepathy::ConnectionInterfaceRequests + 'static> for std::rc::Rc<Connection> {
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceRequests + 'static) {
&**self
}
}
type ChannelSpec = (dbus::Path<'static>, HashMap<String, VarArg>);
type RequestableChannelSpec = (HashMap<String, VarArg>, Vec<String>);
impl telepathy::ConnectionInterfaceRequests for Connection {
fn create_channel(
&self,
request: HashMap<&str, VarArg>,
) -> Result<(dbus::Path<'static>, HashMap<String, VarArg>), MethodErr> {
) -> Result<(dbus::Path<'static>, HashMap<String, VarArg>)> {
println!("Connection<{}>::create_channel({:?})", self.id(), request);
Err(MethodErr::no_arg()) // FIXME: should be NotImplemented?
@@ -29,17 +34,26 @@ impl telepathy::ConnectionInterfaceRequests for Connection {
fn ensure_channel(
&self,
request: HashMap<&str, VarArg>,
) -> Result<(bool, dbus::Path<'static>, HashMap<String, VarArg>), MethodErr> {
) -> Result<(bool, dbus::Path<'static>, HashMap<String, VarArg>)> {
println!("Connection<{}>::ensure_channel({:?})", self.id(), request);
Err(MethodErr::no_arg()) // FIXME: should be NotImplemented?
}
fn channels(&self) -> Result<Vec<ChannelSpec>, MethodErr> {
fn channels(&self) -> Result<Vec<ChannelSpec>> {
println!("Connection<{}>::channels()", self.id());
Ok(vec![])
let mut out = Vec::<ChannelSpec>::new();
for channel in self.channels.read().unwrap().values() {
out.push((
channel.path.clone(),
HashMap::<String, VarArg>::new(), // FIXME: work out what props should be shown
));
}
Ok(out)
}
fn requestable_channel_classes(&self) -> Result<Vec<RequestableChannelSpec>, MethodErr> {
fn requestable_channel_classes(&self) -> Result<Vec<RequestableChannelSpec>> {
println!("Connection<{}>::requestable_channel_classes()", self.id());
Ok(requestables())
}

View File

@@ -1,6 +1,5 @@
#![allow(unused)]
#![allow(clippy::all)]
mod account_interface_addressing;
pub use self::account_interface_addressing::*;