changeset 30399:3eb2dd8a1cc7

Miranda expects a client ack from the other side for channel 2 messages, so we now send it. This is based on a patch by Jan Kaluza.
author ivan.komarov@soc.pidgin.im
date Thu, 05 Aug 2010 22:45:21 +0000
parents be056399ae5f
children 11c54d781835
files libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 3 files changed, 48 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icbm.c	Thu Aug 05 21:19:47 2010 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Thu Aug 05 22:45:21 2010 +0000
@@ -1605,6 +1605,52 @@
 }
 
 /*
+ * Subtype 0x000b.
+ * Send confirmation for a channel 2 message (Miranda wants it by default).
+ */
+void
+aim_im_send_icq_confirmation(OscarData *od, const char *bn, const guchar *cookie)
+{
+	ByteStream bs;
+	aim_snacid_t snacid;
+	guint32 header_size, data_size;
+	guint16 cookie2 = (guint16)g_random_int();
+
+	purple_debug_misc("oscar", "Sending message ack to %s\n", bn);
+
+	header_size = 8 + 2 + 1 + strlen(bn) + 2;
+	data_size = 2 + 1 + 16 + 4*2 + 2*3 + 4*3 + 1*2 + 2*3 + 1;
+	byte_stream_new(&bs, header_size + data_size);
+
+	/* The message header. */
+	aim_im_puticbm(&bs, cookie, 0x0002, bn);
+	byte_stream_put16(&bs, 0x0003);	/* reason */
+
+	/* The actual message. */
+	byte_stream_putle16(&bs, 0x1b);	/* subheader #1 length */
+	byte_stream_put8(&bs, 0x08);	/* protocol version */
+	byte_stream_putcaps(&bs, OSCAR_CAPABILITY_EMPTY);
+	byte_stream_put32(&bs, 0x3);	/* client features */
+	byte_stream_put32(&bs, 0x0004);	/* DC type */
+	byte_stream_put16(&bs, cookie2);	/* a cookie, chosen by fair dice roll */
+	byte_stream_putle16(&bs, 0x0e);	/* header #2 len? */
+	byte_stream_put16(&bs, cookie2);	/* the same cookie again */
+	byte_stream_put32(&bs, 0);	/* unknown */
+	byte_stream_put32(&bs, 0);	/* unknown */
+	byte_stream_put32(&bs, 0);	/* unknown */
+	byte_stream_put8(&bs, 0x01);	/* plain text message */
+	byte_stream_put8(&bs, 0x00);	/* no message flags */
+	byte_stream_put16(&bs, 0x0000);	/* no icq status */
+	byte_stream_put16(&bs, 0x0100);	/* priority */
+	byte_stream_putle16(&bs, 1);	/* query message len */
+	byte_stream_put8(&bs, 0x00);	/* empty query message */
+
+	snacid = aim_cachesnac(od, SNAC_FAMILY_ICBM, 0x000b, 0x0000, NULL, 0);
+	flap_connection_send_snac(od, flap_connection_findbygroup(od, SNAC_FAMILY_ICBM), SNAC_FAMILY_ICBM, 0x000b, 0x0000, snacid, &bs);
+	byte_stream_destroy(&bs);
+}
+
+/*
  * Subtype 0x000b - Receive the response from an ICQ status message
  * request (in which case this contains the ICQ status message) or
  * a file transfer or direct IM request was declined.
--- a/libpurple/protocols/oscar/oscar.c	Thu Aug 05 21:19:47 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Thu Aug 05 22:45:21 2010 +0000
@@ -1758,6 +1758,7 @@
 				g_free(tmp);
 
 				serv_got_im(gc, userinfo->bn, tmp2, flags, time(NULL));
+				aim_im_send_icq_confirmation(od, userinfo->bn, args->cookie);
 				g_free(tmp2);
 			}
 		} else if (args->info.rtfmsg.msgtype == 26) {
--- a/libpurple/protocols/oscar/oscar.h	Thu Aug 05 21:19:47 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Thu Aug 05 22:45:21 2010 +0000
@@ -734,6 +734,7 @@
 /* 0x0014 */ int aim_im_sendmtn(OscarData *od, guint16 type1, const char *bn, guint16 type2);
 /* 0x000b */ int icq_relay_xstatus (OscarData *od, const char *sn, const guchar* cookie);
 void aim_icbm_makecookie(guchar* cookie);
+void aim_im_send_icq_confirmation(OscarData *od, const char *bn, const guchar *cookie);
 
 /* 0x0002 - family_locate.c */
 /*