Changeset e374dee for libfaim/txqueue.c
- Timestamp:
- Oct 10, 2003, 5:12:30 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:
- fe6f1d3
- Parents:
- f4d0975
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfaim/txqueue.c
r862371b re374dee 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) || 40 (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT)) { 41 if (framing != AIM_FRAMETYPE_OFT) { 42 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n"); 43 return NULL; 44 } 45 } else { 46 if (framing != AIM_FRAMETYPE_FLAP) { 47 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n"); 48 return NULL; 49 } 50 } 51 52 if (!(fr = (aim_frame_t *)malloc(sizeof(aim_frame_t)))) 53 return NULL; 54 memset(fr, 0, sizeof(aim_frame_t)); 55 56 fr->conn = conn; 57 58 fr->hdrtype = framing; 59 60 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) { 61 62 fr->hdr.flap.type = chan; 63 64 } else if (fr->hdrtype == AIM_FRAMETYPE_OFT) { 65 66 fr->hdr.rend.type = chan; 67 68 } else 69 faimdprintf(sess, 0, "tx_new: unknown framing\n"); 70 71 if (datalen > 0) { 72 fu8_t *data; 73 74 if (!(data = (unsigned char *)malloc(datalen))) { 75 aim_frame_destroy(fr); 76 return NULL; 77 } 78 79 aim_bstream_init(&fr->data, data, datalen); 80 } 81 82 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)))) 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; 83 74 } 84 75 … … 99 90 static int aim_tx_enqueue__queuebased(aim_session_t *sess, aim_frame_t *fr) 100 91 { 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 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; 126 117 } 127 118 … … 140 131 { 141 132 142 if (!fr->conn) { 143 faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n"); 144 aim_frame_destroy(fr); 145 return 0; 146 } 147 148 if (fr->hdrtype == AIM_FRAMETYPE_FLAP) 149 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn); 150 151 fr->handled = 0; /* not sent yet */ 152 153 aim_tx_sendframe(sess, fr); 154 155 aim_frame_destroy(fr); 156 157 return 0; 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; 158 145 } 159 146 160 147 faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *)) 161 148 { 162 163 if (what == AIM_TX_QUEUED) 164 sess->tx_enqueue = &aim_tx_enqueue__queuebased; 165 else if (what == AIM_TX_IMMEDIATE) 166 sess->tx_enqueue = &aim_tx_enqueue__immediate; 167 else if (what == AIM_TX_USER) { 168 if (!func) 169 return -EINVAL; 170 sess->tx_enqueue = func; 171 } else 172 return -EINVAL; /* unknown action */ 173 174 return 0; 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; 175 161 } 176 162 177 163 faim_internal int aim_tx_enqueue(aim_session_t *sess, aim_frame_t *fr) 178 164 { 179 180 181 182 183 184 185 186 187 188 189 190 165 166 /* 167 * If we want to send a connection thats inprogress, we have to force 168 * them to use the queue based version. Otherwise, use whatever they 169 * 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); 191 177 } 192 178 … … 202 188 faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *conn) 203 189 { 204 flap_seqnum_t ret; 205 206 ret = ++conn->seqnum; 207 208 return ret; 190 flap_seqnum_t ret; 191 ret = ++conn->seqnum; 192 return ret; 209 193 } 210 194 211 195 static int aim_send(int fd, const void *buf, size_t count) 212 196 { 213 int left, cur; 214 215 for (cur = 0, left = count; left; ) { 216 int ret; 217 218 ret = send(fd, ((unsigned char *)buf)+cur, left, 0); 219 if (ret == -1) 220 return -1; 221 else if (ret == 0) 222 return cur; 223 224 cur += ret; 225 left -= ret; 226 } 227 228 return cur; 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; 229 214 } 230 215 231 216 static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count) 232 217 { 233 int wrote = 0; 234 if (!bs || !conn || (count < 0)) 235 return -EINVAL; 236 237 if (count > aim_bstream_empty(bs)) 238 count = aim_bstream_empty(bs); /* truncate to remaining space */ 239 240 if (count) { 241 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 242 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { 243 /* I strongly suspect that this is a horrible thing to do 244 * and I feel really guilty doing it. */ 245 const char *sn = aim_directim_getsn(conn); 246 aim_rxcallback_t userfunc; 247 while (count - wrote > 1024) { 248 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); 249 if ((userfunc=aim_callhandler(conn->sessv, conn, 250 AIM_CB_FAM_SPECIAL, 251 AIM_CB_SPECIAL_IMAGETRANSFER))) 252 userfunc(conn->sessv, NULL, sn, 253 count-wrote>1024 ? ((double)wrote / count) : 1); 254 } 255 } 256 if (count - wrote) { 257 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); 258 } 259 260 } 261 262 263 if (((aim_session_t *)conn->sessv)->debug >= 2) { 264 int i; 265 aim_session_t *sess = (aim_session_t *)conn->sessv; 266 267 faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote); 268 for (i = 0; i < wrote; i++) { 269 if (!(i % 8)) 270 faimdprintf(sess, 2, "\n\t"); 271 faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i)); 272 } 273 faimdprintf(sess, 2, "\n"); 274 } 275 276 277 bs->offset += wrote; 278 279 return wrote; 218 int wrote = 0; 219 if (!bs || !conn || (count < 0)) 220 return -EINVAL; 221 222 if (count > aim_bstream_empty(bs)) 223 count = aim_bstream_empty(bs); /* truncate to remaining space */ 224 225 if (count) { 226 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 227 (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) { 228 /* I strongly suspect that this is a horrible thing to do 229 * and I feel really guilty doing it. */ 230 const char *sn = aim_odc_getsn(conn); 231 aim_rxcallback_t userfunc; 232 while (count - wrote > 1024) { 233 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, 1024); 234 if ((userfunc=aim_callhandler(conn->sessv, conn, 235 AIM_CB_FAM_SPECIAL, 236 AIM_CB_SPECIAL_IMAGETRANSFER))) 237 userfunc(conn->sessv, NULL, sn, 238 count-wrote>1024 ? ((double)wrote / count) : 1); 239 } 240 } 241 if (count - wrote) { 242 wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote); 243 } 244 245 } 246 247 if (((aim_session_t *)conn->sessv)->debug >= 2) { 248 int i; 249 aim_session_t *sess = (aim_session_t *)conn->sessv; 250 251 faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote); 252 for (i = 0; i < wrote; i++) { 253 if (!(i % 8)) 254 faimdprintf(sess, 2, "\n\t"); 255 faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i)); 256 } 257 faimdprintf(sess, 2, "\n"); 258 } 259 260 bs->offset += wrote; 261 262 return wrote; 280 263 } 281 264 282 265 static int sendframe_flap(aim_session_t *sess, aim_frame_t *fr) 283 266 { 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 311 312 313 314 315 267 aim_bstream_t obs; 268 fu8_t *obs_raw; 269 int payloadlen, err = 0, obslen; 270 271 payloadlen = aim_bstream_curpos(&fr->data); 272 273 if (!(obs_raw = malloc(6 + payloadlen))) 274 return -ENOMEM; 275 276 aim_bstream_init(&obs, obs_raw, 6 + payloadlen); 277 278 /* FLAP header */ 279 aimbs_put8(&obs, 0x2a); 280 aimbs_put8(&obs, fr->hdr.flap.type); 281 aimbs_put16(&obs, fr->hdr.flap.seqnum); 282 aimbs_put16(&obs, payloadlen); 283 284 /* payload */ 285 aim_bstream_rewind(&fr->data); 286 aimbs_putbs(&obs, &fr->data, payloadlen); 287 288 obslen = aim_bstream_curpos(&obs); 289 aim_bstream_rewind(&obs); 290 if (aim_bstream_send(&obs, fr->conn, obslen) != obslen) 291 err = -errno; 292 293 free(obs_raw); /* XXX aim_bstream_free */ 294 295 fr->handled = 1; 296 fr->conn->lastactivity = time(NULL); 297 298 return err; 316 299 } 317 300
Note: See TracChangeset
for help on using the changeset viewer.