Changeset cf02dd6 for libfaim/txqueue.c
- Timestamp:
- Dec 10, 2003, 3:20:45 PM (21 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
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 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 168 169 170 171 172 173 174 175 176 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 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 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.