No release numbers
------------------
+ - Fri Dec 15 02:04:12 UTC 2000
+ - Parse rate changes *properly*
+ - Add sample code to faimtest demonstrating my approximations
+ on how to fiddle with aim_conn_setlatency() in relation
+ to the rate changes (properly wildly conservative). [I also
+ copied this stuff into mfaim.]
+
- Thu Dec 14 03:39:34 UTC 2000
- Change the 0x01 to a 0x00 in auth request to make buddy lists work again
- Rearrange bytes in setversions() to match winaim
workingPtr->handled = aim_parse_hostonline(sess, workingPtr);
else if (subtype == 0x0007)
workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
+ else if (subtype == 0x000a)
+ workingPtr->handled = aim_parse_ratechange_middle(sess, workingPtr);
else
workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr);
} else if (family == 0x000e) {
{
rxcallback_t userfunc = NULL;
int ret = 1;
- unsigned long newrate;
+ int i;
+ int code;
+ unsigned long parmid, windowsize, clear, alert, limit, disconnect;
+ unsigned long currentavg, maxavg;
- if (command->commandlen != 0x2f) {
- printf("faim: unknown rate change length 0x%04x\n", command->commandlen);
- return 1;
- }
-
- newrate = aimutil_get32(command->data+34);
+ i = 10;
+
+ code = aimutil_get16(command->data+i);
+ i += 2;
+
+ parmid = aimutil_get16(command->data+i);
+ i += 2;
+
+ windowsize = aimutil_get32(command->data+i);
+ i += 4;
+ clear = aimutil_get32(command->data+i);
+ i += 4;
+ alert = aimutil_get32(command->data+i);
+ i += 4;
+ limit = aimutil_get32(command->data+i);
+ i += 4;
+ disconnect = aimutil_get32(command->data+i);
+ i += 4;
+ currentavg = aimutil_get32(command->data+i);
+ i += 4;
+ maxavg = aimutil_get32(command->data+i);
+ i += 4;
if ((userfunc = aim_callhandler(command->conn, 0x0001, 0x000a)))
- ret = userfunc(sess, command, newrate);
+ ret = userfunc(sess, command, code, parmid, windowsize, clear, alert, limit, disconnect, currentavg, maxavg);
return ret;
}
int aim_parse_last_bad(struct aim_session_t *, struct command_rx_struct *, ...);
faim_internal int aim_parse_generalerrs(struct aim_session_t *, struct command_rx_struct *command, ...);
faim_internal int aim_parsemotd_middle(struct aim_session_t *sess, struct command_rx_struct *command, ...);
+
+#define AIM_RATE_CODE_CHANGE 0x0001
+#define AIM_RATE_CODE_WARNING 0x0002
+#define AIM_RATE_CODE_LIMIT 0x0003
+#define AIM_RATE_CODE_CLEARLIMIT 0x0004
faim_internal int aim_parse_ratechange_middle(struct aim_session_t *sess, struct command_rx_struct *command);
+
faim_internal int aim_parse_evilnotify_middle(struct aim_session_t *sess, struct command_rx_struct *command);
faim_internal int aim_parse_msgack_middle(struct aim_session_t *sess, struct command_rx_struct *command);
int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
{
+ static char *codes[5] = {"invalid",
+ "change",
+ "warning",
+ "limit",
+ "limit cleared"};
va_list ap;
- unsigned long newrate;
-
+ int code;
+ unsigned long parmid, windowsize, clear, alert, limit, disconnect;
+ unsigned long currentavg, maxavg;
+
va_start(ap, command);
- newrate = va_arg(ap, unsigned long);
+
+ /* See code explanations below */
+ code = va_arg(ap, int);
+
+ /*
+ * Known parameter ID's...
+ * 0x0003 BOS (normal ICBMs, userinfo requests, etc)
+ * 0x0005 Chat messages
+ */
+ parmid = va_arg(ap, unsigned long);
+
+ /*
+ * Not sure what this is exactly. I think its the temporal
+ * relation factor (ie, how to make the rest of the numbers
+ * make sense in the real world).
+ */
+ windowsize = va_arg(ap, unsigned long);
+
+ /* Explained below */
+ clear = va_arg(ap, unsigned long);
+ alert = va_arg(ap, unsigned long);
+ limit = va_arg(ap, unsigned long);
+ disconnect = va_arg(ap, unsigned long);
+ currentavg = va_arg(ap, unsigned long);
+ maxavg = va_arg(ap, unsigned long);
+
va_end(ap);
- printf("faimtest: ratechange: %lu\n", newrate);
+
+ printf("faimtest: rate %s (paramid 0x%04lx): curavg = %ld, maxavg = %ld, alert at %ld, clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)\n",
+ (code < 5)?codes[code]:"invalid",
+ parmid,
+ currentavg, maxavg,
+ alert, clear,
+ limit, disconnect,
+ windowsize);
+
+ if (code == AIM_RATE_CODE_CHANGE) {
+ /*
+ * Not real sure when these get sent.
+ */
+ if (currentavg >= clear)
+ aim_conn_setlatency(command->conn, 0);
+
+ } else if (code == AIM_RATE_CODE_WARNING) {
+ /*
+ * We start getting WARNINGs the first time we go below the 'alert'
+ * limit (currentavg < alert) and they stop when either we pause
+ * long enough for currentavg to go above 'clear', or until we
+ * flood it bad enough to go below 'limit' (and start getting
+ * LIMITs instead) or even further and go below 'disconnect' and
+ * get disconnected completely (and won't be able to login right
+ * away either).
+ */
+ aim_conn_setlatency(command->conn, windowsize/4); /* XXX this is bogus! */
+
+ } else if (code == AIM_RATE_CODE_LIMIT) {
+ /*
+ * When we hit LIMIT, messages will start getting dropped.
+ */
+ aim_conn_setlatency(command->conn, windowsize/2); /* XXX this is bogus! */
+
+ } else if (code == AIM_RATE_CODE_CLEARLIMIT) {
+ /*
+ * The limit is cleared when curavg goes above 'clear'.
+ */
+ aim_conn_setlatency(command->conn, 0);
+ }
return 1;
}