pidgin: 8cca6c24: oscar: Update the rate calculations base...
darkrain42 at pidgin.im
darkrain42 at pidgin.im
Tue Nov 3 01:01:10 EST 2009
-----------------------------------------------------------------
Revision: 8cca6c24d83be547b31efecb47a0cc82a672d4de
Ancestor: fc4b6d88441f4d07f1219f2c1601cc45884b8b20
Author: aman at tmm1.net
Date: 2009-11-03T05:53:06
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/8cca6c24d83be547b31efecb47a0cc82a672d4de
Modified files:
libpurple/protocols/oscar/family_oservice.c
libpurple/protocols/oscar/flap_connection.c
libpurple/protocols/oscar/oscar.c
libpurple/protocols/oscar/oscar.h
ChangeLog:
oscar: Update the rate calculations based on OSCAR docs.
Another patch from Aman "tmm1" Gupta.
-------------- next part --------------
============================================================
--- libpurple/protocols/oscar/family_oservice.c f3a7b230108963d9a00848d8bd3075921d81c8f1
+++ libpurple/protocols/oscar/family_oservice.c 52ed87049d764f56537bb0c4a7f69cb360c8cc8f
@@ -319,7 +319,10 @@ rateresp(OscarData *od, FlapConnection *
for (i = 0; i < numclasses; i++)
{
struct rateclass *rateclass;
+ guint32 delta;
+ struct timeval now;
+ gettimeofday(&now, NULL);
rateclass = g_new0(struct rateclass, 1);
rateclass->classid = byte_stream_get16(bs);
@@ -339,11 +342,24 @@ rateresp(OscarData *od, FlapConnection *
* the new version hardcoded here.
*/
if (mod->version >= 3)
- byte_stream_getrawbuf(bs, rateclass->unknown, sizeof(rateclass->unknown));
+ {
+ rateclass->delta = byte_stream_get32(bs);
+ rateclass->dropping_snacs = byte_stream_get8(bs);
+ delta = rateclass->delta;
+
+ rateclass->last.tv_sec = now.tv_sec - delta / 1000;
+ delta %= 1000;
+ rateclass->last.tv_usec = now.tv_usec - delta * 1000;
+ }
+ else
+ {
+ rateclass->delta = rateclass->dropping_snacs = 0;
+ rateclass->last.tv_sec = now.tv_sec;
+ rateclass->last.tv_usec = now.tv_usec;
+ }
+
rateclass->members = g_hash_table_new(g_direct_hash, g_direct_equal);
- rateclass->last.tv_sec = 0;
- rateclass->last.tv_usec = 0;
conn->rateclasses = g_slist_prepend(conn->rateclasses, rateclass);
}
conn->rateclasses = g_slist_reverse(conn->rateclasses);
@@ -383,8 +399,7 @@ rateresp(OscarData *od, FlapConnection *
*/
/*
- * Last step in the conn init procedure is to acknowledge that we
- * agree to these draconian limitations.
+ * Subscribe to rate change information for all rate classes.
*/
aim_srv_rates_addparam(od, conn);
@@ -451,7 +466,10 @@ ratechange(OscarData *od, FlapConnection
aim_rxcallback_t userfunc;
guint16 code, classid;
struct rateclass *rateclass;
+ guint32 delta;
+ struct timeval now;
+ gettimeofday(&now, NULL);
code = byte_stream_get16(bs);
classid = byte_stream_get16(bs);
@@ -468,9 +486,30 @@ ratechange(OscarData *od, FlapConnection
rateclass->current = byte_stream_get32(bs);
rateclass->max = byte_stream_get32(bs);
- if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
- ret = userfunc(od, conn, frame, code, classid, rateclass->windowsize, rateclass->clear, rateclass->alert, rateclass->limit, rateclass->disconnect, rateclass->current, rateclass->max);
+ if (mod->version >= 3)
+ {
+ rateclass->delta = byte_stream_get32(bs);
+ rateclass->dropping_snacs = byte_stream_get8(bs);
+ delta = rateclass->delta;
+
+ rateclass->last.tv_sec = now.tv_sec - delta / 1000;
+ delta %= 1000;
+ rateclass->last.tv_usec = now.tv_usec - delta * 1000;
+ }
+ else
+ {
+ rateclass->delta = rateclass->dropping_snacs = 0;
+ rateclass->last.tv_sec = now.tv_sec;
+ rateclass->last.tv_usec = now.tv_usec;
+ }
+
+ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) {
+ /* Can't pass in guint8 via ... varargs, so we use an unsigned int */
+ unsigned int dropping_snacs = rateclass->dropping_snacs;
+ ret = userfunc(od, conn, frame, code, classid, rateclass->windowsize, rateclass->clear, rateclass->alert, rateclass->limit, rateclass->disconnect, rateclass->current, rateclass->max, rateclass->delta, dropping_snacs);
+ }
+
return ret;
}
============================================================
--- libpurple/protocols/oscar/flap_connection.c 19709b97801d98fd480c6acc2f4b78aeab14d750
+++ libpurple/protocols/oscar/flap_connection.c 697f15a4cb37bfad606470d2deb95875ffb98488
@@ -131,11 +131,13 @@ rateclass_get_new_current(FlapConnection
rateclass_get_new_current(FlapConnection *conn, struct rateclass *rateclass, struct timeval *now)
{
unsigned long timediff; /* In milliseconds */
+ guint32 current;
timediff = (now->tv_sec - rateclass->last.tv_sec) * 1000 + (now->tv_usec - rateclass->last.tv_usec) / 1000;
+ current = ((rateclass->current * (rateclass->windowsize - 1)) + timediff) / rateclass->windowsize;
- /* This formula is taken from the joscar API docs. Preesh. */
- return MIN(((rateclass->current * (rateclass->windowsize - 1)) + timediff) / rateclass->windowsize, rateclass->max);
+ /* This formula is taken from http://dev.aol.com/aim/oscar/#RATELIMIT */
+ return MIN(current, rateclass->max);
}
/*
@@ -161,8 +163,7 @@ static gboolean flap_connection_send_sna
new_current = rateclass_get_new_current(conn, rateclass, &now);
- /* (Add 100ms padding to account for inaccuracies in the calculation) */
- if (new_current < rateclass->alert + 100)
+ if (rateclass->dropping_snacs || new_current <= rateclass->alert)
/* Not ready to send this SNAC yet--keep waiting. */
return FALSE;
@@ -245,10 +246,9 @@ flap_connection_send_snac_with_priority(
gettimeofday(&now, NULL);
new_current = rateclass_get_new_current(conn, rateclass, &now);
- /* (Add 100ms padding to account for inaccuracies in the calculation) */
- if (new_current < rateclass->alert + 100)
+ if (rateclass->dropping_snacs || new_current <= rateclass->alert)
{
- purple_debug_info("oscar", "Current rate for conn %p would be %u, but we alert at %u; enqueueing\n", conn, new_current, (rateclass->alert + 100));
+ purple_debug_info("oscar", "Current rate for conn %p would be %u, but we alert at %u; enqueueing\n", conn, new_current, rateclass->alert);
enqueue = TRUE;
}
============================================================
--- libpurple/protocols/oscar/oscar.c 9282145f5e8a72ec2bcc0de15e99bf7b506830ed
+++ libpurple/protocols/oscar/oscar.c eb9598cfa477d506fbfad9a1b96eb6ee21c1d02e
@@ -3740,7 +3740,8 @@ static int purple_parse_ratechange(Oscar
};
va_list ap;
guint16 code, rateclass;
- guint32 windowsize, clear, alert, limit, disconnect, currentavg, maxavg;
+ guint32 windowsize, clear, alert, limit, disconnect, currentavg, maxavg, delta;
+ guint8 dropping_snacs;
va_start(ap, fr);
code = (guint16)va_arg(ap, unsigned int);
@@ -3752,23 +3753,28 @@ static int purple_parse_ratechange(Oscar
disconnect = va_arg(ap, guint32);
currentavg = va_arg(ap, guint32);
maxavg = va_arg(ap, guint32);
+ delta = va_arg(ap, guint32);
+ dropping_snacs = (guint8)va_arg(ap, unsigned int);
va_end(ap);
purple_debug_misc("oscar",
"rate %s (param ID 0x%04hx): curavg = %u, maxavg = %u, alert at %u, "
- "clear warning at %u, limit at %u, disconnect at %u (window size = %u)\n",
+ "clear warning at %u, limit at %u, disconnect at %u, delta is %u, dropping is %u (window size = %u)\n",
(code < 5) ? codes[code] : codes[0],
rateclass,
currentavg, maxavg,
alert, clear,
limit, disconnect,
- windowsize);
+ delta,
+ dropping_snacs,
+ windowsize
+ );
if (code == AIM_RATE_CODE_LIMIT)
{
purple_debug_warning("oscar", _("The last action you attempted could not be "
"performed because you are over the rate limit. "
- "Please wait 10 seconds and try again."));
+ "Please wait 10 seconds and try again.\n"));
}
return 1;
============================================================
--- libpurple/protocols/oscar/oscar.h 7479032fbbad999fb11c429327d3d72d9e39fe6d
+++ libpurple/protocols/oscar/oscar.h e709c12b5ee15abb9ca81a73cf2904cb302a0a47
@@ -1685,7 +1685,8 @@ struct rateclass {
guint32 disconnect;
guint32 current;
guint32 max;
- guint8 unknown[5]; /* only present in versions >= 3 */
+ guint32 delta;
+ guint8 dropping_snacs;
GHashTable *members; /* Key is family and subtype, value is TRUE. */
struct timeval last; /**< The time when we last sent a SNAC of this rate class. */
More information about the Commits
mailing list