Mercurial > pidgin
comparison libfaim/aim_txqueue.c @ 279:501e09c51cbc
[gaim-migrate @ 289]
Updates to libfaim -> updates to gaim.
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Mon, 29 May 2000 20:30:48 +0000 |
| parents | cfa39d39dec6 |
| children | 7b06ba09ffe2 |
comparison
equal
deleted
inserted
replaced
| 278:29e1669b006b | 279:501e09c51cbc |
|---|---|
| 1 /* | 1 /* |
| 2 * aim_txqueue.c | 2 * aim_txqueue.c |
| 3 * | 3 * |
| 4 * Herein lies all the mangement routines for the transmit (Tx) queue. | 4 * Herein lies all the mangement routines for the transmit (Tx) queue. |
| 5 * | |
| 6 * Changes by EWarmenhoven Fri May 26 22:52:46 UTC 2000: | |
| 7 * - added aim_tx_flushqueue() to the end of aim_tx_enqueue() so that I don't | |
| 8 * have to worry about it any more. mid tells me that doing so will solve the | |
| 9 * 100% bug. Thanks mid! | |
| 10 * | 5 * |
| 11 */ | 6 */ |
| 12 | 7 |
| 13 #include <aim.h> | 8 #include <aim.h> |
| 14 | 9 |
| 22 */ | 17 */ |
| 23 struct command_tx_struct *aim_tx_new(int chan, struct aim_conn_t *conn, int datalen) | 18 struct command_tx_struct *aim_tx_new(int chan, struct aim_conn_t *conn, int datalen) |
| 24 { | 19 { |
| 25 struct command_tx_struct *new; | 20 struct command_tx_struct *new; |
| 26 | 21 |
| 27 if (!conn) | 22 if (!conn) { |
| 23 printf("aim_tx_new: ERROR: no connection specified\n"); | |
| 28 return NULL; | 24 return NULL; |
| 25 } | |
| 29 | 26 |
| 30 new = (struct command_tx_struct *)malloc(sizeof(struct command_tx_struct)); | 27 new = (struct command_tx_struct *)malloc(sizeof(struct command_tx_struct)); |
| 31 if (!new) | 28 if (!new) |
| 32 return NULL; | 29 return NULL; |
| 33 memset(new, 0, sizeof(struct command_tx_struct)); | 30 memset(new, 0, sizeof(struct command_tx_struct)); |
| 42 | 39 |
| 43 return new; | 40 return new; |
| 44 } | 41 } |
| 45 | 42 |
| 46 /* | 43 /* |
| 47 * aim_tx_enqeue() | 44 * aim_tx_enqeue__queuebased() |
| 48 * | 45 * |
| 49 * The overall purpose here is to enqueue the passed in command struct | 46 * The overall purpose here is to enqueue the passed in command struct |
| 50 * into the outgoing (tx) queue. Basically... | 47 * into the outgoing (tx) queue. Basically... |
| 51 * 1) Make a scope-irrelevent copy of the struct | 48 * 1) Make a scope-irrelevent copy of the struct |
| 52 * 2) Lock the struct | 49 * 2) Lock the struct |
| 53 * 3) Mark as not-sent-yet | 50 * 3) Mark as not-sent-yet |
| 54 * 4) Enqueue the struct into the list | 51 * 4) Enqueue the struct into the list |
| 55 * 5) Unlock the struct once it's linked in | 52 * 5) Unlock the struct once it's linked in |
| 56 * 6) Return | 53 * 6) Return |
| 57 * | 54 * |
| 58 */ | 55 * Note that this is only used when doing queue-based transmitting; |
| 59 int aim_tx_enqueue(struct aim_session_t *sess, | 56 * that is, when sess->tx_enqueue is set to &aim_tx_enqueue__queuebased. |
| 60 struct command_tx_struct *newpacket) | 57 * |
| 58 */ | |
| 59 int aim_tx_enqueue__queuebased(struct aim_session_t *sess, | |
| 60 struct command_tx_struct *newpacket) | |
| 61 { | 61 { |
| 62 struct command_tx_struct *cur; | 62 struct command_tx_struct *cur; |
| 63 | 63 |
| 64 if (newpacket->conn == NULL) { | 64 if (newpacket->conn == NULL) { |
| 65 faimdprintf(1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); | 65 faimdprintf(1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); |
| 90 faimdprintf(2, "calling aim_tx_printqueue()\n"); | 90 faimdprintf(2, "calling aim_tx_printqueue()\n"); |
| 91 aim_tx_printqueue(sess); | 91 aim_tx_printqueue(sess); |
| 92 faimdprintf(2, "back from aim_tx_printqueue()\n"); | 92 faimdprintf(2, "back from aim_tx_printqueue()\n"); |
| 93 #endif | 93 #endif |
| 94 | 94 |
| 95 /* mid tells me this should solve a lot of my problems */ | 95 return 0; |
| 96 aim_tx_flushqueue(sess); | 96 } |
| 97 | |
| 98 /* | |
| 99 * aim_tx_enqueue__immediate() | |
| 100 * | |
| 101 * Parallel to aim_tx_enqueue__queuebased, however, this bypasses | |
| 102 * the whole queue mess when you want immediate writes to happen. | |
| 103 * | |
| 104 * Basically the same as its __queuebased couterpart, however | |
| 105 * instead of doing a list append, it just calls aim_tx_sendframe() | |
| 106 * right here. | |
| 107 * | |
| 108 */ | |
| 109 int aim_tx_enqueue__immediate(struct aim_session_t *sess, struct command_tx_struct *newpacket) | |
| 110 { | |
| 111 if (newpacket->conn == NULL) { | |
| 112 faimdprintf(1, "aim_tx_enqueue: ERROR: packet has no connection\n"); | |
| 113 if (newpacket->data) | |
| 114 free(newpacket->data); | |
| 115 free(newpacket); | |
| 116 return -1; | |
| 117 } | |
| 118 | |
| 119 newpacket->seqnum = aim_get_next_txseqnum(newpacket->conn); | |
| 120 | |
| 121 newpacket->lock = 1; /* lock */ | |
| 122 newpacket->sent = 0; /* not sent yet */ | |
| 123 | |
| 124 aim_tx_sendframe(newpacket); | |
| 125 | |
| 126 if (newpacket->data) | |
| 127 free(newpacket->data); | |
| 128 free(newpacket); | |
| 97 | 129 |
| 98 return 0; | 130 return 0; |
| 99 } | 131 } |
| 100 | 132 |
| 101 /* | 133 /* |
| 167 * 7) Unlock the struct. | 199 * 7) Unlock the struct. |
| 168 * 8) Free the temp buffer | 200 * 8) Free the temp buffer |
| 169 * 9) Step to next struct in list and go back to 1. | 201 * 9) Step to next struct in list and go back to 1. |
| 170 * | 202 * |
| 171 */ | 203 */ |
| 204 int aim_tx_sendframe(struct command_tx_struct *cur) | |
| 205 { | |
| 206 u_char *curPacket; | |
| 207 | |
| 208 if (!cur) | |
| 209 return -1; /* fatal */ | |
| 210 | |
| 211 cur->lock = 1; /* lock the struct */ | |
| 212 | |
| 213 /* allocate full-packet buffer */ | |
| 214 curPacket = (char *) malloc(cur->commandlen + 6); | |
| 215 | |
| 216 /* command byte */ | |
| 217 curPacket[0] = 0x2a; | |
| 218 | |
| 219 /* type/family byte */ | |
| 220 curPacket[1] = cur->type; | |
| 221 | |
| 222 /* bytes 3+4: word: FLAP sequence number */ | |
| 223 aimutil_put16(curPacket+2, cur->seqnum); | |
| 224 | |
| 225 /* bytes 5+6: word: SNAC len */ | |
| 226 aimutil_put16(curPacket+4, cur->commandlen); | |
| 227 | |
| 228 /* bytes 7 and on: raw: SNAC data */ /* XXX: ye gods! get rid of this! */ | |
| 229 memcpy(&(curPacket[6]), cur->data, cur->commandlen); | |
| 230 | |
| 231 /* full image of raw packet data now in curPacket */ | |
| 232 faim_mutex_lock(&cur->conn->active); | |
| 233 if ( (u_int)write(cur->conn->fd, curPacket, (cur->commandlen + 6)) != (cur->commandlen + 6)) { | |
| 234 faim_mutex_unlock(&cur->conn->active); | |
| 235 printf("\nWARNING: Error in sending packet 0x%4x -- will try again next time\n\n", cur->seqnum); | |
| 236 cur->sent = 0; /* mark it unsent */ | |
| 237 return 0; /* bail out -- continuable error */ | |
| 238 } else { | |
| 239 faimdprintf(2, "\nSENT 0x%4x\n\n", cur->seqnum); | |
| 240 | |
| 241 cur->sent = 1; /* mark the struct as sent */ | |
| 242 cur->conn->lastactivity = time(NULL); | |
| 243 } | |
| 244 faim_mutex_unlock(&cur->conn->active); | |
| 245 | |
| 246 #if debug > 2 | |
| 247 faimdprintf(2, "\nPacket:"); | |
| 248 for (i = 0; i < (cur->commandlen + 6); i++) { | |
| 249 if ((i % 8) == 0) { | |
| 250 faimdprintf(2, "\n\t"); | |
| 251 } | |
| 252 if (curPacket[i] >= ' ' && curPacket[i]<127) { | |
| 253 faimdprintf(2, "%c=%02x ", curPacket[i], curPacket[i]); | |
| 254 } else { | |
| 255 faimdprintf(2, "0x%2x ", curPacket[i]); | |
| 256 } | |
| 257 } | |
| 258 faimdprintf(2, "\n"); | |
| 259 #endif | |
| 260 cur->lock = 0; /* unlock the struct */ | |
| 261 free(curPacket); /* free up full-packet buffer */ | |
| 262 | |
| 263 return 1; /* success */ | |
| 264 } | |
| 265 | |
| 172 int aim_tx_flushqueue(struct aim_session_t *sess) | 266 int aim_tx_flushqueue(struct aim_session_t *sess) |
| 173 { | 267 { |
| 174 struct command_tx_struct *cur; | 268 struct command_tx_struct *cur; |
| 175 u_char *curPacket = NULL; | 269 |
| 176 #if debug > 1 | 270 #if debug > 1 |
| 177 int i = 0; | 271 int i = 0; |
| 178 #endif | 272 #endif |
| 179 | 273 |
| 180 if (sess->queue_outgoing == NULL) | 274 if (sess->queue_outgoing == NULL) |
| 191 */ | 285 */ |
| 192 if ((cur->conn->lastactivity + cur->conn->forcedlatency) >= time(NULL)) { | 286 if ((cur->conn->lastactivity + cur->conn->forcedlatency) >= time(NULL)) { |
| 193 /* FIXME FIXME -- should be a break! we dont want to block the upper layers */ | 287 /* FIXME FIXME -- should be a break! we dont want to block the upper layers */ |
| 194 sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL)); | 288 sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL)); |
| 195 } | 289 } |
| 196 | 290 |
| 197 cur->lock = 1; /* lock the struct */ | 291 if (aim_tx_sendframe(cur) == -1) |
| 198 | 292 break; |
| 199 /* allocate full-packet buffer */ | |
| 200 curPacket = (char *) malloc(cur->commandlen + 6); | |
| 201 | |
| 202 /* command byte */ | |
| 203 curPacket[0] = 0x2a; | |
| 204 | |
| 205 /* type/family byte */ | |
| 206 curPacket[1] = cur->type; | |
| 207 | |
| 208 /* bytes 3+4: word: FLAP sequence number */ | |
| 209 aimutil_put16(curPacket+2, cur->seqnum); | |
| 210 | |
| 211 /* bytes 5+6: word: SNAC len */ | |
| 212 aimutil_put16(curPacket+4, cur->commandlen); | |
| 213 | |
| 214 /* bytes 7 and on: raw: SNAC data */ | |
| 215 memcpy(&(curPacket[6]), cur->data, cur->commandlen); | |
| 216 | |
| 217 /* full image of raw packet data now in curPacket */ | |
| 218 if ( (u_int)write(cur->conn->fd, curPacket, (cur->commandlen + 6)) != (cur->commandlen + 6)) { | |
| 219 printf("\nWARNING: Error in sending packet 0x%4x -- will try again next time\n\n", cur->seqnum); | |
| 220 cur->sent = 0; /* mark it unsent */ | |
| 221 continue; /* bail out */ | |
| 222 } else { | |
| 223 faimdprintf(2, "\nSENT 0x%4x\n\n", cur->seqnum); | |
| 224 | |
| 225 cur->sent = 1; /* mark the struct as sent */ | |
| 226 cur->conn->lastactivity = time(NULL); | |
| 227 } | |
| 228 #if debug > 2 | |
| 229 faimdprintf(2, "\nPacket:"); | |
| 230 for (i = 0; i < (cur->commandlen + 6); i++) { | |
| 231 if ((i % 8) == 0) { | |
| 232 faimdprintf(2, "\n\t"); | |
| 233 } | |
| 234 if (curPacket[i] >= ' ' && curPacket[i]<127) { | |
| 235 faimdprintf(2, "%c=%02x ", curPacket[i], curPacket[i]); | |
| 236 } else { | |
| 237 faimdprintf(2, "0x%2x ", curPacket[i]); | |
| 238 } | |
| 239 } | |
| 240 faimdprintf(2, "\n"); | |
| 241 #endif | |
| 242 cur->lock = 0; /* unlock the struct */ | |
| 243 free(curPacket); /* free up full-packet buffer */ | |
| 244 } | 293 } |
| 245 } | 294 } |
| 246 | 295 |
| 247 /* purge sent commands from queue */ | 296 /* purge sent commands from queue */ |
| 248 aim_tx_purgequeue(sess); | 297 aim_tx_purgequeue(sess); |
