/soc/2015/koosha/main: cd0d929093ab: XMPP: add back-end support ...
Koosha Khajehmoogahi
koosha at posteo.de
Wed Jun 10 20:38:29 EDT 2015
Changeset: cd0d929093abf2a2f5a61e84d1eccce5eb90b977
Author: Koosha Khajehmoogahi <koosha at posteo.de>
Date: 2015-06-11 02:37 +0200
Branch: default
URL: https://hg.pidgin.im/soc/2015/koosha/main/rev/cd0d929093ab
Description:
XMPP: add back-end support for XEP-0184 "Message Delivery Receipts"
diffstat:
libpurple/protocols/jabber/disco.c | 2 +
libpurple/protocols/jabber/jabber.c | 1 +
libpurple/protocols/jabber/jabber.h | 2 +-
libpurple/protocols/jabber/message.c | 77 ++++++++++++++++++++++++++++++++-
libpurple/protocols/jabber/message.h | 2 +
libpurple/protocols/jabber/namespaces.h | 3 +
6 files changed, 85 insertions(+), 2 deletions(-)
diffs (202 lines):
diff --git a/libpurple/protocols/jabber/disco.c b/libpurple/protocols/jabber/disco.c
--- a/libpurple/protocols/jabber/disco.c
+++ b/libpurple/protocols/jabber/disco.c
@@ -302,6 +302,8 @@ static void jabber_disco_info_cb(JabberS
purple_debug_info("jabber", "remote supports IBB\n");
capabilities |= JABBER_CAP_IBB;
}
+ else if(!strcmp(var, NS_MSG_DELIVERY))
+ capabilities |= JABBER_MSG_DELIVERY;
}
}
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -3941,6 +3941,7 @@ jabber_do_init(void)
jabber_add_feature(NS_SI_FILE_TRANSFER, NULL);
jabber_add_feature(NS_XHTML_IM, NULL);
jabber_add_feature(NS_PING, NULL);
+ jabber_add_feature(NS_MSG_DELIVERY, NULL);
/* Buzz/Attention */
jabber_add_feature(NS_ATTENTION, jabber_buzz_isenabled);
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -50,7 +50,7 @@ typedef enum {
JABBER_CAP_ROSTER_VERSIONING = 1 << 15,
JABBER_CAP_FACEBOOK = 1 << 16,
-
+ JABBER_MSG_DELIVERY = 1 << 17,
JABBER_CAP_RETRIEVED = 1 << 31
} JabberCapabilities;
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -52,12 +52,54 @@ void jabber_message_free(JabberMessage *
g_free(jm->password);
g_free(jm->error);
g_free(jm->thread_id);
+ g_free(jm->receipt_id);
g_list_free(jm->etc);
g_list_free(jm->eventitems);
g_free(jm);
}
+static GHashTable *pending_receipts;
+
+static void add_pending_receipt(JabberMessage *jm) {
+ if (!pending_receipts)
+ pending_receipts = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
+
+ g_hash_table_insert(pending_receipts, g_strdup(jm->id), jm);
+}
+
+static gboolean remove_pending_receipt(JabberMessage *jm) {
+ JabberMessage *pending_msg;
+
+ if (!pending_receipts)
+ return FALSE;
+
+ pending_msg = (JabberMessage *) g_hash_table_lookup(pending_receipts, jm->id);
+ if (pending_msg != NULL) {
+ g_hash_table_remove(pending_receipts, jm->id);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void handle_receipt_request(JabberMessage *jm) {
+ JabberMessage *response;
+
+ response = g_new0(JabberMessage, 1);
+ response->type = JABBER_MESSAGE_OTHER;
+ response->receipt = TRUE;
+ response->delayed = jm->delayed;
+ response->from = g_strdup(jm->to);
+ response->to = g_strdup(jm->from);
+ response->id = jabber_get_next_id(jm->js);
+ response->receipt_id = g_strdup(jm->id);
+ response->chat_state = JM_STATE_NONE;
+ response->js = g_memdup(jm->js, sizeof(*(jm->js)));
+
+ jabber_message_send(response);
+}
+
static void handle_chat(JabberMessage *jm)
{
JabberID *jid = jabber_id_new(jm->from);
@@ -152,6 +194,9 @@ static void handle_chat(JabberMessage *j
jbr->thread_id = g_strdup(jbr->thread_id);
}
+ if (jm->receipt)
+ handle_receipt_request(jm);
+
if (jm->js->googletalk && jm->xhtml == NULL) {
char *tmp = jm->body;
jm->body = jabber_google_format_to_html(jm->body);
@@ -552,7 +597,7 @@ void jabber_message_parse(JabberStream *
{
JabberMessage *jm;
const char *id, *from, *to, *type;
- PurpleXmlNode *child;
+ PurpleXmlNode *child, *sibling;
gboolean signal_return;
from = purple_xmlnode_get_attrib(packet, "from");
@@ -569,6 +614,7 @@ void jabber_message_parse(JabberStream *
jm->js = js;
jm->sent = time(NULL);
jm->delayed = FALSE;
+ jm->receipt = FALSE;
jm->chat_state = JM_STATE_NONE;
if(type) {
@@ -640,6 +686,19 @@ void jabber_message_parse(JabberStream *
char *msg = purple_xmlnode_get_data(child);
char *escaped = purple_markup_escape_text(msg, -1);
jm->body = purple_strdup_withhtml(escaped);
+ if (jm->type == JABBER_MESSAGE_NORMAL ||
+ jm->type == JABBER_MESSAGE_CHAT)
+ {
+ for (sibling = packet->child; sibling; sibling = sibling->next) {
+ if (!strcmp(sibling->name, "request")) {
+ const char *sibling_xmlns = purple_xmlnode_get_namespace(sibling);
+ if (!strcmp(sibling_xmlns, "urn:xmpp:receipts")) {
+ jm->receipt = TRUE;
+ break;
+ }
+ }
+ }
+ }
g_free(escaped);
g_free(msg);
}
@@ -741,6 +800,10 @@ void jabber_message_parse(JabberStream *
jm->eventitems = g_list_append(jm->eventitems, items);
} else if(!strcmp(child->name, "attention") && !strcmp(xmlns, NS_ATTENTION)) {
jm->hasBuzz = TRUE;
+ } else if(!strcmp(child->name, "received") && !strcmp(xmlns, NS_MSG_DELIVERY)) {
+ const char *msg_id = purple_xmlnode_get_attrib(child, "id");
+ if (msg_id)
+ remove_pending_receipt(jm);
} else if(!strcmp(child->name, "delay") && !strcmp(xmlns, NS_DELAYED_DELIVERY)) {
const char *timestamp = purple_xmlnode_get_attrib(child, "stamp");
jm->delayed = TRUE;
@@ -1065,6 +1128,18 @@ void jabber_message_send(JabberMessage *
if(jm->body) {
child = purple_xmlnode_new_child(message, "body");
purple_xmlnode_insert_data(child, jm->body, -1);
+
+ if (jm->type == JABBER_MESSAGE_NORMAL || jm->type == JABBER_MESSAGE_CHAT) {
+ child = purple_xmlnode_new_child(message, "request");
+ purple_xmlnode_set_attrib(child, "xmlns", "urn:xmpp:receipts");
+ }
+ }
+
+ if (jm->receipt) {
+ child = purple_xmlnode_new_child(message, "received");
+ purple_xmlnode_set_attrib(child, "xmlns", "urn:xmpp:receipts");
+ purple_xmlnode_set_attrib(child, "id", jm->receipt_id);
+ add_pending_receipt(jm);
}
if(jm->xhtml) {
diff --git a/libpurple/protocols/jabber/message.h b/libpurple/protocols/jabber/message.h
--- a/libpurple/protocols/jabber/message.h
+++ b/libpurple/protocols/jabber/message.h
@@ -43,6 +43,7 @@ typedef struct _JabberMessage {
time_t sent;
gboolean delayed;
gboolean hasBuzz;
+ gboolean receipt;
char *id;
char *from;
char *to;
@@ -52,6 +53,7 @@ typedef struct _JabberMessage {
char *password;
char *error;
char *thread_id;
+ char *receipt_id;
enum {
JM_STATE_NONE,
JM_STATE_ACTIVE,
diff --git a/libpurple/protocols/jabber/namespaces.h b/libpurple/protocols/jabber/namespaces.h
--- a/libpurple/protocols/jabber/namespaces.h
+++ b/libpurple/protocols/jabber/namespaces.h
@@ -67,6 +67,9 @@
/* XEP-0124 Bidirectional-streams Over Synchronous HTTP (BOSH) */
#define NS_BOSH "http://jabber.org/protocol/httpbind"
+/* XEP-0184 Message Delivery Receipts */
+#define NS_MSG_DELIVERY "urn:xmpp:receipts"
+
/* XEP-0191 Simple Communications Blocking */
#define NS_SIMPLE_BLOCKING "urn:xmpp:blocking"
More information about the Commits
mailing list