home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 3
/
hamradioversion3.0examsandprograms1992.iso
/
misc
/
9q920411
/
lapbtime.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-13
|
3KB
|
110 lines
/* LAPB (AX25) timer recovery routines
* Copyright 1991 Phil Karn, KA9Q
*/
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "lapb.h"
static void tx_enq __ARGS((struct ax25_cb *axp));
/* Called whenever timer T1 expires */
void
recover(p)
void *p;
{
register struct ax25_cb *axp = (struct ax25_cb *)p;
axp->flags.retrans = 1;
axp->retries++;
if((1L << axp->retries) < Blimit)
/* Back off retransmit timer */
set_timer(&axp->t1,dur_timer(&axp->t1)*2);
switch(axp->state){
case LAPB_SETUP:
if(axp->n2 != 0 && axp->retries > axp->n2){
free_q(&axp->txq);
axp->reason = LB_TIMEOUT;
lapbstate(axp,LAPB_DISCONNECTED);
} else {
sendctl(axp,LAPB_COMMAND,SABM|PF);
start_timer(&axp->t1);
}
break;
case LAPB_DISCPENDING:
if(axp->n2 != 0 && axp->retries > axp->n2){
axp->reason = LB_TIMEOUT;
lapbstate(axp,LAPB_DISCONNECTED);
} else {
sendctl(axp,LAPB_COMMAND,DISC|PF);
start_timer(&axp->t1);
}
break;
case LAPB_CONNECTED:
case LAPB_RECOVERY:
if(axp->n2 != 0 && axp->retries > axp->n2){
/* Give up */
sendctl(axp,LAPB_RESPONSE,DM|PF);
free_q(&axp->txq);
axp->reason = LB_TIMEOUT;
lapbstate(axp,LAPB_DISCONNECTED);
} else {
/* Transmit poll */
tx_enq(axp);
lapbstate(axp,LAPB_RECOVERY);
}
break;
}
}
/* Send a poll (S-frame command with the poll bit set) */
void
pollthem(p)
void *p;
{
register struct ax25_cb *axp;
axp = (struct ax25_cb *)p;
if(axp->proto == V1)
return; /* Not supported in the old protocol */
switch(axp->state){
case LAPB_CONNECTED:
axp->retries = 0;
tx_enq(axp);
lapbstate(axp,LAPB_RECOVERY);
break;
}
}
/* Transmit query */
static void
tx_enq(axp)
register struct ax25_cb *axp;
{
char ctl;
struct mbuf *bp;
/* I believe that retransmitting the oldest unacked
* I-frame tends to give better performance than polling,
* as long as the frame isn't too "large", because
* chances are that the I frame got lost anyway.
* This is an option in LAPB, but not in the official AX.25.
*/
if(axp->txq != NULLBUF
&& (len_p(axp->txq) < axp->pthresh || axp->proto == V1)){
/* Retransmit oldest unacked I-frame */
dup_p(&bp,axp->txq,0,len_p(axp->txq));
ctl = PF | I | (((axp->vs - axp->unack) & MMASK) << 1)
| (axp->vr << 5);
sendframe(axp,LAPB_COMMAND,ctl,bp);
} else {
ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;
sendctl(axp,LAPB_COMMAND,ctl);
}
axp->response = 0;
stop_timer(&axp->t3);
start_timer(&axp->t1);
}