OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [ax25/] [ax25_ds_in.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.