home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / h / if / NetMisc / c / LAPBTIME < prev    next >
Encoding:
Text File  |  1994-06-24  |  4.7 KB  |  154 lines

  1. #include <time.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "ax25.h"
  5. #include "timer.h"
  6. #include "lapb.h"
  7.  
  8. /* Called whenever timer T1 expires */
  9. void recover(int *n)
  10. {
  11.         register struct ax25_cb *axp;
  12.  
  13.         axp = (struct ax25_cb *)n;
  14.  
  15.         switch(axp->state){
  16.         case SETUP:
  17.                 if(axp->n2 != 0 && axp->retries == axp->n2){
  18.                         free_q(&axp->txq);
  19.                         lapbstate(axp,DISCONNECTED);
  20.                 } else {
  21.                         axp->retries++;
  22.                         sendctl(axp,COMMAND,SABM|PF);
  23.                         start_timer(&axp->t1);
  24.                 }
  25.                 break;
  26.         case DISCPENDING:
  27.                 if(axp->n2 != 0 && axp->retries == axp->n2){
  28.                         lapbstate(axp,DISCONNECTED);
  29.                 } else {
  30.                         axp->retries++;
  31.                         sendctl(axp,COMMAND,DISC|PF);
  32.                         start_timer(&axp->t1);
  33.                 }
  34.                 break;
  35.         case CONNECTED:
  36.                 axp->retries = 0;
  37.         case RECOVERY:  /* note fall-thru */
  38.                 if(axp->n2 != 0 && axp->retries == axp->n2){
  39.                         /* Give up */
  40.                         sendctl(axp,RESPONSE,DM|PF);
  41.                         free_q(&axp->txq);
  42.                         lapbstate(axp,DISCONNECTED);
  43.                 } else {
  44.                         /* Transmit poll */
  45.                         tx_enq(axp);
  46.                         axp->retries++;
  47.                         lapbstate(axp,RECOVERY);
  48.                 }
  49.                 break;
  50.         case FRAMEREJECT:
  51.                 if(axp->n2 != 0 && axp->retries == axp->n2){
  52.                         sendctl(axp,RESPONSE,DM|PF);
  53.                         free_q(&axp->txq);
  54.                         lapbstate(axp,DISCONNECTED);
  55.                 } else {
  56.                         frmr(axp,0,0);  /* Retransmit last FRMR */
  57.                         start_timer(&axp->t1);
  58.                         axp->retries++;
  59.                 }
  60.                 break;
  61.         }
  62.         /* Empty the trash */
  63.         if(axp->state == DISCONNECTED)
  64.                 del_ax25(axp);
  65. }
  66.  
  67. /* T2 has expired, we can't delay an acknowledgement any further */
  68. void send_ack(int *n)
  69. {
  70.         char control;
  71.         register struct ax25_cb *axp;
  72.  
  73.         axp = (struct ax25_cb *)n;
  74.         switch(axp->state){
  75.         case CONNECTED:
  76.         case RECOVERY:
  77.                 control = len_mbuf(axp->rxq) > axp->window ? RNR : RR;
  78.                 sendctl(axp,RESPONSE,control);
  79.                 axp->response = 0;
  80.                 break;
  81.         }
  82. }
  83.  
  84. /* called when Timer T3 has expired */
  85. /* Send a poll (S-frame command with the poll bit set) */
  86. void pollthem(int *n)
  87. {
  88.         register struct ax25_cb *axp;
  89.  
  90.         axp = (struct ax25_cb *)n;
  91.         if(axp->proto == V1)
  92.                 return; /* Not supported in the old protocol */
  93.         switch(axp->state){
  94.         case CONNECTED:
  95.                 axp->retries = 0;
  96.                 tx_enq(axp);
  97.                 lapbstate(axp,RECOVERY);
  98.                 break;
  99.         }
  100. }
  101.  
  102. /* Called whenever timer T4 (link rudundancy timer) expires */
  103. void redundant(int *n)
  104. {
  105.         register struct ax25_cb *axp;
  106.  
  107.         axp = (struct ax25_cb *)n;
  108.  
  109.         switch(axp->state){
  110.         case CONNECTED:
  111.         case RECOVERY:
  112.                 axp->retries = 0;
  113.                 sendctl(axp,COMMAND,DISC|PF);
  114.                 start_timer(&axp->t1);
  115.                 free_q(&axp->txq);
  116.                 lapbstate(axp,DISCPENDING);
  117.                 break;
  118.         }
  119.         /* Empty the trash */
  120.         if(axp->state == DISCONNECTED)
  121.                 del_ax25(axp);
  122. }
  123.  
  124.  
  125. /* Transmit query */
  126. void tx_enq(register struct ax25_cb *axp)
  127. {
  128.         char ctl;
  129.         struct mbuf *bp;
  130.  
  131.         /* I believe that retransmitting the oldest unacked
  132.          * I-frame tends to give better performance than polling,
  133.          * as long as the frame isn't too "large", because
  134.          * chances are that the I frame got lost anyway.
  135.          * This is an option in LAPB, but not in the official AX.25.
  136.          */
  137.         if(axp->txq != NULLBUF && len_mbuf(axp->txq) < axp->pthresh
  138.          && (axp->proto == V1 || !axp->remotebusy)){
  139.                 /* Retransmit oldest unacked I-frame */
  140.                 dup_p(&bp,axp->txq,0,len_mbuf(axp->txq));
  141.                 ctl = PF | I | ((axp->vs - axp->unack) & MMASK) << 1
  142.                  | axp->vr << 5;
  143.                 sendframe(axp,COMMAND,ctl,bp);
  144.                 start_timer(&axp->t4);
  145.         } else {
  146.                 ctl = len_mbuf(axp->rxq) >= axp->window ? RNR|PF : RR|PF;       
  147.                 sendctl(axp,COMMAND,ctl);
  148.         }
  149.         axp->response = 0;      
  150.         stop_timer(&axp->t3);
  151.         start_timer(&axp->t1);
  152. }
  153.  
  154.