xref: /linux/net/ax25/ax25_ds_in.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
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) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
8  * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
9  */
10 #include <linux/errno.h>
11 #include <linux/types.h>
12 #include <linux/socket.h>
13 #include <linux/in.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/timer.h>
17 #include <linux/string.h>
18 #include <linux/sockios.h>
19 #include <linux/net.h>
20 #include <net/ax25.h>
21 #include <linux/inet.h>
22 #include <linux/netdevice.h>
23 #include <linux/skbuff.h>
24 #include <net/sock.h>
25 #include <net/tcp_states.h>
26 #include <asm/uaccess.h>
27 #include <asm/system.h>
28 #include <linux/fcntl.h>
29 #include <linux/mm.h>
30 #include <linux/interrupt.h>
31 
32 /*
33  *	State machine for state 1, Awaiting Connection State.
34  *	The handling of the timer(s) is in file ax25_ds_timer.c.
35  *	Handling of state 0 and connection release is in ax25.c.
36  */
37 static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
38 {
39 	switch (frametype) {
40 	case AX25_SABM:
41 		ax25->modulus = AX25_MODULUS;
42 		ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
43 		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
44 		break;
45 
46 	case AX25_SABME:
47 		ax25->modulus = AX25_EMODULUS;
48 		ax25->window  =  ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
49 		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
50 		break;
51 
52 	case AX25_DISC:
53 		ax25_send_control(ax25, AX25_DM, pf, AX25_RESPONSE);
54 		break;
55 
56 	case AX25_UA:
57 		ax25_calculate_rtt(ax25);
58 		ax25_stop_t1timer(ax25);
59 		ax25_start_t3timer(ax25);
60 		ax25_start_idletimer(ax25);
61 		ax25->vs      = 0;
62 		ax25->va      = 0;
63 		ax25->vr      = 0;
64 		ax25->state   = AX25_STATE_3;
65 		ax25->n2count = 0;
66 		if (ax25->sk != NULL) {
67 			bh_lock_sock(ax25->sk);
68 			ax25->sk->sk_state = TCP_ESTABLISHED;
69 			/*
70 			 * For WAIT_SABM connections we will produce an accept
71 			 * ready socket here
72 			 */
73 			if (!sock_flag(ax25->sk, SOCK_DEAD))
74 				ax25->sk->sk_state_change(ax25->sk);
75 			bh_unlock_sock(ax25->sk);
76 		}
77 		ax25_dama_on(ax25);
78 
79 		/* according to DK4EG�s spec we are required to
80 		 * send a RR RESPONSE FINAL NR=0.
81 		 */
82 
83 		ax25_std_enquiry_response(ax25);
84 		break;
85 
86 	case AX25_DM:
87 		if (pf)
88 			ax25_disconnect(ax25, ECONNREFUSED);
89 		break;
90 
91 	default:
92 		if (pf)
93 			ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
94 		break;
95 	}
96 
97 	return 0;
98 }
99 
100 /*
101  *	State machine for state 2, Awaiting Release State.
102  *	The handling of the timer(s) is in file ax25_ds_timer.c
103  *	Handling of state 0 and connection release is in ax25.c.
104  */
105 static int ax25_ds_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
106 {
107 	switch (frametype) {
108 	case AX25_SABM:
109 	case AX25_SABME:
110 		ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
111 		ax25_dama_off(ax25);
112 		break;
113 
114 	case AX25_DISC:
115 		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
116 		ax25_dama_off(ax25);
117 		ax25_disconnect(ax25, 0);
118 		break;
119 
120 	case AX25_DM:
121 	case AX25_UA:
122 		if (pf) {
123 			ax25_dama_off(ax25);
124 			ax25_disconnect(ax25, 0);
125 		}
126 		break;
127 
128 	case AX25_I:
129 	case AX25_REJ:
130 	case AX25_RNR:
131 	case AX25_RR:
132 		if (pf) {
133 			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
134 			ax25_dama_off(ax25);
135 		}
136 		break;
137 
138 	default:
139 		break;
140 	}
141 
142 	return 0;
143 }
144 
145 /*
146  *	State machine for state 3, Connected State.
147  *	The handling of the timer(s) is in file ax25_timer.c
148  *	Handling of state 0 and connection release is in ax25.c.
149  */
150 static int ax25_ds_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
151 {
152 	int queued = 0;
153 
154 	switch (frametype) {
155 	case AX25_SABM:
156 	case AX25_SABME:
157 		if (frametype == AX25_SABM) {
158 			ax25->modulus   = AX25_MODULUS;
159 			ax25->window    = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
160 		} else {
161 			ax25->modulus   = AX25_EMODULUS;
162 			ax25->window    = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
163 		}
164 		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
165 		ax25_stop_t1timer(ax25);
166 		ax25_start_t3timer(ax25);
167 		ax25_start_idletimer(ax25);
168 		ax25->condition = 0x00;
169 		ax25->vs        = 0;
170 		ax25->va        = 0;
171 		ax25->vr        = 0;
172 		ax25_requeue_frames(ax25);
173 		ax25_dama_on(ax25);
174 		break;
175 
176 	case AX25_DISC:
177 		ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
178 		ax25_dama_off(ax25);
179 		ax25_disconnect(ax25, 0);
180 		break;
181 
182 	case AX25_DM:
183 		ax25_dama_off(ax25);
184 		ax25_disconnect(ax25, ECONNRESET);
185 		break;
186 
187 	case AX25_RR:
188 	case AX25_RNR:
189 		if (frametype == AX25_RR)
190 			ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
191 		else
192 			ax25->condition |= AX25_COND_PEER_RX_BUSY;
193 
194 		if (ax25_validate_nr(ax25, nr)) {
195 			if (ax25_check_iframes_acked(ax25, nr))
196 				ax25->n2count=0;
197 			if (type == AX25_COMMAND && pf)
198 				ax25_ds_enquiry_response(ax25);
199 		} else {
200 			ax25_ds_nr_error_recovery(ax25);
201 			ax25->state = AX25_STATE_1;
202 		}
203 		break;
204 
205 	case AX25_REJ:
206 		ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
207 
208 		if (ax25_validate_nr(ax25, nr)) {
209 			if (ax25->va != nr)
210 				ax25->n2count=0;
211 
212 			ax25_frames_acked(ax25, nr);
213 			ax25_calculate_rtt(ax25);
214 			ax25_stop_t1timer(ax25);
215 			ax25_start_t3timer(ax25);
216 			ax25_requeue_frames(ax25);
217 
218 			if (type == AX25_COMMAND && pf)
219 				ax25_ds_enquiry_response(ax25);
220 		} else {
221 			ax25_ds_nr_error_recovery(ax25);
222 			ax25->state = AX25_STATE_1;
223 		}
224 		break;
225 
226 	case AX25_I:
227 		if (!ax25_validate_nr(ax25, nr)) {
228 			ax25_ds_nr_error_recovery(ax25);
229 			ax25->state = AX25_STATE_1;
230 			break;
231 		}
232 		if (ax25->condition & AX25_COND_PEER_RX_BUSY) {
233 			ax25_frames_acked(ax25, nr);
234 			ax25->n2count = 0;
235 		} else {
236 			if (ax25_check_iframes_acked(ax25, nr))
237 				ax25->n2count = 0;
238 		}
239 		if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
240 			if (pf) ax25_ds_enquiry_response(ax25);
241 			break;
242 		}
243 		if (ns == ax25->vr) {
244 			ax25->vr = (ax25->vr + 1) % ax25->modulus;
245 			queued = ax25_rx_iframe(ax25, skb);
246 			if (ax25->condition & AX25_COND_OWN_RX_BUSY)
247 				ax25->vr = ns;	/* ax25->vr - 1 */
248 			ax25->condition &= ~AX25_COND_REJECT;
249 			if (pf) {
250 				ax25_ds_enquiry_response(ax25);
251 			} else {
252 				if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
253 					ax25->condition |= AX25_COND_ACK_PENDING;
254 					ax25_start_t2timer(ax25);
255 				}
256 			}
257 		} else {
258 			if (ax25->condition & AX25_COND_REJECT) {
259 				if (pf) ax25_ds_enquiry_response(ax25);
260 			} else {
261 				ax25->condition |= AX25_COND_REJECT;
262 				ax25_ds_enquiry_response(ax25);
263 				ax25->condition &= ~AX25_COND_ACK_PENDING;
264 			}
265 		}
266 		break;
267 
268 	case AX25_FRMR:
269 	case AX25_ILLEGAL:
270 		ax25_ds_establish_data_link(ax25);
271 		ax25->state = AX25_STATE_1;
272 		break;
273 
274 	default:
275 		break;
276 	}
277 
278 	return queued;
279 }
280 
281 /*
282  *	Higher level upcall for a LAPB frame
283  */
284 int ax25_ds_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
285 {
286 	int queued = 0, frametype, ns, nr, pf;
287 
288 	frametype = ax25_decode(ax25, skb, &ns, &nr, &pf);
289 
290 	switch (ax25->state) {
291 	case AX25_STATE_1:
292 		queued = ax25_ds_state1_machine(ax25, skb, frametype, pf, type);
293 		break;
294 	case AX25_STATE_2:
295 		queued = ax25_ds_state2_machine(ax25, skb, frametype, pf, type);
296 		break;
297 	case AX25_STATE_3:
298 		queued = ax25_ds_state3_machine(ax25, skb, frametype, ns, nr, pf, type);
299 		break;
300 	}
301 
302 	return queued;
303 }
304 
305