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