diff options
author | Will Thompson <will.thompson@collabora.co.uk> | 2012-10-31 20:19:18 +0000 |
---|---|---|
committer | Will Thompson <will.thompson@collabora.co.uk> | 2012-12-06 18:28:32 +0000 |
commit | a990012f6e48af641686741ea52506230cdcaaad (patch) | |
tree | 5d541acd4b7dcb3eeee22d993fb6984940b9db7e /src | |
parent | c33a817b5bcf9f6bec7c744e4c5a3f0b96df4118 (diff) |
Emit delivery reports for XEP-0184 receipts.
Diffstat (limited to 'src')
-rw-r--r-- | src/im-channel.c | 32 | ||||
-rw-r--r-- | src/im-channel.h | 3 | ||||
-rw-r--r-- | src/im-factory.c | 47 | ||||
-rw-r--r-- | src/namespaces.h | 1 |
4 files changed, 74 insertions, 9 deletions
diff --git a/src/im-channel.c b/src/im-channel.c index 1d1cf2fa5..c6e40b58a 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 076565ef5..4b6fc7bee 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 661f6fbc1..e0bff2bdf 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 0d06d7d54..2a2d8f91b 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" |