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); |