Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ax25_std_timer.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * Copyright (C) Alan Cox GW4PTS ([email protected])
8  * Copyright (C) Jonathan Naylor G4KLX ([email protected])
9  * Copyright (C) Joerg Reuter DL1BKE ([email protected])
10  * Copyright (C) Frederic Rible F1OAT ([email protected])
11  */
12 #include <linux/errno.h>
13 #include <linux/types.h>
14 #include <linux/socket.h>
15 #include <linux/in.h>
16 #include <linux/kernel.h>
17 #include <linux/timer.h>
18 #include <linux/string.h>
19 #include <linux/sockios.h>
20 #include <linux/net.h>
21 #include <net/ax25.h>
22 #include <linux/inet.h>
23 #include <linux/netdevice.h>
24 #include <linux/skbuff.h>
25 #include <net/sock.h>
26 #include <net/tcp_states.h>
27 #include <asm/uaccess.h>
28 #include <linux/fcntl.h>
29 #include <linux/mm.h>
30 #include <linux/interrupt.h>
31 
33 {
34  struct sock *sk = ax25->sk;
35 
36  if (sk)
37  bh_lock_sock(sk);
38 
39  switch (ax25->state) {
40  case AX25_STATE_0:
41  /* Magic here: If we listen() and a new link dies before it
42  is accepted() it isn't 'dead' so doesn't get removed. */
43  if (!sk || sock_flag(sk, SOCK_DESTROY) ||
44  (sk->sk_state == TCP_LISTEN &&
45  sock_flag(sk, SOCK_DEAD))) {
46  if (sk) {
47  sock_hold(sk);
48  ax25_destroy_socket(ax25);
49  bh_unlock_sock(sk);
50  sock_put(sk);
51  } else
52  ax25_destroy_socket(ax25);
53  return;
54  }
55  break;
56 
57  case AX25_STATE_3:
58  case AX25_STATE_4:
59  /*
60  * Check the state of the receive buffer.
61  */
62  if (sk != NULL) {
63  if (atomic_read(&sk->sk_rmem_alloc) <
64  (sk->sk_rcvbuf >> 1) &&
65  (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
69  break;
70  }
71  }
72  }
73 
74  if (sk)
75  bh_unlock_sock(sk);
76 
78 }
79 
81 {
82  if (ax25->condition & AX25_COND_ACK_PENDING) {
85  }
86 }
87 
89 {
90  ax25->n2count = 0;
92  ax25->state = AX25_STATE_4;
93 }
94 
96 {
97  ax25_clear_queues(ax25);
98 
99  ax25->n2count = 0;
101  ax25->state = AX25_STATE_2;
102 
103  ax25_calculate_t1(ax25);
104  ax25_start_t1timer(ax25);
105  ax25_stop_t2timer(ax25);
106  ax25_stop_t3timer(ax25);
107 
108  if (ax25->sk != NULL) {
109  bh_lock_sock(ax25->sk);
110  ax25->sk->sk_state = TCP_CLOSE;
111  ax25->sk->sk_err = 0;
112  ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
113  if (!sock_flag(ax25->sk, SOCK_DEAD)) {
114  ax25->sk->sk_state_change(ax25->sk);
115  sock_set_flag(ax25->sk, SOCK_DEAD);
116  }
117  bh_unlock_sock(ax25->sk);
118  }
119 }
120 
122 {
123  switch (ax25->state) {
124  case AX25_STATE_1:
125  if (ax25->n2count == ax25->n2) {
126  if (ax25->modulus == AX25_MODULUS) {
127  ax25_disconnect(ax25, ETIMEDOUT);
128  return;
129  } else {
130  ax25->modulus = AX25_MODULUS;
131  ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
132  ax25->n2count = 0;
134  }
135  } else {
136  ax25->n2count++;
137  if (ax25->modulus == AX25_MODULUS)
139  else
141  }
142  break;
143 
144  case AX25_STATE_2:
145  if (ax25->n2count == ax25->n2) {
147  ax25_disconnect(ax25, ETIMEDOUT);
148  return;
149  } else {
150  ax25->n2count++;
152  }
153  break;
154 
155  case AX25_STATE_3:
156  ax25->n2count = 1;
158  ax25->state = AX25_STATE_4;
159  break;
160 
161  case AX25_STATE_4:
162  if (ax25->n2count == ax25->n2) {
164  ax25_disconnect(ax25, ETIMEDOUT);
165  return;
166  } else {
167  ax25->n2count++;
169  }
170  break;
171  }
172 
173  ax25_calculate_t1(ax25);
174  ax25_start_t1timer(ax25);
175 }