ax25_ds_timer.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

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 036 Jonathan(G4KLX) Cloned from ax25_timer.c.
  14.  * Joerg(DL1BKE) Added DAMA Slave Timeout timer
  15.  * AX.25 037 Jonathan(G4KLX) New timer architecture.
  16.  */
  17. #include <linux/errno.h>
  18. #include <linux/types.h>
  19. #include <linux/socket.h>
  20. #include <linux/in.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/timer.h>
  24. #include <linux/string.h>
  25. #include <linux/sockios.h>
  26. #include <linux/net.h>
  27. #include <net/ax25.h>
  28. #include <linux/inet.h>
  29. #include <linux/netdevice.h>
  30. #include <linux/skbuff.h>
  31. #include <net/sock.h>
  32. #include <asm/uaccess.h>
  33. #include <asm/system.h>
  34. #include <linux/fcntl.h>
  35. #include <linux/mm.h>
  36. #include <linux/interrupt.h>
  37. static void ax25_ds_timeout(unsigned long);
  38. /*
  39.  * Add DAMA slave timeout timer to timer list.
  40.  * Unlike the connection based timers the timeout function gets 
  41.  * triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT
  42.  * (aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in
  43.  * 1/10th of a second.
  44.  */
  45. static void ax25_ds_add_timer(ax25_dev *ax25_dev)
  46. {
  47. struct timer_list *t = &ax25_dev->dama.slave_timer;
  48. t->data = (unsigned long) ax25_dev;
  49. t->function = &ax25_ds_timeout;
  50. t->expires = jiffies + HZ;
  51. add_timer(t);
  52. }
  53. void ax25_ds_del_timer(ax25_dev *ax25_dev)
  54. {
  55. if (ax25_dev) del_timer(&ax25_dev->dama.slave_timer);
  56. }
  57. void ax25_ds_set_timer(ax25_dev *ax25_dev)
  58. {
  59. if (ax25_dev == NULL) /* paranoia */
  60. return;
  61. del_timer(&ax25_dev->dama.slave_timer);
  62. ax25_dev->dama.slave_timeout = ax25_dev->values[AX25_VALUES_DS_TIMEOUT] / 10;
  63. ax25_ds_add_timer(ax25_dev);
  64. }
  65. /*
  66.  * DAMA Slave Timeout
  67.  * Silently discard all (slave) connections in case our master forgot us...
  68.  */
  69. static void ax25_ds_timeout(unsigned long arg)
  70. {
  71. ax25_dev *ax25_dev = (struct ax25_dev *) arg;
  72. ax25_cb *ax25;
  73. if (ax25_dev == NULL || !ax25_dev->dama.slave)
  74. return; /* Yikes! */
  75. if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) {
  76. ax25_ds_set_timer(ax25_dev);
  77. return;
  78. }
  79. for (ax25=ax25_list; ax25 != NULL; ax25 = ax25->next) {
  80. if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
  81. continue;
  82. ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  83. ax25_disconnect(ax25, ETIMEDOUT);
  84. }
  85. ax25_dev_dama_off(ax25_dev);
  86. }
  87. void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
  88. {
  89. switch (ax25->state) {
  90. case AX25_STATE_0:
  91. /* Magic here: If we listen() and a new link dies before it
  92.    is accepted() it isn't 'dead' so doesn't get removed. */
  93. if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
  94. ax25_destroy_socket(ax25);
  95. return;
  96. }
  97. break;
  98. case AX25_STATE_3:
  99. /*
  100.  * Check the state of the receive buffer.
  101.  */
  102. if (ax25->sk != NULL) {
  103. if (atomic_read(&ax25->sk->rmem_alloc) < (ax25->sk->rcvbuf / 2) && 
  104.     (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
  105. ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
  106. ax25->condition &= ~AX25_COND_ACK_PENDING;
  107. break;
  108. }
  109. }
  110. break;
  111. }
  112. ax25_start_heartbeat(ax25);
  113. }
  114. /* dl1bke 960114: T3 works much like the IDLE timeout, but
  115.  *                gets reloaded with every frame for this
  116.  *   connection.
  117.  */
  118. void ax25_ds_t3timer_expiry(ax25_cb *ax25)
  119. {
  120. ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  121. ax25_dama_off(ax25);
  122. ax25_disconnect(ax25, ETIMEDOUT);
  123. }
  124. /* dl1bke 960228: close the connection when IDLE expires.
  125.  *   unlike T3 this timer gets reloaded only on
  126.  *   I frames.
  127.  */
  128. void ax25_ds_idletimer_expiry(ax25_cb *ax25)
  129. {
  130. ax25_clear_queues(ax25);
  131. ax25->n2count = 0;
  132. ax25->state = AX25_STATE_2;
  133. ax25_calculate_t1(ax25);
  134. ax25_start_t1timer(ax25);
  135. ax25_stop_t3timer(ax25);
  136. if (ax25->sk != NULL) {
  137. ax25->sk->state     = TCP_CLOSE;
  138. ax25->sk->err       = 0;
  139. ax25->sk->shutdown |= SEND_SHUTDOWN;
  140. if (!ax25->sk->dead)
  141. ax25->sk->state_change(ax25->sk);
  142. ax25->sk->dead      = 1;
  143. }
  144. }
  145. /* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
  146.  *                within the poll of any connected channel. Remember 
  147.  *                that we are not allowed to send anything unless we
  148.  *                get polled by the Master.
  149.  *
  150.  *                Thus we'll have to do parts of our T1 handling in
  151.  *                ax25_enquiry_response().
  152.  */
  153. void ax25_ds_t1_timeout(ax25_cb *ax25)
  154. {
  155. switch (ax25->state) {
  156. case AX25_STATE_1: 
  157. if (ax25->n2count == ax25->n2) {
  158. if (ax25->modulus == AX25_MODULUS) {
  159. ax25_disconnect(ax25, ETIMEDOUT);
  160. return;
  161. } else {
  162. ax25->modulus = AX25_MODULUS;
  163. ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
  164. ax25->n2count = 0;
  165. ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
  166. }
  167. } else {
  168. ax25->n2count++;
  169. if (ax25->modulus == AX25_MODULUS)
  170. ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
  171. else
  172. ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
  173. }
  174. break;
  175. case AX25_STATE_2:
  176. if (ax25->n2count == ax25->n2) {
  177. ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  178. ax25_disconnect(ax25, ETIMEDOUT);
  179. return;
  180. } else {
  181. ax25->n2count++;
  182. }
  183. break;
  184. case AX25_STATE_3:
  185. if (ax25->n2count == ax25->n2) {
  186. ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
  187. ax25_disconnect(ax25, ETIMEDOUT);
  188. return;
  189. } else {
  190. ax25->n2count++;
  191. }
  192. break;
  193. }
  194. ax25_calculate_t1(ax25);
  195. ax25_start_t1timer(ax25);
  196. }