telepathy-gabble: Emit delivery reports for XEP-0184 receipts.
Will Thompson
wjt at kemper.freedesktop.org
Thu Dec 6 10:37:22 PST 2012
Module: telepathy-gabble
Branch: master
Commit: a990012f6e48af641686741ea52506230cdcaaad
URL: http://cgit.freedesktop.org/telepathy/telepathy-gabble/commit/?id=a990012f6e48af641686741ea52506230cdcaaad
Author: Will Thompson <will.thompson at collabora.co.uk>
Date: Wed Oct 31 20:19:18 2012 +0000
Emit delivery reports for XEP-0184 receipts.
---
src/im-channel.c | 32 +++++++++++++++++++++++---------
src/im-channel.h | 3 +++
src/im-factory.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
src/namespaces.h | 1 +
4 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/src/im-channel.c b/src/im-channel.c
index 1d1cf2f..c6e40b5 100644
--- a/src/im-channel.c
+++ b/src/im-channel.c
@@ -476,7 +476,7 @@ _gabble_im_channel_report_delivery (
TpBaseChannel *base_chan = (TpBaseChannel *) self;
TpBaseConnection *base_conn;
TpHandle peer;
- TpMessage *msg, *delivery_report;
+ TpMessage *delivery_report;
gchar *tmp;
g_return_if_fail (GABBLE_IS_IM_CHANNEL (self));
@@ -495,7 +495,6 @@ _gabble_im_channel_report_delivery (
priv->chat_states_supported = CHAT_STATES_UNKNOWN;
}
- msg = build_message (self, type, timestamp, text);
delivery_report = tp_cm_message_new (base_conn, 1);
tp_message_set_uint32 (delivery_report, 0, "message-type",
TP_CHANNEL_TEXT_MESSAGE_TYPE_DELIVERY_REPORT);
@@ -514,15 +513,20 @@ _gabble_im_channel_report_delivery (
if (id != NULL)
tp_message_set_string (delivery_report, 0, "delivery-token", id);
- /* This is a delivery report, so the original sender of the echoed message
- * must be us! */
- tp_cm_message_set_sender (msg, tp_base_connection_get_self_handle (base_conn));
+ if (text != NULL)
+ {
+ TpMessage *msg = build_message (self, type, timestamp, text);
+ /* This is a delivery report, so the original sender of the echoed message
+ * must be us! */
+ tp_cm_message_set_sender (msg, tp_base_connection_get_self_handle (base_conn));
- /* Since this is a delivery report, we can trust the id on the message. */
- if (id != NULL)
- tp_message_set_string (msg, 0, "message-token", id);
+ /* Since this is a delivery report, we can trust the id on the message. */
+ if (id != NULL)
+ tp_message_set_string (msg, 0, "message-token", id);
+
+ tp_cm_message_take_message (delivery_report, 0, "delivery-echo", msg);
+ }
- tp_cm_message_take_message (delivery_report, 0, "delivery-echo", msg);
tp_message_mixin_take_received (G_OBJECT (self), delivery_report);
}
@@ -550,6 +554,16 @@ _gabble_im_channel_state_receive (GabbleIMChannel *chan,
tp_base_channel_get_target_handle (base_chan), state);
}
+void
+gabble_im_channel_receive_receipt (
+ GabbleIMChannel *self,
+ const gchar *receipt_id)
+{
+ _gabble_im_channel_report_delivery (self,
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, 0, receipt_id, NULL,
+ GABBLE_TEXT_CHANNEL_SEND_NO_ERROR, TP_DELIVERY_STATUS_DELIVERED);
+}
+
static void
gabble_im_channel_close (TpBaseChannel *base_chan)
{
diff --git a/src/im-channel.h b/src/im-channel.h
index 076565e..4b6fc7b 100644
--- a/src/im-channel.h
+++ b/src/im-channel.h
@@ -71,6 +71,9 @@ void _gabble_im_channel_receive (GabbleIMChannel *chan,
gint state);
void _gabble_im_channel_state_receive (GabbleIMChannel *chan,
TpChannelChatState state);
+void gabble_im_channel_receive_receipt (
+ GabbleIMChannel *self,
+ const gchar *receipt_id);
void _gabble_im_channel_report_delivery (
GabbleIMChannel *self,
diff --git a/src/im-factory.c b/src/im-factory.c
index 661f6fb..e0bff2b 100644
--- a/src/im-factory.c
+++ b/src/im-factory.c
@@ -60,6 +60,7 @@ struct _GabbleImFactoryPrivate
{
GabbleConnection *conn;
guint message_cb_id;
+ guint delivery_report_cb_id;
GHashTable *channels;
gulong status_changed_id;
@@ -266,6 +267,42 @@ im_factory_message_cb (
return TRUE;
}
+/* Signals incoming delivery receipts. http://xmpp.org/extensions/xep-0184.html
+ */
+static gboolean
+im_factory_receipt_cb (
+ WockyPorter *porter,
+ WockyStanza *message,
+ gpointer user_data)
+{
+ GabbleImFactory *self = GABBLE_IM_FACTORY (user_data);
+ WockyNode *received;
+ const gchar *from, *received_id;
+ GabbleIMChannel *channel;
+
+ received = wocky_node_get_child_ns (wocky_stanza_get_top_node (message),
+ "received", NS_RECEIPTS);
+ g_return_val_if_fail (received != NULL, FALSE);
+
+ received_id = wocky_node_get_attribute (received, "id");
+ if (received_id == NULL)
+ {
+ STANZA_DEBUG (message, "but *what* did you receive?!");
+ return TRUE;
+ }
+
+ from = wocky_stanza_get_from (message);
+ channel = get_channel_for_incoming_message (self, from, FALSE);
+ if (channel == NULL)
+ {
+ DEBUG ("no existing channel with '%s'; ignoring receipt", from);
+ return TRUE;
+ }
+
+ gabble_im_channel_receive_receipt (channel, received_id);
+ return TRUE;
+}
+
/**
* im_channel_closed_cb:
*
@@ -433,6 +470,10 @@ gabble_im_factory_close_all (GabbleImFactory *self)
wocky_porter_unregister_handler (porter, self->priv->message_cb_id);
self->priv->message_cb_id = 0;
+
+ wocky_porter_unregister_handler (porter, self->priv->delivery_report_cb_id);
+ self->priv->delivery_report_cb_id = 0;
+
g_object_unref (porter);
}
}
@@ -519,6 +560,12 @@ porter_available_cb (
WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE,
WOCKY_PORTER_HANDLER_PRIORITY_MIN, im_factory_message_cb, self,
NULL);
+ self->priv->delivery_report_cb_id = wocky_porter_register_handler_from_anyone (porter,
+ WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE,
+ WOCKY_PORTER_HANDLER_PRIORITY_MIN, im_factory_receipt_cb, self,
+ '(',
+ "received", ':', NS_RECEIPTS,
+ ')', NULL);
g_object_get (conn, "stream-server", &stream_server, NULL);
diff --git a/src/namespaces.h b/src/namespaces.h
index 0d06d7d..2a2d8f9 100644
--- a/src/namespaces.h
+++ b/src/namespaces.h
@@ -103,6 +103,7 @@
#define NS_PRESENCE_INVISIBLE "presence-invisible"
#define NS_PRIVACY "jabber:iq:privacy"
#define NS_INVISIBLE "urn:xmpp:invisible:0"
+#define NS_RECEIPTS "urn:xmpp:receipts"
#define NS_REGISTER "jabber:iq:register"
#define NS_ROSTER "jabber:iq:roster"
#define NS_SEARCH "jabber:iq:search"
More information about the telepathy-commits
mailing list