Changeset cf02dd6 for libfaim/txqueue.c


Ignore:
Timestamp:
Dec 10, 2003, 3:20:45 PM (17 years ago)
Author:
James M. Kretchmar <kretch@mit.edu>
Branches:
master, barnowl_perlaim, debian, owl, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
b1fe407
Parents:
8c46404
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfaim/txqueue.c

    r1e34e40 rcf02dd6  
    2929faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen)
    3030{
    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;
    7482}
    7583
     
    9098static int aim_tx_enqueue__queuebased(aim_session_t *sess, aim_frame_t *fr)
    9199{
    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;
    117125}
    118126
     
    131139{
    132140
    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;
    145157}
    146158
    147159faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *))
    148160{
    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;
    161174}
    162175
    163176faim_internal int aim_tx_enqueue(aim_session_t *sess, aim_frame_t *fr)
    164177{
    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);
     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);
    177190}
    178191
     
    188201faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *conn)
    189202{
    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;
    193208}
    194209
    195210static int aim_send(int fd, const void *buf, size_t count)
    196211{
    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;
    214228}
    215229
    216230static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count)
    217231{
    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;
    275277}
    276278
    277279static int sendframe_flap(aim_session_t *sess, aim_frame_t *fr)
    278280{
    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;
    311313}
    312314
Note: See TracChangeset for help on using the changeset viewer.