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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [ax25/] [ax25_timer.c] - Blame information for rev 1629

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

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *      AX.25 release 035
3
 *
4
 *      This code REQUIRES 1.2.1 or higher/ NET3.029
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 028a      Jonathan(G4KLX) New state machine based on SDL diagrams.
14
 *      AX.25 028b      Jonathan(G4KLX) Extracted AX25 control block from the
15
 *                                      sock structure.
16
 *      AX.25 029       Alan(GW4PTS)    Switched to KA9Q constant names.
17
 *      AX.25 031       Joerg(DL1BKE)   Added DAMA support
18
 *      AX.25 032       Joerg(DL1BKE)   Fixed DAMA timeout bug
19
 *      AX.25 033       Jonathan(G4KLX) Modularisation functions.
20
 *      AX.25 035       Frederic(F1OAT) Support for pseudo-digipeating.
21
 */
22
 
23
#include <linux/config.h>
24
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
25
#include <linux/errno.h>
26
#include <linux/types.h>
27
#include <linux/socket.h>
28
#include <linux/in.h>
29
#include <linux/kernel.h>
30
#include <linux/sched.h>
31
#include <linux/timer.h>
32
#include <linux/string.h>
33
#include <linux/sockios.h>
34
#include <linux/net.h>
35
#include <net/ax25.h>
36
#include <linux/inet.h>
37
#include <linux/netdevice.h>
38
#include <linux/skbuff.h>
39
#include <net/sock.h>
40
#include <asm/segment.h>
41
#include <asm/system.h>
42
#include <linux/fcntl.h>
43
#include <linux/mm.h>
44
#include <linux/interrupt.h>
45
 
46
static void ax25_timer(unsigned long);
47
 
48
/*
49
 *      Linux set timer
50
 */
51
void ax25_set_timer(ax25_cb *ax25)
52
{
53
        unsigned long flags;
54
 
55
        save_flags(flags); cli();
56
        del_timer(&ax25->timer);
57
        restore_flags(flags);
58
 
59
        ax25->timer.data     = (unsigned long)ax25;
60
        ax25->timer.function = &ax25_timer;
61
        ax25->timer.expires  = jiffies + 10;
62
 
63
        add_timer(&ax25->timer);
64
}
65
 
66
/*
67
 *      AX.25 TIMER
68
 *
69
 *      This routine is called every 100ms. Decrement timer by this
70
 *      amount - if expired then process the event.
71
 */
72
static void ax25_timer(unsigned long param)
73
{
74
        ax25_cb *ax25 = (ax25_cb *)param;
75
 
76
        switch (ax25->state) {
77
                case AX25_STATE_0:
78
                        /* Magic here: If we listen() and a new link dies before it
79
                           is accepted() it isn't 'dead' so doesn't get removed. */
80
                        if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
81
                                ax25_destroy_socket(ax25);
82
                                return;
83
                        }
84
                        break;
85
 
86
                case AX25_STATE_3:
87
                case AX25_STATE_4:
88
                        /*
89
                         * Check the state of the receive buffer.
90
                         */
91
                        if (ax25->sk != NULL) {
92
                                if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
93
                                        ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
94
                                        ax25->condition &= ~AX25_COND_ACK_PENDING;
95
                                        if (!ax25->dama_slave)
96
                                                ax25_send_control(ax25, AX25_RR, AX25_POLLOFF, AX25_RESPONSE);
97
                                        break;
98
                                }
99
                        }
100
                        /*
101
                         * Check for frames to transmit.
102
                         */
103
                        if (!ax25->dama_slave)
104
                                ax25_kick(ax25);
105
                        break;
106
 
107
                default:
108
                        break;
109
        }
110
 
111
        if (ax25->t2timer > 0 && --ax25->t2timer == 0) {
112
                if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
113
                        if (ax25->condition & AX25_COND_ACK_PENDING) {
114
                                ax25->condition &= ~AX25_COND_ACK_PENDING;
115
                                if (!ax25->dama_slave)
116
                                        ax25_timeout_response(ax25);
117
                        }
118
                }
119
        }
120
 
121
        if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
122
                /* dl1bke 960114: T3 expires and we are in DAMA mode:  */
123
                /*                send a DISC and abort the connection */
124
                if (ax25->dama_slave) {
125
                        ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
126
                        ax25_disconnect(ax25, ETIMEDOUT);
127
                        ax25_set_timer(ax25);
128
                        return;
129
                }
130
 
131
                if (ax25->state == AX25_STATE_3) {
132
                        ax25->n2count = 0;
133
                        ax25_transmit_enquiry(ax25);
134
                        ax25->state   = AX25_STATE_4;
135
                }
136
 
137
                ax25->t3timer = ax25->t3;
138
        }
139
 
140
        if (ax25->idletimer > 0 && --ax25->idletimer == 0) {
141
                /* dl1bke 960228: close the connection when IDLE expires */
142
                /*                similar to DAMA T3 timeout but with    */
143
                /*                a "clean" disconnect of the connection */
144
 
145
                ax25_clear_queues(ax25);
146
 
147
                ax25->n2count = 0;
148
                if (!ax25->dama_slave) {
149
                        ax25->t3timer = 0;
150
                        ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
151
                } else {
152
                        ax25->t3timer = ax25->t3;
153
                }
154
 
155
                /* state 1 or 2 should not happen, but... */
156
 
157
                if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2)
158
                        ax25->state = AX25_STATE_0;
159
                else
160
                        ax25->state = AX25_STATE_2;
161
 
162
                ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
163
                ax25->t2timer = 0;
164
 
165
                if (ax25->sk != NULL) {
166
                        ax25->sk->state     = TCP_CLOSE;
167
                        ax25->sk->err       = 0;
168
                        ax25->sk->shutdown |= SEND_SHUTDOWN;
169
                        if (!ax25->sk->dead)
170
                                ax25->sk->state_change(ax25->sk);
171
                        ax25->sk->dead      = 1;
172
                }
173
        }
174
 
175
        /* dl1bke 960114: DAMA T1 timeouts are handled in ax25_dama_slave_transmit */
176
        /*                nevertheless we have to re-enqueue the timer struct...   */
177
        if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
178
                ax25_set_timer(ax25);
179
                return;
180
        }
181
 
182
        if (!ax25_dev_is_dama_slave(ax25->device)) {
183
                if (ax25->dama_slave)
184
                        ax25->dama_slave = 0;
185
                ax25_t1_timeout(ax25);
186
        }
187
}
188
 
189
 
190
/* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
191
 *                within the poll of any connected channel. Remember
192
 *                that we are not allowed to send anything unless we
193
 *                get polled by the Master.
194
 *
195
 *                Thus we'll have to do parts of our T1 handling in
196
 *                ax25_enquiry_response().
197
 */
198
void ax25_t1_timeout(ax25_cb *ax25)
199
{
200
        switch (ax25->state) {
201
                case AX25_STATE_1:
202
                        if (ax25->n2count == ax25->n2) {
203
                                if (ax25->modulus == AX25_MODULUS) {
204
                                        ax25_disconnect(ax25, ETIMEDOUT);
205
                                } else {
206
                                        ax25->modulus = AX25_MODULUS;
207
                                        ax25->window  = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
208
                                        ax25->n2count = 0;
209
                                        ax25_send_control(ax25, AX25_SABM, ax25_dev_is_dama_slave(ax25->device) ? AX25_POLLOFF : AX25_POLLON, AX25_COMMAND);
210
                                }
211
                        } else {
212
                                ax25->n2count++;
213
                                if (ax25->modulus == AX25_MODULUS)
214
                                        ax25_send_control(ax25, AX25_SABM, ax25_dev_is_dama_slave(ax25->device) ? AX25_POLLOFF : AX25_POLLON, AX25_COMMAND);
215
                                else
216
                                        ax25_send_control(ax25, AX25_SABME, ax25_dev_is_dama_slave(ax25->device) ? AX25_POLLOFF : AX25_POLLON, AX25_COMMAND);
217
                        }
218
                        break;
219
 
220
                case AX25_STATE_2:
221
                        if (ax25->n2count == ax25->n2) {
222
                                ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
223
                                ax25_disconnect(ax25, ETIMEDOUT);
224
                        } else {
225
                                ax25->n2count++;
226
                                if (!ax25_dev_is_dama_slave(ax25->device))
227
                                        ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
228
                        }
229
                        break;
230
 
231
                case AX25_STATE_3:
232
                        ax25->n2count = 1;
233
                        if (!ax25->dama_slave)
234
                                ax25_transmit_enquiry(ax25);
235
                        ax25->state   = AX25_STATE_4;
236
                        break;
237
 
238
                case AX25_STATE_4:
239
                        if (ax25->n2count == ax25->n2) {
240
                                ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
241
                                ax25_disconnect(ax25, ETIMEDOUT);
242
                        } else {
243
                                ax25->n2count++;
244
                                if (!ax25->dama_slave)
245
                                        ax25_transmit_enquiry(ax25);
246
                        }
247
                        break;
248
        }
249
 
250
        ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
251
 
252
        ax25_set_timer(ax25);
253
}
254
 
255
/************************************************************************/
256
/*      Module support functions follow.                                */
257
/************************************************************************/
258
 
259
static struct protocol_struct {
260
        struct protocol_struct *next;
261
        unsigned int pid;
262
        int (*func)(struct sk_buff *, ax25_cb *);
263
} *protocol_list = NULL;
264
 
265
static struct linkfail_struct {
266
        struct linkfail_struct *next;
267
        void (*func)(ax25_cb *, int);
268
} *linkfail_list = NULL;
269
 
270
static struct listen_struct {
271
        struct listen_struct *next;
272
        ax25_address  callsign;
273
        struct device *dev;
274
} *listen_list = NULL;
275
 
276
int ax25_protocol_register(unsigned int pid, int (*func)(struct sk_buff *, ax25_cb *))
277
{
278
        struct protocol_struct *protocol;
279
        unsigned long flags;
280
 
281
        if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT)
282
                return 0;
283
#ifdef CONFIG_INET
284
        if (pid == AX25_P_IP || pid == AX25_P_ARP)
285
                return 0;
286
#endif
287
        if ((protocol = (struct protocol_struct *)kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL)
288
                return 0;
289
 
290
        protocol->pid  = pid;
291
        protocol->func = func;
292
 
293
        save_flags(flags);
294
        cli();
295
 
296
        protocol->next = protocol_list;
297
        protocol_list  = protocol;
298
 
299
        restore_flags(flags);
300
 
301
        return 1;
302
}
303
 
304
void ax25_protocol_release(unsigned int pid)
305
{
306
        struct protocol_struct *s, *protocol = protocol_list;
307
        unsigned long flags;
308
 
309
        if (protocol == NULL)
310
                return;
311
 
312
        save_flags(flags);
313
        cli();
314
 
315
        if (protocol->pid == pid) {
316
                protocol_list = protocol->next;
317
                restore_flags(flags);
318
                kfree_s(protocol, sizeof(struct protocol_struct));
319
                return;
320
        }
321
 
322
        while (protocol != NULL && protocol->next != NULL) {
323
                if (protocol->next->pid == pid) {
324
                        s = protocol->next;
325
                        protocol->next = protocol->next->next;
326
                        restore_flags(flags);
327
                        kfree_s(s, sizeof(struct protocol_struct));
328
                        return;
329
                }
330
 
331
                protocol = protocol->next;
332
        }
333
 
334
        restore_flags(flags);
335
}
336
 
337
int ax25_linkfail_register(void (*func)(ax25_cb *, int))
338
{
339
        struct linkfail_struct *linkfail;
340
        unsigned long flags;
341
 
342
        if ((linkfail = (struct linkfail_struct *)kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
343
                return 0;
344
 
345
        linkfail->func = func;
346
 
347
        save_flags(flags);
348
        cli();
349
 
350
        linkfail->next = linkfail_list;
351
        linkfail_list  = linkfail;
352
 
353
        restore_flags(flags);
354
 
355
        return 1;
356
}
357
 
358
void ax25_linkfail_release(void (*func)(ax25_cb *, int))
359
{
360
        struct linkfail_struct *s, *linkfail = linkfail_list;
361
        unsigned long flags;
362
 
363
        if (linkfail == NULL)
364
                return;
365
 
366
        save_flags(flags);
367
        cli();
368
 
369
        if (linkfail->func == func) {
370
                linkfail_list = linkfail->next;
371
                restore_flags(flags);
372
                kfree_s(linkfail, sizeof(struct linkfail_struct));
373
                return;
374
        }
375
 
376
        while (linkfail != NULL && linkfail->next != NULL) {
377
                if (linkfail->next->func == func) {
378
                        s = linkfail->next;
379
                        linkfail->next = linkfail->next->next;
380
                        restore_flags(flags);
381
                        kfree_s(s, sizeof(struct linkfail_struct));
382
                        return;
383
                }
384
 
385
                linkfail = linkfail->next;
386
        }
387
 
388
        restore_flags(flags);
389
}
390
 
391
int ax25_listen_register(ax25_address *callsign, struct device *dev)
392
{
393
        struct listen_struct *listen;
394
        unsigned long flags;
395
 
396
        if (ax25_listen_mine(callsign, dev))
397
                return 0;
398
 
399
        if ((listen = (struct listen_struct *)kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL)
400
                return 0;
401
 
402
        listen->callsign = *callsign;
403
        listen->dev      = dev;
404
 
405
        save_flags(flags);
406
        cli();
407
 
408
        listen->next = listen_list;
409
        listen_list  = listen;
410
 
411
        restore_flags(flags);
412
 
413
        return 1;
414
}
415
 
416
void ax25_listen_release(ax25_address *callsign, struct device *dev)
417
{
418
        struct listen_struct *s, *listen = listen_list;
419
        unsigned long flags;
420
 
421
        if (listen == NULL)
422
                return;
423
 
424
        save_flags(flags);
425
        cli();
426
 
427
        if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) {
428
                listen_list = listen->next;
429
                restore_flags(flags);
430
                kfree_s(listen, sizeof(struct listen_struct));
431
                return;
432
        }
433
 
434
        while (listen != NULL && listen->next != NULL) {
435
                if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) {
436
                        s = listen->next;
437
                        listen->next = listen->next->next;
438
                        restore_flags(flags);
439
                        kfree_s(s, sizeof(struct listen_struct));
440
                        return;
441
                }
442
 
443
                listen = listen->next;
444
        }
445
 
446
        restore_flags(flags);
447
}
448
 
449
int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
450
{
451
        struct protocol_struct *protocol;
452
 
453
        for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
454
                if (protocol->pid == pid)
455
                        return protocol->func;
456
 
457
        return NULL;
458
}
459
 
460
int ax25_listen_mine(ax25_address *callsign, struct device *dev)
461
{
462
        struct listen_struct *listen;
463
 
464
        for (listen = listen_list; listen != NULL; listen = listen->next)
465
                if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL))
466
                        return 1;
467
 
468
        return 0;
469
}
470
 
471
void ax25_link_failed(ax25_cb *ax25, int reason)
472
{
473
        struct linkfail_struct *linkfail;
474
 
475
        for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next)
476
                (linkfail->func)(ax25, reason);
477
}
478
 
479
int ax25_protocol_is_registered(unsigned int pid)
480
{
481
        struct protocol_struct *protocol;
482
 
483
        for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
484
                if (protocol->pid == pid)
485
                        return 1;
486
 
487
        return 0;
488
}
489
 
490
#endif

powered by: WebSVN 2.1.0

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