home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / NR4TIMER.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  5KB  |  189 lines

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.   
  6. #include "global.h"
  7. #ifdef NETROM
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include <ctype.h>
  15.   
  16. #undef NR4DEBUG
  17.   
  18. unsigned Nr_timertype = 0;      /* default to binary exponential */
  19.   
  20. /* The ACK timer has expired without any data becoming available.
  21.  * Go ahead and send an ACK.
  22.  */
  23.   
  24. void
  25. nr4ackit(p)
  26. void *p ;
  27. {
  28.     struct nr4cb *cb  = (struct nr4cb *)p ;
  29.     struct nr4hdr rhdr ;
  30.   
  31. #ifdef NR4DEBUG
  32.     printf("ACKIT called.\n") ;
  33. #endif
  34.   
  35.     stop_timer(&cb->tack);  /* fixed N1BEE 920811 */
  36.     if (cb->qfull)              /* Are we choked? */
  37.         rhdr.opcode = NR4OPACK | NR4CHOKE ;
  38.     else
  39.         rhdr.opcode = NR4OPACK ;
  40.     rhdr.yourindex = cb->yournum ;
  41.     rhdr.yourid = cb->yourid ;
  42.     rhdr.u.ack.rxseq = cb->rxpected ;
  43.   
  44.     nr4sframe(cb->remote.node, &rhdr, NULLBUF) ;
  45. }
  46.   
  47. /* Called when one of the transmit timers has expired */
  48.   
  49. void
  50. nr4txtimeout(p)
  51. void *p ;
  52. {
  53.     struct nr4cb *cb = (struct nr4cb *)p ;
  54.     unsigned seq ;
  55.     struct nr4txbuf *t ;
  56.   
  57.     /* Sanity check */
  58.   
  59.     if (cb->state != NR4STCON)
  60.         return ;
  61.   
  62.     /* Scan through the send window looking for expired timers */
  63.   
  64.     for (seq = cb->ackxpected ;
  65.         nr4between(cb->ackxpected, seq, cb->nextosend) ;
  66.     seq = (seq + 1) & NR4SEQMASK) {
  67.   
  68.         t = &cb->txbufs[seq % cb->window] ;
  69.   
  70.         if (t->tretry.state == TIMER_EXPIRE) {
  71.             t->tretry.state = TIMER_STOP ;  /* So we don't do it again */
  72.             /* This thing above fails because the timer code
  73.                itself does the reverse, changing TIMER_STOP to
  74.                TIMER_EXPIRE.  What we really want to do here
  75.                is properly restart the timer.  -- N1BEE */
  76.             /* start_timer(&(t->tretry)); */
  77.   
  78.             if (t->retries == Nr4retries) {
  79.                 cb->dreason = NR4RTIMEOUT ;
  80.                 nr4state(cb, NR4STDISC) ;
  81.             }
  82.   
  83.             t->retries++ ;
  84.   
  85.             /* We keep track of the highest retry count in the window. */
  86.             /* If packet times out and its new retry count exceeds the */
  87.             /* max, we update the max and bump the backoff level.  This */
  88.             /* expedient is to avoid bumping the backoff level for every */
  89.             /* expiration, since with more than one timer we would back */
  90.             /* off way too fast (and at a rate dependent on the window */
  91.             /* size! */
  92.   
  93.             if (t->retries > cb->txmax) {
  94.                 cb->blevel++ ;
  95.                 cb->txmax = t->retries ;    /* update the max */
  96.             }
  97.   
  98.             nr4sbuf(cb,seq) ;   /* Resend buffer */
  99.         }
  100.     }
  101.   
  102. }
  103.   
  104. /* Connect/disconnect acknowledgement timeout */
  105.   
  106. void
  107. nr4cdtimeout(p)
  108. void *p ;
  109. {
  110.     struct nr4cb *cb = (struct nr4cb *)p ;
  111.     struct nr4hdr hdr ;
  112.   
  113.     switch(cb->state) {
  114.         case NR4STCPEND:
  115.             if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  116.                 cb->dreason = NR4RTIMEOUT ;
  117.                 nr4state(cb, NR4STDISC) ;       /* Give it up */
  118.             } else {
  119.             /* Set up header */
  120.   
  121.                 hdr.opcode = NR4OPCONRQ ;
  122.                 hdr.u.conreq.myindex = cb->mynum ;
  123.                 hdr.u.conreq.myid = cb->myid ;
  124.                 hdr.u.conreq.window = Nr4window ;
  125.                 memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
  126.                 memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
  127.   
  128.             /* Bump tries counter and backoff level, and restart timer */
  129.             /* We use a linear or binary exponential backoff. */
  130.   
  131.                 cb->cdtries++ ;
  132.                 cb->blevel++ ;
  133.   
  134.                 if(Nr_timertype)
  135.                 /* linear */
  136.                     set_timer(&cb->tcd,dur_timer(&cb->tcd)+cb->srtt);
  137.                 else
  138.                 /* exponential */
  139.                     set_timer(&cb->tcd,dur_timer(&cb->tcd)*2);
  140.   
  141.                 start_timer(&cb->tcd) ;
  142.   
  143.             /* Send connect request packet */
  144.   
  145.                 nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  146.             }
  147.             break ;
  148.   
  149.         case NR4STDPEND:
  150.             if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  151.                 cb->dreason = NR4RTIMEOUT ;
  152.                 nr4state(cb, NR4STDISC) ;       /* Give it up */
  153.             } else {
  154.             /* Format header */
  155.   
  156.                 hdr.opcode = NR4OPDISRQ ;
  157.                 hdr.yourindex = cb->yournum ;
  158.                 hdr.yourid = cb->yourid ;
  159.   
  160.             /* Bump retry count and start timer */
  161.             /* We don't really need to be fancy here, since we */
  162.             /* should have a good idea of the round trip time by now. */
  163.   
  164.                 cb->cdtries++ ;
  165.                 start_timer(&cb->tcd) ;
  166.   
  167.             /* Send disconnect request packet */
  168.   
  169.                 nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  170.             }
  171.             break ;
  172.     }
  173. }
  174.   
  175. /* The choke timer has expired.  Unchoke and kick. */
  176.   
  177. void
  178. nr4unchoke(p)
  179. void *p ;
  180. {
  181.     struct nr4cb *cb = (struct nr4cb *)p ;
  182.   
  183.     cb->choked = 0 ;
  184.     nr4output(cb) ;
  185. }
  186.   
  187. #endif /* NETROM */
  188.   
  189.