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