# HG changeset patch # User Mark Doliner # Date 1165052693 0 # Node ID 25c3a33c648509675ec6f8d7869d3023cd412fa9 # Parent 337dfc40a5389362ed61c63c83dd7b32cabce75e [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 diff -r 337dfc40a538 -r 25c3a33c6485 libgaim/protocols/oscar/family_icbm.c --- 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); diff -r 337dfc40a538 -r 25c3a33c6485 libgaim/protocols/oscar/family_locate.c --- 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; } diff -r 337dfc40a538 -r 25c3a33c6485 libgaim/protocols/oscar/flap_connection.c --- 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. */ diff -r 337dfc40a538 -r 25c3a33c6485 libgaim/protocols/oscar/oscar.h --- 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);