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

  1. /* LAPB (AX.25) timer recovery routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  */
  6. #include "global.h"
  7. #ifdef AX25
  8. #include "mbuf.h"
  9. #include "ax25.h"
  10. #include "timer.h"
  11. #include "lapb.h"
  12. #ifdef NETROM
  13. #include "netrom.h"
  14. #endif
  15.   
  16. static void tx_enq __ARGS((struct ax25_cb *axp));
  17.   
  18. int lapbtimertype = 0;      /* default to binary exponential */
  19.   
  20. /* Called whenever timer T1 expires */
  21. void
  22. recover(p)
  23. void *p;
  24. {
  25.     struct ax25_cb *axp = (struct ax25_cb *)p;
  26.     long waittime = dur_timer(&axp->t1);
  27.   
  28.     axp->flags.retrans = 1;
  29.     axp->retries++;
  30.   
  31. #ifdef NETROM
  32.     {
  33.         struct nrnbr_tab *np;
  34.   
  35.     /* If this is a netrom neighbour, increment the retry count */
  36.         if((axp->iface->flags & IS_NR_IFACE) && ((np = find_nrnbr(axp->remote,axp->iface)) != NULL))
  37.             np->retries++;
  38.     }
  39. #endif
  40.   
  41.     switch(axp->iface->ax25->lapbtimertype){
  42.         case 2:          /* original backoff mode*/
  43.             waittime = axp->srt * 2;
  44.             break;
  45.         case 1:          /* linear backoff mode */
  46.             if((1L << axp->retries) < axp->iface->ax25->blimit)
  47.                 waittime = dur_timer(&axp->t1) + axp->srt;
  48.             break;
  49.         case 0:          /* exponential backoff mode */
  50.             if((1L << axp->retries) < axp->iface->ax25->blimit)
  51.                 waittime = dur_timer(&axp->t1) * 2;
  52.             break;
  53.     }
  54.     {
  55.         /* IF a maximum is set, and we surpass it, use the maximum */
  56.         long maxwait = axp->iface->ax25->maxwait;
  57.         if(maxwait && (waittime > maxwait))
  58.             waittime = maxwait;
  59.     }
  60.     set_timer(&axp->t1,waittime);
  61.   
  62.     switch(axp->state){
  63.         case LAPB_SETUP:
  64.             if(axp->n2 != 0 && axp->retries > axp->n2){
  65. #ifdef NETROM
  66.                 nr_derate(axp);
  67. #endif
  68.                 free_q(&axp->txq);
  69.                 axp->reason = LB_TIMEOUT;
  70.                 lapbstate(axp,LAPB_DISCONNECTED);
  71.             } else {
  72.                 sendctl(axp,LAPB_COMMAND,SABM|PF);
  73.                 start_timer(&axp->t1);
  74.             }
  75.             break;
  76.         case LAPB_DISCPENDING:
  77.             if(axp->n2 != 0 && axp->retries > axp->n2){
  78. #ifdef NETROM
  79.                 nr_derate(axp);
  80. #endif
  81.                 axp->reason = LB_TIMEOUT;
  82.                 lapbstate(axp,LAPB_DISCONNECTED);
  83.             } else {
  84.                 sendctl(axp,LAPB_COMMAND,DISC|PF);
  85.                 start_timer(&axp->t1);
  86.             }
  87.             break;
  88.         case LAPB_CONNECTED:
  89.         case LAPB_RECOVERY:
  90.             if(axp->n2 != 0 && axp->retries > axp->n2){
  91.             /* Give up */
  92. #ifdef NETROM
  93.                 nr_derate(axp);
  94. #endif
  95.                 sendctl(axp,LAPB_RESPONSE,DM|PF);
  96.                 free_q(&axp->txq);
  97.                 axp->reason = LB_TIMEOUT;
  98.                 lapbstate(axp,LAPB_DISCONNECTED);
  99.             } else {
  100.             /* Transmit poll */
  101.                 tx_enq(axp);
  102.                 lapbstate(axp,LAPB_RECOVERY);
  103.             }
  104.             break;
  105.     }
  106. }
  107.   
  108.   
  109. /* Send a poll (S-frame command with the poll bit set) */
  110. void
  111. pollthem(p)
  112. void *p;
  113. {
  114.     register struct ax25_cb *axp;
  115.   
  116.     axp = (struct ax25_cb *)p;
  117.     if(axp->proto == V1)
  118.         return; /* Not supported in the old protocol */
  119.     switch(axp->state){
  120.         case LAPB_CONNECTED:
  121.             axp->retries = 0;
  122.             tx_enq(axp);
  123.             lapbstate(axp,LAPB_RECOVERY);
  124.             break;
  125.     }
  126. }
  127.   
  128. /* Called whenever timer T4 (link rudundancy timer) expires */
  129. void
  130. redundant(p)
  131. void *p;
  132. {
  133.     register struct ax25_cb *axp;
  134.   
  135.     axp = (struct ax25_cb *)p;
  136.     switch(axp->state){
  137.         case LAPB_CONNECTED:
  138.         case LAPB_RECOVERY:
  139.             axp->retries = 0;
  140.             sendctl(axp,LAPB_COMMAND,DISC|PF);
  141.             start_timer(&axp->t1);
  142.             free_q(&axp->txq);
  143.             lapbstate(axp,LAPB_DISCPENDING);
  144.             break;
  145.     }
  146. }
  147.   
  148. /* Transmit query */
  149. static void
  150. tx_enq(axp)
  151. register struct ax25_cb *axp;
  152. {
  153.     char ctl;
  154.     struct mbuf *bp;
  155.   
  156.     /* I believe that retransmitting the oldest unacked
  157.      * I-frame tends to give better performance than polling,
  158.      * as long as the frame isn't too "large", because
  159.      * chances are that the I frame got lost anyway.
  160.      * This is an option in LAPB, but not in the official AX.25.
  161.      */
  162.     if(axp->txq != NULLBUF
  163.     && (len_p(axp->txq) < axp->pthresh || axp->proto == V1)){
  164.         /* Retransmit oldest unacked I-frame */
  165.         dup_p(&bp,axp->txq,0,len_p(axp->txq));
  166.         ctl = PF | I | (((axp->vs - axp->unack) & MMASK) << 1)
  167.         | (axp->vr << 5);
  168.         sendframe(axp,LAPB_COMMAND,ctl,bp);
  169.     } else {
  170.         ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;
  171.         sendctl(axp,LAPB_COMMAND,ctl);
  172.     }
  173.     axp->response = 0;
  174.     stop_timer(&axp->t3);
  175.     start_timer(&axp->t1);
  176. }
  177.   
  178. #endif /* AX25 */
  179.   
  180.