Changeset cf02dd6 for libfaim/txqueue.c
- Timestamp:
- Dec 10, 2003, 3:20:45 PM (22 years ago)
- Branches:
- master, barnowl_perlaim, debian, owl, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- b1fe407
- Parents:
- 8c46404
- File:
-
- 1 edited
-
libfaim/txqueue.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libfaim/txqueue.c
r1e34e40 rcf02dd6 29 29 faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen) 30 30 { 31 aim_frame_t *fr; 32 33 if (!conn) { 34 faimdprintf(sess, 0, "aim_tx_new: ERROR: no connection specified\n"); 35 return NULL; 36 } 37 38 /* For sanity... */ 39 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) || (conn->type == AIM_CONN_TYPE_LISTENER)) { 40 if (framing != AIM_FRAMETYPE_OFT) { 41 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n"); 42 return NULL; 43 } 44 } else { 45 if (framing != AIM_FRAMETYPE_FLAP) { 46 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n"); 47 return NULL; 48 } 49 } 50 51 if (!(fr = (aim_frame_t *)malloc(sizeof(aim_frame_t)))) return NULL; 52 memset(fr, 0, sizeof(aim_frame_t)); 53 54 fr->conn = conn; 55 fr->hdrtype = framing; 56 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 57 fr->hdr.flap.type = chan; 58 } else if (fr->hdrtype == AIM_FRAMETYPE_OFT) { 59 fr->hdr.rend.type = chan; 60 } else { 61 faimdprintf(sess, 0, "tx_new: unknown framing\n"); 62 } 63 64 if (datalen > 0) { 65 fu8_t *data; 66 if (!(data = (unsigned char *)malloc(datalen))) { 67 aim_frame_destroy(fr); 68 return NULL; 69 } 70 aim_bstream_init(&fr->data, data, datalen); 71 } 72 73 return fr; 31 aim_frame_t *fr; 32 33 if (!conn) { 34 faimdprintf(sess, 0, "aim_tx_new: ERROR: no connection specified\n"); 35 return NULL; 36 } 37 38 /* For sanity... */ 39 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) || (conn->type == AIM_CONN_TYPE_LISTENER)) { 40 if (framing != AIM_FRAMETYPE_OFT) { 41 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n"); 42 return NULL; 43 } 44 } else { 45 if (framing != AIM_FRAMETYPE_FLAP) { 46 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n"); 47 return NULL; 48 } 49 } 50 51 if (!(fr = (aim_frame_t *)malloc(sizeof(aim_frame_t)))) 52 return NULL; 53 memset(fr, 0, sizeof(aim_frame_t)); 54 55 fr->conn = conn; 56 57 fr->hdrtype = framing; 58 59 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 60 61 fr->hdr.flap.type = chan; 62 63 } else if (fr->hdrtype == AIM_FRAMETYPE_OFT) { 64 65 fr->hdr.rend.type = chan; 66 67 } else 68 faimdprintf(sess, 0, "tx_new: unknown framing\n"); 69 70 if (datalen > 0) { 71 fu8_t *data; 72 73 if (!(data = (unsigned char *)malloc(datalen))) { 74 aim_frame_destroy(fr); 75 return NULL; 76 } 77 78 aim_bstream_init(&fr->data, data, datalen); 79 } 80 81 return fr; 74 82 } 75 83 … … 90 98 static int aim_tx_enqueue__queuebased(aim_session_t *sess, aim_frame_t *fr) 91 99 { 92 93 if (!fr->conn) {94 faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n");95 fr->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);96 }97 98 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) {99 /* assign seqnum -- XXX should really not assign until hardxmit */100 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn);101 }102 103 fr->handled = 0; /* not sent yet */104 105 /* see overhead note in aim_rxqueue counterpart */106 if (!sess->queue_outgoing)107 sess->queue_outgoing = fr;108 else {109 aim_frame_t *cur;110 111 for (cur = sess->queue_outgoing; cur->next; cur = cur->next)112 ;113 cur->next = fr;114 }115 116 return 0;100 101 if (!fr->conn) { 102 faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); 103 fr->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); 104 } 105 106 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 107 /* assign seqnum -- XXX should really not assign until hardxmit */ 108 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 109 } 110 111 fr->handled = 0; /* not sent yet */ 112 113 /* see overhead note in aim_rxqueue counterpart */ 114 if (!sess->queue_outgoing) 115 sess->queue_outgoing = fr; 116 else { 117 aim_frame_t *cur; 118 119 for (cur = sess->queue_outgoing; cur->next; cur = cur->next) 120 ; 121 cur->next = fr; 122 } 123 124 return 0; 117 125 } 118 126 … … 131 139 { 132 140 133 if (!fr->conn) { 134 faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n"); 135 aim_frame_destroy(fr); 136 return 0; 137 } 138 139 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 140 fr->handled = 0; /* not sent yet */ 141 aim_tx_sendframe(sess, fr); 142 aim_frame_destroy(fr); 143 144 return 0; 141 if (!fr->conn) { 142 faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n"); 143 aim_frame_destroy(fr); 144 return 0; 145 } 146 147 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) 148 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 149 150 fr->handled = 0; /* not sent yet */ 151 152 aim_tx_sendframe(sess, fr); 153 154 aim_frame_destroy(fr); 155 156 return 0; 145 157 } 146 158 147 159 faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *)) 148 160 { 149 if (what == AIM_TX_QUEUED) { 150 sess->tx_enqueue = &aim_tx_enqueue__queuebased; 151 } else if (what == AIM_TX_IMMEDIATE) { 152 sess->tx_enqueue = &aim_tx_enqueue__immediate; 153 } else if (what == AIM_TX_USER) { 154 if (!func) return -EINVAL; 155 sess->tx_enqueue = func; 156 } else { 157 return -EINVAL; /* unknown action */ 158 } 159 160 return 0; 161 162 if (what == AIM_TX_QUEUED) 163 sess->tx_enqueue = &aim_tx_enqueue__queuebased; 164 else if (what == AIM_TX_IMMEDIATE) 165 sess->tx_enqueue = &aim_tx_enqueue__immediate; 166 else if (what == AIM_TX_USER) { 167 if (!func) 168 return -EINVAL; 169 sess->tx_enqueue = func; 170 } else 171 return -EINVAL; /* unknown action */ 172 173 return 0; 161 174 } 162 175 163 176 faim_internal int aim_tx_enqueue(aim_session_t *sess, aim_frame_t *fr) 164 177 { 165 166 /*167 * If we want to send a connection thats inprogress, we have to force168 * them to use the queue based version. Otherwise, use whatever they169 * want.170 */171 if (fr && fr->conn &&172 (fr->conn->status & AIM_CONN_STATUS_INPROGRESS)) {173 return aim_tx_enqueue__queuebased(sess, fr);174 }175 176 return (*sess->tx_enqueue)(sess, fr);178 179 /* 180 * If we want to send a connection thats inprogress, we have to force 181 * them to use the queue based version. Otherwise, use whatever they 182 * want. 183 */ 184 if (fr && fr->conn && 185 (fr->conn->status & AIM_CONN_STATUS_INPROGRESS)) { 186 return aim_tx_enqueue__queuebased(sess, fr); 187 } 188 189 return (*sess->tx_enqueue)(sess, fr); 177 190 } 178 191 … … 188 201 faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *conn) 189 202 { 190 flap_seqnum_t ret; 191 ret = ++conn->seqnum; 192 return ret; 203 flap_seqnum_t ret; 204 205 ret = ++conn->seqnum; 206 207 return ret; 193 208 } 194 209 195 210 static int aim_send(int fd, const void *buf, size_t count) 196 211 { 197 int left, cur; 198 199 for (cur = 0, left = count; left; ) { 200 int ret; 201 202 ret = send(fd, ((unsigned char *)buf)+cur, left, 0); 203 if (ret == -1) { 204 return -1; 205 } else if (ret == 0) { 206 return cur; 207 } 208 209 cur += ret; 210 left -= ret; 211 } 212 213 return cur; 212 int left, cur; 213 214 for (cur = 0, left = count; left; ) { 215 int ret; 216 217 ret = send(fd, ((unsigned char *)buf)+cur, left, 0); 218 if (ret == -1) 219 return -1; 220 else if (ret == 0) 221 return cur; 222 223 cur += ret; 224 left -= ret; 225 } 226 227 return cur; 214 228 } 215 229 216 230 static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count) 217 231 { 218 int wrote = 0; 219 int rv = 0; 220 if (!bs || !conn || (count < 0)) 221 return -EINVAL; 222 223 if (count > aim_bstream_empty(bs)) 224 count = aim_bstream_empty(bs); /* truncate to remaining space */ 225 226 if (count) { 227 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 228 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { 229 /* I strongly suspect that this is a horrible thing to do 230 * and I feel really guilty doing it. */ 231 const char *sn = aim_odc_getsn(conn); 232 aim_rxcallback_t userfunc; 233 while (count - wrote > 1024) { 234 rv = aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); 235 if (rv < 0) { 236 fprintf(stderr, "aim_bstream_send: aim_send failed...\n"); 237 return -EINVAL; 238 } 239 wrote = wrote + rv; 240 241 if ((userfunc=aim_callhandler(conn->sessv, conn, 242 AIM_CB_FAM_SPECIAL, 243 AIM_CB_SPECIAL_IMAGETRANSFER))) 244 userfunc(conn->sessv, NULL, sn, 245 count-wrote>1024 ? ((double)wrote / count) : 1); 246 } 247 } 248 if (count - wrote) { 249 rv = aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); 250 if (rv < 0) { 251 fprintf(stderr, "aim_bstream_send: aim_send failed...\n"); 252 return -EINVAL; 253 } 254 wrote = wrote + rv; 255 } 256 257 } 258 259 if (((aim_session_t *)conn->sessv)->debug >= 2) { 260 int i; 261 aim_session_t *sess = (aim_session_t *)conn->sessv; 262 263 faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote); 264 for (i = 0; i < wrote; i++) { 265 if (!(i % 8)) 266 faimdprintf(sess, 2, "\n\t"); 267 faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i)); 268 } 269 faimdprintf(sess, 2, "\n"); 270 } 271 272 bs->offset += wrote; 273 274 return wrote; 232 int wrote = 0; 233 if (!bs || !conn || (count < 0)) 234 return -EINVAL; 235 236 if (count > aim_bstream_empty(bs)) 237 count = aim_bstream_empty(bs); /* truncate to remaining space */ 238 239 if (count) { 240 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 241 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { 242 /* I strongly suspect that this is a horrible thing to do 243 * and I feel really guilty doing it. */ 244 const char *sn = aim_odc_getsn(conn); 245 aim_rxcallback_t userfunc; 246 while (count - wrote > 1024) { 247 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); 248 if ((userfunc=aim_callhandler(conn->sessv, conn, 249 AIM_CB_FAM_SPECIAL, 250 AIM_CB_SPECIAL_IMAGETRANSFER))) 251 userfunc(conn->sessv, NULL, sn, 252 count-wrote>1024 ? ((double)wrote / count) : 1); 253 } 254 } 255 if (count - wrote) { 256 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); 257 } 258 259 } 260 261 if (((aim_session_t *)conn->sessv)->debug >= 2) { 262 int i; 263 aim_session_t *sess = (aim_session_t *)conn->sessv; 264 265 faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote); 266 for (i = 0; i < wrote; i++) { 267 if (!(i % 8)) 268 faimdprintf(sess, 2, "\n\t"); 269 faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i)); 270 } 271 faimdprintf(sess, 2, "\n"); 272 } 273 274 bs->offset += wrote; 275 276 return wrote; 275 277 } 276 278 277 279 static int sendframe_flap(aim_session_t *sess, aim_frame_t *fr) 278 280 { 279 aim_bstream_t obs;280 fu8_t *obs_raw;281 int payloadlen, err = 0, obslen;282 283 payloadlen = aim_bstream_curpos(&fr->data);284 285 if (!(obs_raw = malloc(6 + payloadlen)))286 return -ENOMEM;287 288 aim_bstream_init(&obs, obs_raw, 6 + payloadlen);289 290 /* FLAP header */291 aimbs_put8(&obs, 0x2a);292 aimbs_put8(&obs, fr->hdr.flap.type);293 aimbs_put16(&obs, fr->hdr.flap.seqnum);294 aimbs_put16(&obs, payloadlen);295 296 /* payload */297 aim_bstream_rewind(&fr->data);298 aimbs_putbs(&obs, &fr->data, payloadlen);299 300 obslen = aim_bstream_curpos(&obs);301 aim_bstream_rewind(&obs);302 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen)303 err = -errno;304 305 free(obs_raw); /* XXX aim_bstream_free */306 307 fr->handled = 1;308 fr->conn->lastactivity = time(NULL);309 310 return err;281 aim_bstream_t obs; 282 fu8_t *obs_raw; 283 int payloadlen, err = 0, obslen; 284 285 payloadlen = aim_bstream_curpos(&fr->data); 286 287 if (!(obs_raw = malloc(6 + payloadlen))) 288 return -ENOMEM; 289 290 aim_bstream_init(&obs, obs_raw, 6 + payloadlen); 291 292 /* FLAP header */ 293 aimbs_put8(&obs, 0x2a); 294 aimbs_put8(&obs, fr->hdr.flap.type); 295 aimbs_put16(&obs, fr->hdr.flap.seqnum); 296 aimbs_put16(&obs, payloadlen); 297 298 /* payload */ 299 aim_bstream_rewind(&fr->data); 300 aimbs_putbs(&obs, &fr->data, payloadlen); 301 302 obslen = aim_bstream_curpos(&obs); 303 aim_bstream_rewind(&obs); 304 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen) 305 err = -errno; 306 307 free(obs_raw); /* XXX aim_bstream_free */ 308 309 fr->handled = 1; 310 fr->conn->lastactivity = time(NULL); 311 312 return err; 311 313 } 312 314
Note: See TracChangeset
for help on using the changeset viewer.
