home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / h / if / Radio / c / NR4TIMER < prev    next >
Encoding:
Text File  |  1993-12-22  |  5.3 KB  |  165 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 <stdio.h>
  7. #include <ctype.h>
  8. #include <time.h>
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "timer.h"
  12. #include "ax25.h"
  13. #include "lapb.h"
  14. #include "netrom.h"
  15. #include "nr4.h"
  16. #include "misc.h"
  17.  
  18. #undef NR4DEBUG
  19.  
  20. /* The ACK timer has expired without any data becoming available.
  21.  * Go ahead and send an ACK.
  22.  */
  23.  
  24. void nr4ackit(char *p)
  25. {
  26.         struct nr4cb *cb  = (struct nr4cb *)p ;
  27.         struct nr4hdr rhdr ;
  28.  
  29. #ifdef NR4DEBUG
  30.         cwprintf(NULL, "ACKIT called.\r\n") ;
  31. #endif
  32.         if (cb->qfull)                          /* Are we choked? */
  33.                 rhdr.opcode = NR4OPACK | NR4CHOKE ;
  34.         else
  35.                 rhdr.opcode = NR4OPACK ;
  36.         rhdr.yourindex = cb->yournum ;
  37.         rhdr.yourid = cb->yourid ;
  38.         rhdr.u.ack.rxseq = cb->rxpected ;
  39.  
  40.         nr4sframe(&cb->node, &rhdr, NULLBUF) ;
  41. }
  42.  
  43. /* Called when one of the transmit timers has expired */
  44.  
  45. void nr4txtimeout(char *p)
  46. {
  47.         struct nr4cb *cb = (struct nr4cb *)p ;
  48.         unsigned seq ;
  49.         struct nr4txbuf *t ;
  50.  
  51.         /* Sanity check */
  52.  
  53.         if (cb->state != NR4STCON)
  54.                 return ;
  55.  
  56.         /* Scan through the send window looking for expired timers */
  57.         
  58.         for (seq = cb->ackxpected ;
  59.                  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  60.                  seq = (seq + 1) & NR4SEQMASK) {
  61.                 
  62.                 t = &cb->txbufs[seq % cb->window] ;
  63.  
  64.                 if (t->tretry.state == TIMER_EXPIRE) {
  65.                         t->tretry.state = TIMER_STOP ;  /* So we don't do it again */
  66.  
  67.                         if (t->retries == Nr4retries) {
  68.                                 cb->dreason = NR4RTIMEOUT ;
  69.                                 nr4state(cb, NR4STDISC) ;
  70.                         }
  71.  
  72.                         t->retries++ ;
  73.                         
  74.                         /* We keep track of the highest retry count in the window. */
  75.                         /* If packet times out and its new retry count exceeds the */
  76.                         /* max, we update the max and bump the backoff level.  This */
  77.                         /* expedient is to avoid bumping the backoff level for every */
  78.                         /* expiration, since with more than one timer we would back */
  79.                         /* off way too fast (and at a rate dependent on the window */
  80.                         /* size! */
  81.  
  82.                         if (t->retries > cb->txmax) {
  83.                                 cb->blevel++ ;
  84.                                 cb->txmax = t->retries ;        /* update the max */
  85.                         }
  86.                         
  87.                         nr4sbuf(cb,seq) ;       /* Resend buffer */
  88.                 }
  89.          }
  90.         
  91. }
  92.  
  93. /* Connect/disconnect acknowledgement timeout */
  94.  
  95. void nr4cdtimeout(char *p)
  96. {
  97.         struct nr4cb *cb = (struct nr4cb *)p ;
  98.         struct nr4hdr hdr ;
  99.  
  100.         switch(cb->state) {
  101.           case NR4STCPEND:
  102.                 if (cb->cdtries == Nr4retries) {        /* Have we tried long enough? */
  103.                         cb->dreason = NR4RTIMEOUT ;
  104.                         nr4state(cb, NR4STDISC) ;               /* Give it up */
  105.                 } else {
  106.                         /* Set up header */
  107.                         
  108.                         hdr.opcode = NR4OPCONRQ ;
  109.                         hdr.u.conreq.myindex = cb->mynum ;
  110.                         hdr.u.conreq.myid = cb->myid ;
  111.                         hdr.u.conreq.window = Nr4window ;
  112.                         hdr.u.conreq.user = cb->luser ;
  113.                         hdr.u.conreq.node = mycall ;
  114.  
  115.                         /* Bump tries counter and backoff level, and restart timer */
  116.                         /* We use a binary exponential backoff. */
  117.                         
  118.                         cb->cdtries++ ;
  119.                         cb->blevel++ ;
  120.                         cb->tcd.start *= 2 ;
  121.                         start_timer(&cb->tcd) ;
  122.  
  123.                         /* Send connect request packet */
  124.  
  125.                         nr4sframe(&cb->node, &hdr, NULLBUF) ;
  126.                 }
  127.                 break ;
  128.                 
  129.           case NR4STDPEND:
  130.                 if (cb->cdtries == Nr4retries) {        /* Have we tried long enough? */
  131.                         cb->dreason = NR4RTIMEOUT ;
  132.                         nr4state(cb, NR4STDISC) ;               /* Give it up */
  133.                 } else {
  134.                         /* Format header */
  135.                         
  136.                         hdr.opcode = NR4OPDISRQ ;
  137.                         hdr.yourindex = cb->yournum ;
  138.                         hdr.yourid = cb->yourid ;
  139.  
  140.                         /* Bump retry count and start timer */
  141.                         /* We don't really need to be fancy here, since we */
  142.                         /* should have a good idea of the round trip time by now. */
  143.                         
  144.                         cb->cdtries++ ;
  145.                         start_timer(&cb->tcd) ;
  146.  
  147.                         /* Send disconnect request packet */
  148.  
  149.                         nr4sframe(&cb->node, &hdr, NULLBUF) ;
  150.                 }
  151.                 break ;
  152.         }
  153. }
  154.  
  155. /* The choke timer has expired.  Unchoke and kick. */
  156.  
  157. void nr4unchoke(char *p)
  158. {
  159.         struct nr4cb *cb = (struct nr4cb *)p ;
  160.  
  161.         cb->choked = 0 ;
  162.         nr4output(cb) ;
  163. }
  164.  
  165.