home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / network / src_1218.zip / LAPBTIME.C < prev    next >
C/C++ Source or Header  |  1991-07-14  |  3KB  |  110 lines

  1. /* LAPB (AX25) timer recovery routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "ax25.h"
  7. #include "timer.h"
  8. #include "lapb.h"
  9.  
  10. static void tx_enq __ARGS((struct ax25_cb *axp));
  11.  
  12. /* Called whenever timer T1 expires */
  13. void
  14. recover(p)
  15. void *p;
  16. {
  17.     register struct ax25_cb *axp = (struct ax25_cb *)p;
  18.  
  19.     axp->flags.retrans = 1;
  20.     axp->retries++;
  21.     if((1L << axp->retries) < Blimit)
  22.         /* Back off retransmit timer */
  23.         set_timer(&axp->t1,dur_timer(&axp->t1)*2);
  24.  
  25.     switch(axp->state){
  26.     case LAPB_SETUP:
  27.         if(axp->n2 != 0 && axp->retries > axp->n2){
  28.             free_q(&axp->txq);
  29.             axp->reason = LB_TIMEOUT;
  30.             lapbstate(axp,LAPB_DISCONNECTED);
  31.         } else {
  32.             sendctl(axp,LAPB_COMMAND,SABM|PF);
  33.             start_timer(&axp->t1);
  34.         }
  35.         break;
  36.     case LAPB_DISCPENDING:
  37.         if(axp->n2 != 0 && axp->retries > axp->n2){
  38.             axp->reason = LB_TIMEOUT;
  39.             lapbstate(axp,LAPB_DISCONNECTED);
  40.         } else {
  41.             sendctl(axp,LAPB_COMMAND,DISC|PF);
  42.             start_timer(&axp->t1);
  43.         }
  44.         break;
  45.     case LAPB_CONNECTED:
  46.     case LAPB_RECOVERY:
  47.         if(axp->n2 != 0 && axp->retries > axp->n2){
  48.             /* Give up */
  49.             sendctl(axp,LAPB_RESPONSE,DM|PF);
  50.             free_q(&axp->txq);
  51.             axp->reason = LB_TIMEOUT;
  52.             lapbstate(axp,LAPB_DISCONNECTED);
  53.         } else {
  54.             /* Transmit poll */
  55.             tx_enq(axp);
  56.             lapbstate(axp,LAPB_RECOVERY);
  57.         }
  58.         break;
  59.     }
  60. }
  61.  
  62.  
  63. /* Send a poll (S-frame command with the poll bit set) */
  64. void
  65. pollthem(p)
  66. void *p;
  67. {
  68.     register struct ax25_cb *axp;
  69.  
  70.     axp = (struct ax25_cb *)p;
  71.     if(axp->proto == V1)
  72.         return;    /* Not supported in the old protocol */
  73.     switch(axp->state){
  74.     case LAPB_CONNECTED:
  75.         axp->retries = 0;
  76.         tx_enq(axp);
  77.         lapbstate(axp,LAPB_RECOVERY);
  78.         break;
  79.     }
  80. }
  81. /* Transmit query */
  82. static void
  83. tx_enq(axp)
  84. register struct ax25_cb *axp;
  85. {
  86.     char ctl;
  87.     struct mbuf *bp;
  88.  
  89.     /* I believe that retransmitting the oldest unacked
  90.      * I-frame tends to give better performance than polling,
  91.      * as long as the frame isn't too "large", because
  92.      * chances are that the I frame got lost anyway.
  93.      * This is an option in LAPB, but not in the official AX.25.
  94.      */
  95.     if(axp->txq != NULLBUF
  96.      && (len_p(axp->txq) < axp->pthresh || axp->proto == V1)){
  97.         /* Retransmit oldest unacked I-frame */
  98.         dup_p(&bp,axp->txq,0,len_p(axp->txq));
  99.         ctl = PF | I | (((axp->vs - axp->unack) & MMASK) << 1)
  100.          | (axp->vr << 5);
  101.         sendframe(axp,LAPB_COMMAND,ctl,bp);
  102.     } else {
  103.         ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;    
  104.         sendctl(axp,LAPB_COMMAND,ctl);
  105.     }
  106.     axp->response = 0;    
  107.     stop_timer(&axp->t3);
  108.     start_timer(&axp->t1);
  109. }
  110.