Mercurial > pidgin
comparison libfaim/aim_txqueue.c @ 445:e4c34ca88d9b
[gaim-migrate @ 455]
Hehehehehe
Libfaim got updated, gaim got updated. btw, gaim/faim can't sign in yet,
don't ask me why. it's not my fault.
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Thu, 29 Jun 2000 20:40:28 +0000 |
| parents | 0f14e6d8a51b |
| children | 595ac7759563 |
comparison
equal
deleted
inserted
replaced
| 444:e7885c54ed2f | 445:e4c34ca88d9b |
|---|---|
| 12 * | 12 * |
| 13 * This is more for looks than anything else. | 13 * This is more for looks than anything else. |
| 14 * | 14 * |
| 15 * Right now, that is. If/when we implement a pool of transmit | 15 * Right now, that is. If/when we implement a pool of transmit |
| 16 * frames, this will become the request-an-unused-frame part. | 16 * frames, this will become the request-an-unused-frame part. |
| 17 */ | 17 * |
| 18 struct command_tx_struct *aim_tx_new(int chan, struct aim_conn_t *conn, int datalen) | 18 * framing = AIM_FRAMETYPE_OFT/OSCAR |
| 19 * chan = channel for OSCAR, hdrtype for OFT | |
| 20 * | |
| 21 */ | |
| 22 struct command_tx_struct *aim_tx_new(unsigned short framing, int chan, struct aim_conn_t *conn, int datalen) | |
| 19 { | 23 { |
| 20 struct command_tx_struct *new; | 24 struct command_tx_struct *new; |
| 21 | 25 |
| 22 if (!conn) { | 26 if (!conn) { |
| 23 printf("aim_tx_new: ERROR: no connection specified\n"); | 27 printf("aim_tx_new: ERROR: no connection specified\n"); |
| 28 if (!new) | 32 if (!new) |
| 29 return NULL; | 33 return NULL; |
| 30 memset(new, 0, sizeof(struct command_tx_struct)); | 34 memset(new, 0, sizeof(struct command_tx_struct)); |
| 31 | 35 |
| 32 new->conn = conn; | 36 new->conn = conn; |
| 33 new->type = chan; | |
| 34 | 37 |
| 35 if(datalen) { | 38 if(datalen) { |
| 36 new->data = (u_char *)malloc(datalen); | 39 new->data = (u_char *)malloc(datalen); |
| 37 new->commandlen = datalen; | 40 new->commandlen = datalen; |
| 41 } else | |
| 42 new->data = NULL; | |
| 43 | |
| 44 new->hdrtype = framing; | |
| 45 if (new->hdrtype == AIM_FRAMETYPE_OSCAR) { | |
| 46 new->hdr.oscar.type = chan; | |
| 47 } else if (new->hdrtype == AIM_FRAMETYPE_OFT) { | |
| 48 new->hdr.oft.type = chan; | |
| 49 new->hdr.oft.hdr2len = 0; /* this will get setup by caller */ | |
| 50 } else { | |
| 51 printf("tx_new: unknown framing\n"); | |
| 38 } | 52 } |
| 39 | 53 |
| 40 return new; | 54 return new; |
| 41 } | 55 } |
| 42 | 56 |
| 64 if (newpacket->conn == NULL) { | 78 if (newpacket->conn == NULL) { |
| 65 faimdprintf(1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); | 79 faimdprintf(1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); |
| 66 newpacket->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); | 80 newpacket->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); |
| 67 } | 81 } |
| 68 | 82 |
| 69 /* assign seqnum */ | 83 if (newpacket->hdrtype == AIM_FRAMETYPE_OSCAR) { |
| 70 newpacket->seqnum = aim_get_next_txseqnum(newpacket->conn); | 84 /* assign seqnum */ |
| 85 newpacket->hdr.oscar.seqnum = aim_get_next_txseqnum(newpacket->conn); | |
| 86 } | |
| 71 /* set some more fields */ | 87 /* set some more fields */ |
| 72 newpacket->lock = 1; /* lock */ | 88 newpacket->lock = 1; /* lock */ |
| 73 newpacket->sent = 0; /* not sent yet */ | 89 newpacket->sent = 0; /* not sent yet */ |
| 74 newpacket->next = NULL; /* always last */ | 90 newpacket->next = NULL; /* always last */ |
| 75 | 91 |
| 114 free(newpacket->data); | 130 free(newpacket->data); |
| 115 free(newpacket); | 131 free(newpacket); |
| 116 return -1; | 132 return -1; |
| 117 } | 133 } |
| 118 | 134 |
| 119 newpacket->seqnum = aim_get_next_txseqnum(newpacket->conn); | 135 if (newpacket->hdrtype == AIM_FRAMETYPE_OSCAR) |
| 136 newpacket->hdr.oscar.seqnum = aim_get_next_txseqnum(newpacket->conn); | |
| 120 | 137 |
| 121 newpacket->lock = 1; /* lock */ | 138 newpacket->lock = 1; /* lock */ |
| 122 newpacket->sent = 0; /* not sent yet */ | 139 newpacket->sent = 0; /* not sent yet */ |
| 123 | 140 |
| 124 aim_tx_sendframe(newpacket); | 141 aim_tx_sendframe(sess, newpacket); |
| 125 | 142 |
| 126 if (newpacket->data) | 143 if (newpacket->data) |
| 127 free(newpacket->data); | 144 free(newpacket->data); |
| 128 free(newpacket); | 145 free(newpacket); |
| 129 | 146 |
| 167 | 184 |
| 168 if (sess->queue_outgoing == NULL) | 185 if (sess->queue_outgoing == NULL) |
| 169 faimdprintf(2, "aim_tx_flushqueue(): queue empty"); | 186 faimdprintf(2, "aim_tx_flushqueue(): queue empty"); |
| 170 else { | 187 else { |
| 171 for (cur = sess->queue_outgoing; cur; cur = cur->next) { | 188 for (cur = sess->queue_outgoing; cur; cur = cur->next) { |
| 172 faimdprintf(2, "\t %2x %4x %4x %1d %1d\n", | 189 faimdprintf(2, "\t %2x %2x %4x %4x %1d %1d\n", |
| 173 cur->type, cur->seqnum, | 190 cur->hdrtype, |
| 191 (cur->hdrtype==AIM_FRAMETYPE_OFT)?cur->hdr.oft.type:cur->hdr.oscar.type, | |
| 192 (cur->hdrtype==AIM_FRAMETYPE_OSCAR)?cur->seqnum:0, | |
| 174 cur->commandlen, cur->lock, | 193 cur->commandlen, cur->lock, |
| 175 cur->sent); | 194 cur->sent); |
| 176 } | 195 } |
| 177 } | 196 } |
| 178 | 197 |
| 204 * 7) Unlock the struct. | 223 * 7) Unlock the struct. |
| 205 * 8) Free the temp buffer | 224 * 8) Free the temp buffer |
| 206 * 9) Step to next struct in list and go back to 1. | 225 * 9) Step to next struct in list and go back to 1. |
| 207 * | 226 * |
| 208 */ | 227 */ |
| 209 int aim_tx_sendframe(struct command_tx_struct *cur) | 228 int aim_tx_sendframe(struct aim_session_t *sess, struct command_tx_struct *cur) |
| 210 { | 229 { |
| 211 u_char *curPacket; | 230 int buflen = 0; |
| 231 unsigned char *curPacket; | |
| 212 | 232 |
| 213 if (!cur) | 233 if (!cur) |
| 214 return -1; /* fatal */ | 234 return -1; /* fatal */ |
| 215 | 235 |
| 216 cur->lock = 1; /* lock the struct */ | 236 cur->lock = 1; /* lock the struct */ |
| 217 | 237 |
| 238 if (cur->hdrtype == AIM_FRAMETYPE_OSCAR) | |
| 239 buflen = cur->commandlen + 6; | |
| 240 else if (cur->hdrtype == AIM_FRAMETYPE_OFT) | |
| 241 buflen = cur->hdr.oft.hdr2len + 8; | |
| 242 else { | |
| 243 cur->lock = 0; | |
| 244 return -1; | |
| 245 } | |
| 246 | |
| 218 /* allocate full-packet buffer */ | 247 /* allocate full-packet buffer */ |
| 219 curPacket = (char *) malloc(cur->commandlen + 6); | 248 if (!(curPacket = (unsigned char *) malloc(buflen))) { |
| 249 cur->lock = 0; | |
| 250 return -1; | |
| 251 } | |
| 220 | 252 |
| 221 /* command byte */ | 253 if (cur->hdrtype == AIM_FRAMETYPE_OSCAR) { |
| 222 curPacket[0] = 0x2a; | 254 /* command byte */ |
| 255 curPacket[0] = 0x2a; | |
| 223 | 256 |
| 224 /* type/family byte */ | 257 /* type/family byte */ |
| 225 curPacket[1] = cur->type; | 258 curPacket[1] = cur->hdr.oscar.type; |
| 226 | 259 |
| 227 /* bytes 3+4: word: FLAP sequence number */ | 260 /* bytes 3+4: word: FLAP sequence number */ |
| 228 aimutil_put16(curPacket+2, cur->seqnum); | 261 aimutil_put16(curPacket+2, cur->hdr.oscar.seqnum); |
| 229 | 262 |
| 230 /* bytes 5+6: word: SNAC len */ | 263 /* bytes 5+6: word: SNAC len */ |
| 231 aimutil_put16(curPacket+4, cur->commandlen); | 264 aimutil_put16(curPacket+4, cur->commandlen); |
| 232 | 265 |
| 233 /* bytes 7 and on: raw: SNAC data */ /* XXX: ye gods! get rid of this! */ | 266 /* bytes 7 and on: raw: SNAC data */ /* XXX: ye gods! get rid of this! */ |
| 234 memcpy(&(curPacket[6]), cur->data, cur->commandlen); | 267 memcpy(&(curPacket[6]), cur->data, cur->commandlen); |
| 235 | 268 |
| 236 /* full image of raw packet data now in curPacket */ | 269 } else if (cur->hdrtype == AIM_FRAMETYPE_OFT) { |
| 270 int z = 0; | |
| 271 | |
| 272 z += aimutil_put8(curPacket+z, 0x4f); | |
| 273 z += aimutil_put8(curPacket+z, 0x44); | |
| 274 z += aimutil_put8(curPacket+z, 0x43); | |
| 275 z += aimutil_put8(curPacket+z, 0x32); | |
| 276 | |
| 277 z += aimutil_put16(curPacket+z, cur->hdr.oft.hdr2len + 8); | |
| 278 z += aimutil_put16(curPacket+z, cur->hdr.oft.type); | |
| 279 | |
| 280 memcpy(curPacket+z, cur->hdr.oft.hdr2, cur->hdr.oft.hdr2len); | |
| 281 } | |
| 282 | |
| 283 /* | |
| 284 * For OSCAR, a full image of the raw packet data now in curPacket. | |
| 285 * For OFT, an image of just the bloated header is in curPacket, | |
| 286 * since OFT allows us to do the data in a different write (yay!). | |
| 287 */ | |
| 237 faim_mutex_lock(&cur->conn->active); | 288 faim_mutex_lock(&cur->conn->active); |
| 238 if ( (u_int)write(cur->conn->fd, curPacket, (cur->commandlen + 6)) != (cur->commandlen + 6)) { | 289 if ( (u_int)write(cur->conn->fd, curPacket, buflen) != buflen) { |
| 239 faim_mutex_unlock(&cur->conn->active); | 290 faim_mutex_unlock(&cur->conn->active); |
| 240 printf("\nWARNING: Error in sending packet 0x%4x -- will try again next time\n\n", cur->seqnum); | 291 cur->sent = 1; |
| 241 cur->sent = 0; /* mark it unsent */ | 292 aim_conn_kill(sess, &cur->conn); |
| 242 return 0; /* bail out -- continuable error */ | 293 return 0; /* bail out */ |
| 243 } else { | 294 } |
| 244 faimdprintf(2, "\nSENT 0x%4x\n\n", cur->seqnum); | 295 |
| 245 | 296 if ((cur->hdrtype == AIM_FRAMETYPE_OFT) && cur->commandlen) { |
| 246 cur->sent = 1; /* mark the struct as sent */ | 297 if (write(cur->conn->fd, cur->data, cur->commandlen) != cur->commandlen) { |
| 247 cur->conn->lastactivity = time(NULL); | 298 /* |
| 248 } | 299 * Theres nothing we can do about this since we've already sent the |
| 300 * header! The connection is unstable. | |
| 301 */ | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 cur->sent = 1; /* mark the struct as sent */ | |
| 306 cur->conn->lastactivity = time(NULL); | |
| 307 | |
| 249 faim_mutex_unlock(&cur->conn->active); | 308 faim_mutex_unlock(&cur->conn->active); |
| 250 | 309 |
| 251 #if debug > 2 | 310 #if debug > 2 |
| 252 faimdprintf(2, "\nPacket:"); | 311 faimdprintf(2, "\nPacket:"); |
| 253 for (i = 0; i < (cur->commandlen + 6); i++) { | 312 for (i = 0; i < (cur->commandlen + 6); i++) { |
| 291 if ((cur->conn->lastactivity + cur->conn->forcedlatency) >= time(NULL)) { | 350 if ((cur->conn->lastactivity + cur->conn->forcedlatency) >= time(NULL)) { |
| 292 /* FIXME FIXME -- should be a break! we dont want to block the upper layers */ | 351 /* FIXME FIXME -- should be a break! we dont want to block the upper layers */ |
| 293 sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL)); | 352 sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL)); |
| 294 } | 353 } |
| 295 | 354 |
| 296 if (aim_tx_sendframe(cur) == -1) | 355 if (aim_tx_sendframe(sess, cur) == -1) |
| 297 break; | 356 break; |
| 298 } | 357 } |
| 299 } | 358 } |
| 300 | 359 |
| 301 /* purge sent commands from queue */ | 360 /* purge sent commands from queue */ |
| 322 | 381 |
| 323 if (sess->queue_outgoing->next == NULL) { | 382 if (sess->queue_outgoing->next == NULL) { |
| 324 if (!sess->queue_outgoing->lock && sess->queue_outgoing->sent) { | 383 if (!sess->queue_outgoing->lock && sess->queue_outgoing->sent) { |
| 325 tmp = sess->queue_outgoing; | 384 tmp = sess->queue_outgoing; |
| 326 sess->queue_outgoing = NULL; | 385 sess->queue_outgoing = NULL; |
| 386 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) | |
| 387 free(tmp->hdr.oft.hdr2); | |
| 327 free(tmp->data); | 388 free(tmp->data); |
| 328 free(tmp); | 389 free(tmp); |
| 329 } | 390 } |
| 330 return; | 391 return; |
| 331 } | 392 } |
| 332 | 393 |
| 333 for(cur = sess->queue_outgoing; cur->next != NULL; ) { | 394 for(cur = sess->queue_outgoing; cur->next != NULL; ) { |
| 334 if (!cur->next->lock && cur->next->sent) { | 395 if (!cur->next->lock && cur->next->sent) { |
| 335 tmp = cur->next; | 396 tmp = cur->next; |
| 336 cur->next = tmp->next; | 397 cur->next = tmp->next; |
| 398 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) | |
| 399 free(tmp->hdr.oft.hdr2); | |
| 337 free(tmp->data); | 400 free(tmp->data); |
| 338 free(tmp); | 401 free(tmp); |
| 339 } | 402 } |
| 340 cur = cur->next; | 403 cur = cur->next; |
| 341 | 404 |
