nr4timer.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:4k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "timer.h"
  9. #include "ax25.h"
  10. #include "lapb.h"
  11. #include "netrom.h"
  12. #include "nr4.h"
  13. #include <ctype.h>
  14. #undef NR4DEBUG
  15. /* The ACK timer has expired without any data becoming available.
  16.  * Go ahead and send an ACK.
  17.  */
  18. void
  19. nr4ackit(p)
  20. void *p ;
  21. {
  22. struct nr4cb *cb  = (struct nr4cb *)p ;
  23. struct nr4hdr rhdr ;
  24. #ifdef NR4DEBUG
  25. printf("ACKIT called.n") ;
  26. #endif
  27. if (cb->qfull) /* Are we choked? */
  28. rhdr.opcode = NR4OPACK | NR4CHOKE ;
  29. else
  30. rhdr.opcode = NR4OPACK ;
  31. rhdr.yourindex = cb->yournum ;
  32. rhdr.yourid = cb->yourid ;
  33. rhdr.u.ack.rxseq = cb->rxpected ;
  34. nr4sframe(cb->remote.node, &rhdr, NULL) ;
  35. }
  36. /* Called when one of the transmit timers has expired */
  37. void
  38. nr4txtimeout(p)
  39. void *p ;
  40. {
  41. struct nr4cb *cb = (struct nr4cb *)p ;
  42. unsigned seq ;
  43. struct nr4txbuf *t ;
  44. /* Sanity check */
  45. if (cb->state != NR4STCON)
  46. return ;
  47. /* Scan through the send window looking for expired timers */
  48. for (seq = cb->ackxpected ;
  49.  nr4between(cb->ackxpected, seq, cb->nextosend) ;
  50.  seq = (seq + 1) & NR4SEQMASK) {
  51. t = &cb->txbufs[seq % cb->window] ;
  52. if (t->tretry.state == TIMER_EXPIRE) {
  53. t->tretry.state = TIMER_STOP ; /* So we don't do it again */
  54. if (t->retries == Nr4retries) {
  55. cb->dreason = NR4RTIMEOUT ;
  56. nr4state(cb, NR4STDISC) ;
  57. }
  58. t->retries++ ;
  59. /* We keep track of the highest retry count in the window. */
  60. /* If packet times out and its new retry count exceeds the *
  61. /* max, we update the max and bump the backoff level.  This */
  62. /* expedient is to avoid bumping the backoff level for every */
  63. /* expiration, since with more than one timer we would back */
  64. /* off way too fast (and at a rate dependent on the window */
  65. /* size! */
  66. if (t->retries > cb->txmax) {
  67. cb->blevel++ ;
  68. cb->txmax = t->retries ; /* update the max */
  69. }
  70. nr4sbuf(cb,seq) ; /* Resend buffer */
  71. }
  72.  }
  73. }
  74. /* Connect/disconnect acknowledgement timeout */
  75. void
  76. nr4cdtimeout(p)
  77. void *p ;
  78. {
  79. struct nr4cb *cb = (struct nr4cb *)p ;
  80. struct nr4hdr hdr ;
  81. switch(cb->state) {
  82.   case NR4STCPEND:
  83.    if (cb->cdtries == Nr4retries) { /* Have we tried long enough? */
  84. cb->dreason = NR4RTIMEOUT ;
  85. nr4state(cb, NR4STDISC) ; /* Give it up */
  86. } else {
  87. /* Set up header */
  88. hdr.opcode = NR4OPCONRQ ;
  89. hdr.u.conreq.myindex = cb->mynum ;
  90. hdr.u.conreq.myid = cb->myid ;
  91. hdr.u.conreq.window = Nr4window ;
  92. memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
  93. memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
  94. /* Bump tries counter and backoff level, and restart timer */
  95. /* We use a binary exponential backoff. */
  96. cb->cdtries++ ;
  97. cb->blevel++ ;
  98. set_timer(&cb->tcd,dur_timer(&cb->tcd)*2);
  99. start_timer(&cb->tcd) ;
  100. /* Send connect request packet */
  101. nr4sframe(cb->remote.node,&hdr, NULL) ;
  102. }
  103. break ;
  104.   case NR4STDPEND:
  105.    if (cb->cdtries == Nr4retries) { /* Have we tried long enough? */
  106. cb->dreason = NR4RTIMEOUT ;
  107. nr4state(cb, NR4STDISC) ; /* Give it up */
  108. } else {
  109. /* Format header */
  110. hdr.opcode = NR4OPDISRQ ;
  111. hdr.yourindex = cb->yournum ;
  112. hdr.yourid = cb->yourid ;
  113. /* Bump retry count and start timer */
  114. /* We don't really need to be fancy here, since we */
  115. /* should have a good idea of the round trip time by now. */
  116. cb->cdtries++ ;
  117. start_timer(&cb->tcd) ;
  118. /* Send disconnect request packet */
  119. nr4sframe(cb->remote.node,&hdr, NULL) ;
  120. }
  121. break ;
  122. }
  123. }
  124. /* The choke timer has expired.  Unchoke and kick. */
  125. void
  126. nr4unchoke(p)
  127. void *p ;
  128. {
  129. struct nr4cb *cb = (struct nr4cb *)p ;
  130. cb->choked = 0 ;
  131. nr4output(cb) ;
  132. }