changeset 15089:25c3a33c6485

[gaim-migrate @ 17874] Add a flap_connection_send_snac() helper function that makes it a little easier/cleaner to send a SNAC-based FLAP command. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 02 Dec 2006 09:44:53 +0000
parents 337dfc40a538
children 033e1604cf63
files libgaim/protocols/oscar/family_icbm.c libgaim/protocols/oscar/family_locate.c libgaim/protocols/oscar/flap_connection.c libgaim/protocols/oscar/oscar.h
diffstat 4 files changed, 80 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/libgaim/protocols/oscar/family_icbm.c	Sat Dec 02 08:56:35 2006 +0000
+++ b/libgaim/protocols/oscar/family_icbm.c	Sat Dec 02 09:44:53 2006 +0000
@@ -269,8 +269,8 @@
 int aim_im_sendch1_ext(OscarData *od, struct aim_sendimext_args *args)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
 	aim_snacid_t snacid;
+	ByteStream data;
 	guchar cookie[8];
 	int msgtlvlen;
 	static const guint8 deffeatures[] = { 0x01, 0x01, 0x01, 0x02 };
@@ -313,30 +313,26 @@
 		msgtlvlen += 4 /* charset */ + args->msglen;
 	}
 
-	frame = flap_frame_new(od, 0x02, msgtlvlen+128);
-
-	/* XXX - should be optional */
-	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1);
-	aim_putsnac(&frame->data, 0x0004, 0x0006, 0x0000, snacid);
+	byte_stream_init(&data, g_malloc(msgtlvlen + 128), msgtlvlen + 128);
 
 	/* Generate an ICBM cookie */
 	aim_icbm_makecookie(cookie);
 
 	/* ICBM header */
-	aim_im_puticbm(&frame->data, cookie, 0x0001, args->destsn);
+	aim_im_puticbm(&data, cookie, 0x0001, args->destsn);
 
 	/* Message TLV (type 0x0002) */
-	byte_stream_put16(&frame->data, 0x0002);
-	byte_stream_put16(&frame->data, msgtlvlen);
+	byte_stream_put16(&data, 0x0002);
+	byte_stream_put16(&data, msgtlvlen);
 
 	/* Features TLV (type 0x0501) */
-	byte_stream_put16(&frame->data, 0x0501);
+	byte_stream_put16(&data, 0x0501);
 	if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES) {
-		byte_stream_put16(&frame->data, args->featureslen);
-		byte_stream_putraw(&frame->data, args->features, args->featureslen);
+		byte_stream_put16(&data, args->featureslen);
+		byte_stream_putraw(&data, args->features, args->featureslen);
 	} else {
-		byte_stream_put16(&frame->data, sizeof(deffeatures));
-		byte_stream_putraw(&frame->data, deffeatures, sizeof(deffeatures));
+		byte_stream_put16(&data, sizeof(deffeatures));
+		byte_stream_putraw(&data, deffeatures, sizeof(deffeatures));
 	}
 
 	if (args->flags & AIM_IMFLAGS_MULTIPART) {
@@ -344,42 +340,42 @@
 
 		/* Insert each message part in a TLV (type 0x0101) */
 		for (sec = args->mpmsg->parts; sec; sec = sec->next) {
-			byte_stream_put16(&frame->data, 0x0101);
-			byte_stream_put16(&frame->data, sec->datalen + 4);
-			byte_stream_put16(&frame->data, sec->charset);
-			byte_stream_put16(&frame->data, sec->charsubset);
-			byte_stream_putraw(&frame->data, (guchar *)sec->data, sec->datalen);
+			byte_stream_put16(&data, 0x0101);
+			byte_stream_put16(&data, sec->datalen + 4);
+			byte_stream_put16(&data, sec->charset);
+			byte_stream_put16(&data, sec->charsubset);
+			byte_stream_putraw(&data, (guchar *)sec->data, sec->datalen);
 		}
 
 	} else {
 
 		/* Insert message text in a TLV (type 0x0101) */
-		byte_stream_put16(&frame->data, 0x0101);
+		byte_stream_put16(&data, 0x0101);
 
 		/* Message block length */
-		byte_stream_put16(&frame->data, args->msglen + 0x04);
+		byte_stream_put16(&data, args->msglen + 0x04);
 
 		/* Character set */
-		byte_stream_put16(&frame->data, args->charset);
-		byte_stream_put16(&frame->data, args->charsubset);
+		byte_stream_put16(&data, args->charset);
+		byte_stream_put16(&data, args->charsubset);
 
 		/* Message.  Not terminated */
-		byte_stream_putraw(&frame->data, (guchar *)args->msg, args->msglen);
+		byte_stream_putraw(&data, (guchar *)args->msg, args->msglen);
 	}
 
 	/* Set the Autoresponse flag */
 	if (args->flags & AIM_IMFLAGS_AWAY) {
-		byte_stream_put16(&frame->data, 0x0004);
-		byte_stream_put16(&frame->data, 0x0000);
+		byte_stream_put16(&data, 0x0004);
+		byte_stream_put16(&data, 0x0000);
 	} else if (args->flags & AIM_IMFLAGS_ACK) {
 		/* Set the Request Acknowledge flag */
-		byte_stream_put16(&frame->data, 0x0003);
-		byte_stream_put16(&frame->data, 0x0000);
+		byte_stream_put16(&data, 0x0003);
+		byte_stream_put16(&data, 0x0000);
 	}
 
 	if (args->flags & AIM_IMFLAGS_OFFLINE) {
-		byte_stream_put16(&frame->data, 0x0006);
-		byte_stream_put16(&frame->data, 0x0000);
+		byte_stream_put16(&data, 0x0006);
+		byte_stream_put16(&data, 0x0000);
 	}
 
 	/*
@@ -388,12 +384,12 @@
 	 * IMs and when you change your icon.
 	 */
 	if (args->flags & AIM_IMFLAGS_HASICON) {
-		byte_stream_put16(&frame->data, 0x0008);
-		byte_stream_put16(&frame->data, 0x000c);
-		byte_stream_put32(&frame->data, args->iconlen);
-		byte_stream_put16(&frame->data, 0x0001);
-		byte_stream_put16(&frame->data, args->iconsum);
-		byte_stream_put32(&frame->data, args->iconstamp);
+		byte_stream_put16(&data, 0x0008);
+		byte_stream_put16(&data, 0x000c);
+		byte_stream_put32(&data, args->iconlen);
+		byte_stream_put16(&data, 0x0001);
+		byte_stream_put16(&data, args->iconsum);
+		byte_stream_put32(&data, args->iconstamp);
 	}
 
 	/*
@@ -401,11 +397,15 @@
 	 * XXX - Every time?  Surely not...
 	 */
 	if (args->flags & AIM_IMFLAGS_BUDDYREQ) {
-		byte_stream_put16(&frame->data, 0x0009);
-		byte_stream_put16(&frame->data, 0x0000);
+		byte_stream_put16(&data, 0x0009);
+		byte_stream_put16(&data, 0x0000);
 	}
 
-	flap_connection_send(conn, frame);
+	/* XXX - should be optional */
+	snacid = aim_cachesnac(od, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1);
+
+	flap_connection_send_snac(od, conn, 0x0004, 0x0006, 0x0000, snacid, &data);
+	g_free(data.data);
 
 	/* clean out SNACs over 60sec old */
 	aim_cleansnacs(od, 60);
--- a/libgaim/protocols/oscar/family_locate.c	Sat Dec 02 08:56:35 2006 +0000
+++ b/libgaim/protocols/oscar/family_locate.c	Sat Dec 02 09:44:53 2006 +0000
@@ -1356,22 +1356,23 @@
 aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags)
 {
 	FlapConnection *conn;
-	FlapFrame *frame;
+	unsigned int length;
+	ByteStream data;
 	aim_snacid_t snacid;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, SNAC_FAMILY_LOCATE)) || !sn)
 		return -EINVAL;
 
-	frame = flap_frame_new(od, 0x02, 10+4+1+strlen(sn));
+	length = 4 + 1 + strlen(sn);
+	byte_stream_init(&data, g_malloc(length), length);
+	byte_stream_put32(&data, flags);
+	byte_stream_put8(&data, strlen(sn));
+	byte_stream_putstr(&data, sn);
 
 	snacid = aim_cachesnac(od, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);
+	flap_connection_send_snac(od, conn, 0x0002, 0x0015, 0x0000, snacid, &data);
 
-	aim_putsnac(&frame->data, 0x0002, 0x0015, 0x0000, snacid);
-	byte_stream_put32(&frame->data, flags);
-	byte_stream_put8(&frame->data, strlen(sn));
-	byte_stream_putstr(&frame->data, sn);
-
-	flap_connection_send(conn, frame);
+	g_free(data.data);
 
 	return 0;
 }
--- a/libgaim/protocols/oscar/flap_connection.c	Sat Dec 02 08:56:35 2006 +0000
+++ b/libgaim/protocols/oscar/flap_connection.c	Sat Dec 02 09:44:53 2006 +0000
@@ -51,7 +51,7 @@
 }
 
 /**
- * This sends a channel 1 SNAC containing the FLAP version and
+ * This sends a channel 1 FLAP containing the FLAP version and
  * the authentication cookie.  This is sent when connecting to
  * any FLAP server after the initial connection to the auth
  * server.  It is always the very first packet sent by both the
@@ -73,7 +73,35 @@
 }
 
 /**
- * This sends an empty channel 4 SNAC.  This is sent to signify
+ * This sends a channel 2 FLAP containing a SNAC.  The SNAC family and
+ * subtype are looked up in the rate info for this connection, and if
+ * sending this SNAC will induce rate limiting then we delay sending
+ * of the SNAC by putting it into an outgoing holding queue.
+ */
+void
+flap_connection_send_snac(OscarData *od, FlapConnection *conn, guint16 family, guint16 subtype, guint16 flags, aim_snacid_t snacid, ByteStream *data)
+{
+	FlapFrame *frame;
+	guint32 length;
+
+	length = data != NULL ? data->offset : 0;
+
+	frame = flap_frame_new(od, 0x02, 10 + length);
+	aim_putsnac(&frame->data, family, subtype, flags, snacid);
+
+	if (length > 0)
+	{
+		byte_stream_rewind(data);
+		byte_stream_putbs(&frame->data, data, length);
+	}
+
+	/* TODO: Outgoing message throttling */
+
+	flap_connection_send(conn, frame);
+}
+
+/**
+ * This sends an empty channel 4 FLAP.  This is sent to signify
  * that we're logging off.  This shouldn't really be necessary--
  * usually the AIM server will detect that the TCP connection has
  * been destroyed--but it's good practice.
@@ -88,7 +116,7 @@
 }
 
 /**
- * This sends an empty channel 5 SNAC.  This is used as a keepalive
+ * This sends an empty channel 5 FLAP.  This is used as a keepalive
  * packet in FLAP connections.  WinAIM 4.x and higher send these
  * _every minute_ to keep the connection alive.
  */
--- a/libgaim/protocols/oscar/oscar.h	Sat Dec 02 08:56:35 2006 +0000
+++ b/libgaim/protocols/oscar/oscar.h	Sat Dec 02 09:44:53 2006 +0000
@@ -582,6 +582,7 @@
 void flap_connection_send(FlapConnection *conn, FlapFrame *frame);
 void flap_connection_send_version(OscarData *od, FlapConnection *conn);
 void flap_connection_send_version_with_cookie(OscarData *od, FlapConnection *conn, guint16 length, const guint8 *chipsahoy);
+void flap_connection_send_snac(OscarData *od, FlapConnection *conn, guint16 family, const guint16 subtype, guint16 flags, aim_snacid_t snacid, ByteStream *data);
 void flap_connection_send_keepalive(OscarData *od, FlapConnection *conn);
 FlapFrame *flap_frame_new(OscarData *od, guint16 channel, int datalen);