1 /*
2  *	NET/ROM release 007
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  *	NET/ROM 001	Jonathan(G4KLX)	Cloned from ax25_timer.c
14  *	NET/ROM 007	Jonathan(G4KLX)	New timer architecture.
15  *					Implemented idle timer.
16  */
17 
18 #include <linux/errno.h>
19 #include <linux/types.h>
20 #include <linux/socket.h>
21 #include <linux/in.h>
22 #include <linux/kernel.h>
23 #include <linux/sched.h>
24 #include <linux/timer.h>
25 #include <linux/string.h>
26 #include <linux/sockios.h>
27 #include <linux/net.h>
28 #include <net/ax25.h>
29 #include <linux/inet.h>
30 #include <linux/netdevice.h>
31 #include <linux/skbuff.h>
32 #include <net/sock.h>
33 #include <asm/uaccess.h>
34 #include <asm/system.h>
35 #include <linux/fcntl.h>
36 #include <linux/mm.h>
37 #include <linux/interrupt.h>
38 #include <net/netrom.h>
39 
40 static void nr_heartbeat_expiry(unsigned long);
41 static void nr_t1timer_expiry(unsigned long);
42 static void nr_t2timer_expiry(unsigned long);
43 static void nr_t4timer_expiry(unsigned long);
44 static void nr_idletimer_expiry(unsigned long);
45 
nr_start_t1timer(struct sock * sk)46 void nr_start_t1timer(struct sock *sk)
47 {
48 	del_timer(&sk->protinfo.nr->t1timer);
49 
50 	sk->protinfo.nr->t1timer.data     = (unsigned long)sk;
51 	sk->protinfo.nr->t1timer.function = &nr_t1timer_expiry;
52 	sk->protinfo.nr->t1timer.expires  = jiffies + sk->protinfo.nr->t1;
53 
54 	add_timer(&sk->protinfo.nr->t1timer);
55 }
56 
nr_start_t2timer(struct sock * sk)57 void nr_start_t2timer(struct sock *sk)
58 {
59 	del_timer(&sk->protinfo.nr->t2timer);
60 
61 	sk->protinfo.nr->t2timer.data     = (unsigned long)sk;
62 	sk->protinfo.nr->t2timer.function = &nr_t2timer_expiry;
63 	sk->protinfo.nr->t2timer.expires  = jiffies + sk->protinfo.nr->t2;
64 
65 	add_timer(&sk->protinfo.nr->t2timer);
66 }
67 
nr_start_t4timer(struct sock * sk)68 void nr_start_t4timer(struct sock *sk)
69 {
70 	del_timer(&sk->protinfo.nr->t4timer);
71 
72 	sk->protinfo.nr->t4timer.data     = (unsigned long)sk;
73 	sk->protinfo.nr->t4timer.function = &nr_t4timer_expiry;
74 	sk->protinfo.nr->t4timer.expires  = jiffies + sk->protinfo.nr->t4;
75 
76 	add_timer(&sk->protinfo.nr->t4timer);
77 }
78 
nr_start_idletimer(struct sock * sk)79 void nr_start_idletimer(struct sock *sk)
80 {
81 	del_timer(&sk->protinfo.nr->idletimer);
82 
83 	if (sk->protinfo.nr->idle > 0) {
84 		sk->protinfo.nr->idletimer.data     = (unsigned long)sk;
85 		sk->protinfo.nr->idletimer.function = &nr_idletimer_expiry;
86 		sk->protinfo.nr->idletimer.expires  = jiffies + sk->protinfo.nr->idle;
87 
88 		add_timer(&sk->protinfo.nr->idletimer);
89 	}
90 }
91 
nr_start_heartbeat(struct sock * sk)92 void nr_start_heartbeat(struct sock *sk)
93 {
94 	del_timer(&sk->timer);
95 
96 	sk->timer.data     = (unsigned long)sk;
97 	sk->timer.function = &nr_heartbeat_expiry;
98 	sk->timer.expires  = jiffies + 5 * HZ;
99 
100 	add_timer(&sk->timer);
101 }
102 
nr_stop_t1timer(struct sock * sk)103 void nr_stop_t1timer(struct sock *sk)
104 {
105 	del_timer(&sk->protinfo.nr->t1timer);
106 }
107 
nr_stop_t2timer(struct sock * sk)108 void nr_stop_t2timer(struct sock *sk)
109 {
110 	del_timer(&sk->protinfo.nr->t2timer);
111 }
112 
nr_stop_t4timer(struct sock * sk)113 void nr_stop_t4timer(struct sock *sk)
114 {
115 	del_timer(&sk->protinfo.nr->t4timer);
116 }
117 
nr_stop_idletimer(struct sock * sk)118 void nr_stop_idletimer(struct sock *sk)
119 {
120 	del_timer(&sk->protinfo.nr->idletimer);
121 }
122 
nr_stop_heartbeat(struct sock * sk)123 void nr_stop_heartbeat(struct sock *sk)
124 {
125 	del_timer(&sk->timer);
126 }
127 
nr_t1timer_running(struct sock * sk)128 int nr_t1timer_running(struct sock *sk)
129 {
130 	return timer_pending(&sk->protinfo.nr->t1timer);
131 }
132 
nr_heartbeat_expiry(unsigned long param)133 static void nr_heartbeat_expiry(unsigned long param)
134 {
135 	struct sock *sk = (struct sock *)param;
136 
137 	switch (sk->protinfo.nr->state) {
138 
139 		case NR_STATE_0:
140 			/* Magic here: If we listen() and a new link dies before it
141 			   is accepted() it isn't 'dead' so doesn't get removed. */
142 			if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
143 				nr_destroy_socket(sk);
144 				return;
145 			}
146 			break;
147 
148 		case NR_STATE_3:
149 			/*
150 			 * Check for the state of the receive buffer.
151 			 */
152 			if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
153 			    (sk->protinfo.nr->condition & NR_COND_OWN_RX_BUSY)) {
154 				sk->protinfo.nr->condition &= ~NR_COND_OWN_RX_BUSY;
155 				sk->protinfo.nr->condition &= ~NR_COND_ACK_PENDING;
156 				sk->protinfo.nr->vl         = sk->protinfo.nr->vr;
157 				nr_write_internal(sk, NR_INFOACK);
158 				break;
159 			}
160 			break;
161 	}
162 
163 	nr_start_heartbeat(sk);
164 }
165 
nr_t2timer_expiry(unsigned long param)166 static void nr_t2timer_expiry(unsigned long param)
167 {
168 	struct sock *sk = (struct sock *)param;
169 
170 	if (sk->protinfo.nr->condition & NR_COND_ACK_PENDING) {
171 		sk->protinfo.nr->condition &= ~NR_COND_ACK_PENDING;
172 		nr_enquiry_response(sk);
173 	}
174 }
175 
nr_t4timer_expiry(unsigned long param)176 static void nr_t4timer_expiry(unsigned long param)
177 {
178 	struct sock *sk = (struct sock *)param;
179 
180 	sk->protinfo.nr->condition &= ~NR_COND_PEER_RX_BUSY;
181 }
182 
nr_idletimer_expiry(unsigned long param)183 static void nr_idletimer_expiry(unsigned long param)
184 {
185 	struct sock *sk = (struct sock *)param;
186 
187 	nr_clear_queues(sk);
188 
189 	sk->protinfo.nr->n2count = 0;
190 	nr_write_internal(sk, NR_DISCREQ);
191 	sk->protinfo.nr->state = NR_STATE_2;
192 
193 	nr_start_t1timer(sk);
194 	nr_stop_t2timer(sk);
195 	nr_stop_t4timer(sk);
196 
197 	sk->state     = TCP_CLOSE;
198 	sk->err       = 0;
199 	sk->shutdown |= SEND_SHUTDOWN;
200 
201 	if (!sk->dead)
202 		sk->state_change(sk);
203 
204 	sk->dead = 1;
205 }
206 
nr_t1timer_expiry(unsigned long param)207 static void nr_t1timer_expiry(unsigned long param)
208 {
209 	struct sock *sk = (struct sock *)param;
210 
211 	switch (sk->protinfo.nr->state) {
212 
213 		case NR_STATE_1:
214 			if (sk->protinfo.nr->n2count == sk->protinfo.nr->n2) {
215 				nr_disconnect(sk, ETIMEDOUT);
216 				return;
217 			} else {
218 				sk->protinfo.nr->n2count++;
219 				nr_write_internal(sk, NR_CONNREQ);
220 			}
221 			break;
222 
223 		case NR_STATE_2:
224 			if (sk->protinfo.nr->n2count == sk->protinfo.nr->n2) {
225 				nr_disconnect(sk, ETIMEDOUT);
226 				return;
227 			} else {
228 				sk->protinfo.nr->n2count++;
229 				nr_write_internal(sk, NR_DISCREQ);
230 			}
231 			break;
232 
233 		case NR_STATE_3:
234 			if (sk->protinfo.nr->n2count == sk->protinfo.nr->n2) {
235 				nr_disconnect(sk, ETIMEDOUT);
236 				return;
237 			} else {
238 				sk->protinfo.nr->n2count++;
239 				nr_requeue_frames(sk);
240 			}
241 			break;
242 	}
243 
244 	nr_start_t1timer(sk);
245 }
246