nr4timer.c
资源名称:export.zip [点击查看]
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:4k
源码类别:
TCP/IP协议栈
开发平台:
Visual C++
- /* net/rom level 4 (transport) protocol timer management.
- * Copyright 1989 by Daniel M. Frank, W9NK. Permission granted for
- * non-commercial distribution only.
- */
- #include <stdio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "ax25.h"
- #include "lapb.h"
- #include "netrom.h"
- #include "nr4.h"
- #include <ctype.h>
- #undef NR4DEBUG
- /* The ACK timer has expired without any data becoming available.
- * Go ahead and send an ACK.
- */
- void
- nr4ackit(p)
- void *p ;
- {
- struct nr4cb *cb = (struct nr4cb *)p ;
- struct nr4hdr rhdr ;
- #ifdef NR4DEBUG
- printf("ACKIT called.n") ;
- #endif
- if (cb->qfull) /* Are we choked? */
- rhdr.opcode = NR4OPACK | NR4CHOKE ;
- else
- rhdr.opcode = NR4OPACK ;
- rhdr.yourindex = cb->yournum ;
- rhdr.yourid = cb->yourid ;
- rhdr.u.ack.rxseq = cb->rxpected ;
- nr4sframe(cb->remote.node, &rhdr, NULL) ;
- }
- /* Called when one of the transmit timers has expired */
- void
- nr4txtimeout(p)
- void *p ;
- {
- struct nr4cb *cb = (struct nr4cb *)p ;
- unsigned seq ;
- struct nr4txbuf *t ;
- /* Sanity check */
- if (cb->state != NR4STCON)
- return ;
- /* Scan through the send window looking for expired timers */
- for (seq = cb->ackxpected ;
- nr4between(cb->ackxpected, seq, cb->nextosend) ;
- seq = (seq + 1) & NR4SEQMASK) {
- t = &cb->txbufs[seq % cb->window] ;
- if (t->tretry.state == TIMER_EXPIRE) {
- t->tretry.state = TIMER_STOP ; /* So we don't do it again */
- if (t->retries == Nr4retries) {
- cb->dreason = NR4RTIMEOUT ;
- nr4state(cb, NR4STDISC) ;
- }
- t->retries++ ;
- /* We keep track of the highest retry count in the window. */
- /* If packet times out and its new retry count exceeds the *
- /* max, we update the max and bump the backoff level. This */
- /* expedient is to avoid bumping the backoff level for every */
- /* expiration, since with more than one timer we would back */
- /* off way too fast (and at a rate dependent on the window */
- /* size! */
- if (t->retries > cb->txmax) {
- cb->blevel++ ;
- cb->txmax = t->retries ; /* update the max */
- }
- nr4sbuf(cb,seq) ; /* Resend buffer */
- }
- }
- }
- /* Connect/disconnect acknowledgement timeout */
- void
- nr4cdtimeout(p)
- void *p ;
- {
- struct nr4cb *cb = (struct nr4cb *)p ;
- struct nr4hdr hdr ;
- switch(cb->state) {
- case NR4STCPEND:
- if (cb->cdtries == Nr4retries) { /* Have we tried long enough? */
- cb->dreason = NR4RTIMEOUT ;
- nr4state(cb, NR4STDISC) ; /* Give it up */
- } else {
- /* Set up header */
- hdr.opcode = NR4OPCONRQ ;
- hdr.u.conreq.myindex = cb->mynum ;
- hdr.u.conreq.myid = cb->myid ;
- hdr.u.conreq.window = Nr4window ;
- memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
- memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
- /* Bump tries counter and backoff level, and restart timer */
- /* We use a binary exponential backoff. */
- cb->cdtries++ ;
- cb->blevel++ ;
- set_timer(&cb->tcd,dur_timer(&cb->tcd)*2);
- start_timer(&cb->tcd) ;
- /* Send connect request packet */
- nr4sframe(cb->remote.node,&hdr, NULL) ;
- }
- break ;
- case NR4STDPEND:
- if (cb->cdtries == Nr4retries) { /* Have we tried long enough? */
- cb->dreason = NR4RTIMEOUT ;
- nr4state(cb, NR4STDISC) ; /* Give it up */
- } else {
- /* Format header */
- hdr.opcode = NR4OPDISRQ ;
- hdr.yourindex = cb->yournum ;
- hdr.yourid = cb->yourid ;
- /* Bump retry count and start timer */
- /* We don't really need to be fancy here, since we */
- /* should have a good idea of the round trip time by now. */
- cb->cdtries++ ;
- start_timer(&cb->tcd) ;
- /* Send disconnect request packet */
- nr4sframe(cb->remote.node,&hdr, NULL) ;
- }
- break ;
- }
- }
- /* The choke timer has expired. Unchoke and kick. */
- void
- nr4unchoke(p)
- void *p ;
- {
- struct nr4cb *cb = (struct nr4cb *)p ;
- cb->choked = 0 ;
- nr4output(cb) ;
- }