ax25_std_timer.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * AX.25 release 037
  3.  *
  4.  * This code REQUIRES 2.1.15 or higher/ NET3.038
  5.  *
  6.  * This module:
  7.  * This module is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License
  9.  * as published by the Free Software Foundation; either version
  10.  * 2 of the License, or (at your option) any later version.
  11.  *
  12.  * History
  13.  * AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
  14.  * AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from the
  15.  * sock structure.
  16.  * AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
  17.  * AX.25 031 Joerg(DL1BKE) Added DAMA support
  18.  * AX.25 032 Joerg(DL1BKE) Fixed DAMA timeout bug
  19.  * AX.25 033 Jonathan(G4KLX) Modularisation functions.
  20.  * AX.25 035 Frederic(F1OAT) Support for pseudo-digipeating.
  21.  * AX.25 036 Jonathan(G4KLX) Split from ax25_timer.c.
  22.  * AX.25 037 Jonathan(G4KLX) New timer architecture.
  23.  */
  24. #include <linux/errno.h>
  25. #include <linux/types.h>
  26. #include <linux/socket.h>
  27. #include <linux/in.h>
  28. #include <linux/kernel.h>
  29. #include <linux/sched.h>
  30. #include <linux/timer.h>
  31. #include <linux/string.h>
  32. #include <linux/sockios.h>
  33. #include <linux/net.h>
  34. #include <net/ax25.h>
  35. #include <linux/inet.h>
  36. #include <linux/netdevice.h>
  37. #include <linux/skbuff.h>
  38. #include <net/sock.h>
  39. #include <asm/uaccess.h>
  40. #include <asm/system.h>
  41. #include <linux/fcntl.h>
  42. #include <linux/mm.h>
  43. #include <linux/interrupt.h>
  44. void ax25_std_heartbeat_expiry(ax25_cb *ax25)
  45. {
  46. switch (ax25->state) {
  47. case AX25_STATE_0:
  48. /* Magic here: If we listen() and a new link dies before it
  49.    is accepted() it isn't 'dead' so doesn't get removed. */
  50. if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
  51. ax25_destroy_socket(ax25);
  52. return;
  53. }
  54. break;
  55. case AX25_STATE_3:
  56. case AX25_STATE_4:
  57. /*
  58.  * Check the state of the receive buffer.
  59.  */
  60. if (ax25->sk != NULL) {
  61. if (atomic_read(&ax25->sk->rmem_alloc) < (ax25->sk->rcvbuf / 2) &&
  62.     (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
  63. ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
  64. ax25->condition &= ~AX25_COND_ACK_PENDING;
  65. ax25_send_control(ax25, AX25_RR, AX25_POLLOFF, AX25_RESPONSE);
  66. break;
  67. }
  68. }
  69. }
  70. ax25_start_heartbeat(ax25);
  71. }
  72. void ax25_std_t2timer_expiry(ax25_cb *ax25)
  73. {
  74. if (ax25->condition & AX25_COND_ACK_PENDING) {
  75. ax25->condition &= ~AX25_COND_ACK_PENDING;
  76. ax25_std_timeout_response(ax25);
  77. }
  78. }
  79. void ax25_std_t3timer_expiry(ax25_cb *ax25)
  80. {
  81. ax25->n2count = 0;
  82. ax25_std_transmit_enquiry(ax25);
  83. ax25->state   = AX25_STATE_4;
  84. }
  85. void ax25_std_idletimer_expiry(ax25_cb *ax25)
  86. {
  87. ax25_clear_queues(ax25);
  88. ax25->n2count = 0;
  89. ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  90. ax25->state   = AX25_STATE_2;
  91. ax25_calculate_t1(ax25);
  92. ax25_start_t1timer(ax25);
  93. ax25_stop_t2timer(ax25);
  94. ax25_stop_t3timer(ax25);
  95. if (ax25->sk != NULL) {
  96. ax25->sk->state     = TCP_CLOSE;
  97. ax25->sk->err       = 0;
  98. ax25->sk->shutdown |= SEND_SHUTDOWN;
  99. if (!ax25->sk->dead)
  100. ax25->sk->state_change(ax25->sk);
  101. ax25->sk->dead      = 1;
  102. }
  103. }
  104. void ax25_std_t1timer_expiry(ax25_cb *ax25)
  105. {
  106. switch (ax25->state) {
  107. case AX25_STATE_1: 
  108. if (ax25->n2count == ax25->n2) {
  109. if (ax25->modulus == AX25_MODULUS) {
  110. ax25_disconnect(ax25, ETIMEDOUT);
  111. return;
  112. } else {
  113. ax25->modulus = AX25_MODULUS;
  114. ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
  115. ax25->n2count = 0;
  116. ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
  117. }
  118. } else {
  119. ax25->n2count++;
  120. if (ax25->modulus == AX25_MODULUS)
  121. ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
  122. else
  123. ax25_send_control(ax25, AX25_SABME, AX25_POLLON, AX25_COMMAND);
  124. }
  125. break;
  126. case AX25_STATE_2:
  127. if (ax25->n2count == ax25->n2) {
  128. ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  129. ax25_disconnect(ax25, ETIMEDOUT);
  130. return;
  131. } else {
  132. ax25->n2count++;
  133. ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  134. }
  135. break;
  136. case AX25_STATE_3: 
  137. ax25->n2count = 1;
  138. ax25_std_transmit_enquiry(ax25);
  139. ax25->state   = AX25_STATE_4;
  140. break;
  141. case AX25_STATE_4:
  142. if (ax25->n2count == ax25->n2) {
  143. ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
  144. ax25_disconnect(ax25, ETIMEDOUT);
  145. return;
  146. } else {
  147. ax25->n2count++;
  148. ax25_std_transmit_enquiry(ax25);
  149. }
  150. break;
  151. }
  152. ax25_calculate_t1(ax25);
  153. ax25_start_t1timer(ax25);
  154. }