Changeset e374dee for libfaim/txqueue.c


Ignore:
Timestamp:
Oct 10, 2003, 5:12:30 PM (18 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:
fe6f1d3
Parents:
f4d0975
Message:
*** empty log message ***
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfaim/txqueue.c

    r862371b re374dee  
    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) ||
    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;
    8374}
    8475
     
    9990static int aim_tx_enqueue__queuebased(aim_session_t *sess, aim_frame_t *fr)
    10091{
    101 
    102         if (!fr->conn) {
    103                 faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n");
    104                 fr->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
    105         }
    106 
    107         if (fr->hdrtype == AIM_FRAMETYPE_FLAP) {
    108                 /* assign seqnum -- XXX should really not assign until hardxmit */
    109                 fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn);
    110         }
    111 
    112         fr->handled = 0; /* not sent yet */
    113 
    114         /* see overhead note in aim_rxqueue counterpart */
    115         if (!sess->queue_outgoing)
    116                 sess->queue_outgoing = fr;
    117         else {
    118                 aim_frame_t *cur;
    119 
    120                 for (cur = sess->queue_outgoing; cur->next; cur = cur->next)
    121                         ;
    122                 cur->next = fr;
    123         }
    124 
    125         return 0;
     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;
    126117}
    127118
     
    140131{
    141132
    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;
    158145}
    159146
    160147faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *))
    161148{
    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;
    175161}
    176162
    177163faim_internal int aim_tx_enqueue(aim_session_t *sess, aim_frame_t *fr)
    178164{
    179        
    180         /*
    181         * If we want to send a connection thats inprogress, we have to force
    182         * them to use the queue based version. Otherwise, use whatever they
    183         * want.
    184         */
    185         if (fr && fr->conn &&
    186                         (fr->conn->status & AIM_CONN_STATUS_INPROGRESS)) {
    187                 return aim_tx_enqueue__queuebased(sess, fr);
    188         }
    189 
    190         return (*sess->tx_enqueue)(sess, fr);
     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);
    191177}
    192178
     
    202188faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *conn)
    203189{
    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;
    209193}
    210194
    211195static int aim_send(int fd, const void *buf, size_t count)
    212196{
    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;
    229214}
    230215
    231216static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count)
    232217{
    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;
    280263}
    281264
    282265static int sendframe_flap(aim_session_t *sess, aim_frame_t *fr)
    283266{
    284         aim_bstream_t obs;
    285         fu8_t *obs_raw;
    286         int payloadlen, err = 0, obslen;
    287 
    288         payloadlen = aim_bstream_curpos(&fr->data);
    289 
    290         if (!(obs_raw = malloc(6 + payloadlen)))
    291                 return -ENOMEM;
    292 
    293         aim_bstream_init(&obs, obs_raw, 6 + payloadlen);
    294 
    295         /* FLAP header */
    296         aimbs_put8(&obs, 0x2a);
    297         aimbs_put8(&obs, fr->hdr.flap.type);
    298         aimbs_put16(&obs, fr->hdr.flap.seqnum);
    299         aimbs_put16(&obs, payloadlen);
    300 
    301         /* payload */
    302         aim_bstream_rewind(&fr->data);
    303         aimbs_putbs(&obs, &fr->data, payloadlen);
    304 
    305         obslen = aim_bstream_curpos(&obs);
    306         aim_bstream_rewind(&obs);
    307         if (aim_bstream_send(&obs, fr->conn, obslen) != obslen)
    308                 err = -errno;
    309        
    310         free(obs_raw); /* XXX aim_bstream_free */
    311 
    312         fr->handled = 1;
    313         fr->conn->lastactivity = time(NULL);
    314 
    315         return err;
     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;
    316299}
    317300
Note: See TracChangeset for help on using the changeset viewer.