Fix receipts handling according to recent XEP updates
* add lm_get_uid() @xmpp_helper.h
* identify receipts by id attribute of 'received' subelement
instead of stanza id
--- a/mcabber/mcabber/hbuf.c Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/hbuf.c Sun Oct 14 17:39:11 2012 +0200
@@ -525,7 +525,7 @@
// hbuf_remove_receipt(hbuf, xep184)
// Remove the Receipt Flag for the message with the given xep184 id
// Returns TRUE if it was found and removed, otherwise FALSE
-gboolean hbuf_remove_receipt(GList *hbuf, gpointer xep184)
+gboolean hbuf_remove_receipt(GList *hbuf, gconstpointer xep184)
{
hbuf_block *blk;
@@ -533,7 +533,8 @@
for ( ; hbuf; hbuf = g_list_previous(hbuf)) {
blk = (hbuf_block*)(hbuf->data);
- if (blk->prefix.xep184 == xep184) {
+ if (!g_strcmp0(blk->prefix.xep184, xep184)) {
+ g_free(blk->prefix.xep184);
blk->prefix.xep184 = NULL;
blk->prefix.flags ^= HBB_PREFIX_RECEIPT;
return TRUE;
--- a/mcabber/mcabber/hbuf.h Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/hbuf.h Sun Oct 14 17:39:11 2012 +0200
@@ -50,7 +50,7 @@
GList *hbuf_jump_date(GList *hbuf, time_t t);
GList *hbuf_jump_percent(GList *hbuf, int pc);
GList *hbuf_jump_readmark(GList *hbuf);
-gboolean hbuf_remove_receipt(GList *hbuf, gpointer xep184);
+gboolean hbuf_remove_receipt(GList *hbuf, gconstpointer xep184);
void hbuf_set_readmark(GList *hbuf, gboolean action);
void hbuf_remove_trailing_readmark(GList *hbuf);
--- a/mcabber/mcabber/screen.c Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/screen.c Sun Oct 14 17:39:11 2012 +0200
@@ -2247,7 +2247,7 @@
scr_show_window(jidto, FALSE);
}
-void scr_remove_receipt_flag(const char *bjid, gpointer xep184)
+void scr_remove_receipt_flag(const char *bjid, gconstpointer xep184)
{
winbuf *win_entry = scr_search_window(bjid, FALSE);
if (win_entry) {
--- a/mcabber/mcabber/screen.h Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/screen.h Sun Oct 14 17:39:11 2012 +0200
@@ -109,7 +109,7 @@
void scr_update_main_status(int forceupdate);
void scr_update_chat_status(int forceupdate);
void scr_roster_visibility(int status);
-void scr_remove_receipt_flag(const char *jidto, gpointer xep184);
+void scr_remove_receipt_flag(const char *jidto, gconstpointer xep184);
void scr_show_buddy_window(void);
int scr_buddy_buffer_exists(const char *jid);
void scr_update_buddy_window(void);
--- a/mcabber/mcabber/xmpp.c Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/xmpp.c Sun Oct 14 17:39:11 2012 +0200
@@ -295,15 +295,6 @@
g_slist_free(resources);
}
-static LmHandlerResult cb_xep184(LmMessageHandler *h, LmConnection *c,
- LmMessage *m, gpointer user_data)
-{
- char *from = jidtodisp(lm_message_get_from(m));
- scr_remove_receipt_flag(from, h);
- g_free(from);
- return LM_HANDLER_RESULT_REMOVE_MESSAGE;
-}
-
// xmpp_send_msg(jid, text, type, subject,
// otrinject, *encrypted, type_overwrite)
// When encrypted is not NULL, the function set *encrypted to 1 if the
@@ -429,10 +420,11 @@
if (sl_buddy && xep184 &&
caps_has_feature(buddy_resource_getcaps(sl_buddy->data, rname),
NS_RECEIPTS, barejid)) {
- lm_message_node_set_attribute
- (lm_message_node_add_child(x->node, "request", NULL),
- "xmlns", NS_RECEIPTS);
- *xep184 = lm_message_handler_new(cb_xep184, NULL, NULL);
+ lm_message_node_set_attribute(lm_message_node_add_child(x->node, "request",
+ NULL),
+ "xmlns", NS_RECEIPTS);
+ *xep184 = lm_get_uid ();
+ lm_message_node_set_attribute (x->node, "id", (const gchar *)*xep184);
}
g_free(barejid);
@@ -499,11 +491,7 @@
if (mystatus != invisible)
#endif
update_last_use();
- if (xep184 && *xep184) {
- lm_connection_send_with_reply(lconnection, x, *xep184, NULL);
- lm_message_handler_unref(*xep184);
- } else
- lm_connection_send(lconnection, x, NULL);
+ lm_connection_send(lconnection, x, NULL);
lm_message_unref(x);
}
@@ -1305,6 +1293,16 @@
lm_message_unref(rcvd);
}
+ { // xep184 receipt confirmation
+ LmMessageNode *received = lm_message_node_get_child(m->node, "received");
+ if (received && !g_strcmp0(lm_message_node_get_attribute(received, "xmlns"), NS_RECEIPTS)) {
+ char *jid = jidtodisp(from);
+ const char *id = lm_message_node_get_attribute(received, "id");
+ scr_remove_receipt_flag(jid, id);
+ g_free(jid);
+ }
+ }
+
if (from) {
x = lm_message_node_find_xmlns(m->node, NS_MUC_USER);
if (x && !strcmp(x->name, "x"))
--- a/mcabber/mcabber/xmpp_helper.c Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/xmpp_helper.c Sun Oct 14 17:39:11 2012 +0200
@@ -73,7 +73,6 @@
{0, NULL, NULL, NULL, NULL}
};
-
#ifdef MODULES_ENABLE
static GSList *xmpp_additional_features = NULL;
static char *ver, *ver_notavail;
@@ -105,6 +104,13 @@
}
#endif
+// The caller must g_free this after use
+gchar *lm_get_uid ()
+{
+ static guint xmpp_uid = 0;
+ return g_strdup_printf ("mc%u", ++xmpp_uid);
+}
+
const gchar* lm_message_node_get_child_value(LmMessageNode *node,
const gchar *child)
{
--- a/mcabber/mcabber/xmpp_helper.h Sat Oct 13 19:53:12 2012 +0200
+++ b/mcabber/mcabber/xmpp_helper.h Sun Oct 14 17:39:11 2012 +0200
@@ -29,6 +29,8 @@
void xmpp_del_feature (const char *xmlns);
#endif
+gchar *lm_get_uid (void);
+
LmMessageNode *lm_message_node_new(const gchar *name, const gchar *xmlns);
LmMessageNode *lm_message_node_find_xmlns(LmMessageNode *node,
const char *xmlns);