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

Subversion Repositories or1k

[/] [or1k/] [tags/] [LINUX_2_4_26_OR32/] [linux/] [linux-2.4/] [net/] [ax25/] [ax25_ds_timer.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      AX.25 release 037
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
 *      AX.25 036       Jonathan(G4KLX) Cloned from ax25_timer.c.
14
 *                      Joerg(DL1BKE)   Added DAMA Slave Timeout timer
15
 *      AX.25 037       Jonathan(G4KLX) New timer architecture.
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
 
39
static void ax25_ds_timeout(unsigned long);
40
 
41
/*
42
 *      Add DAMA slave timeout timer to timer list.
43
 *      Unlike the connection based timers the timeout function gets
44
 *      triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT
45
 *      (aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in
46
 *      1/10th of a second.
47
 */
48
 
49
static void ax25_ds_add_timer(ax25_dev *ax25_dev)
50
{
51
        struct timer_list *t = &ax25_dev->dama.slave_timer;
52
        t->data         = (unsigned long) ax25_dev;
53
        t->function     = &ax25_ds_timeout;
54
        t->expires      = jiffies + HZ;
55
        add_timer(t);
56
}
57
 
58
void ax25_ds_del_timer(ax25_dev *ax25_dev)
59
{
60
        if (ax25_dev) del_timer(&ax25_dev->dama.slave_timer);
61
}
62
 
63
void ax25_ds_set_timer(ax25_dev *ax25_dev)
64
{
65
        if (ax25_dev == NULL)           /* paranoia */
66
                return;
67
 
68
        del_timer(&ax25_dev->dama.slave_timer);
69
        ax25_dev->dama.slave_timeout = ax25_dev->values[AX25_VALUES_DS_TIMEOUT] / 10;
70
        ax25_ds_add_timer(ax25_dev);
71
}
72
 
73
/*
74
 *      DAMA Slave Timeout
75
 *      Silently discard all (slave) connections in case our master forgot us...
76
 */
77
 
78
static void ax25_ds_timeout(unsigned long arg)
79
{
80
        ax25_dev *ax25_dev = (struct ax25_dev *) arg;
81
        ax25_cb *ax25;
82
 
83
        if (ax25_dev == NULL || !ax25_dev->dama.slave)
84
                return;                 /* Yikes! */
85
 
86
        if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) {
87
                ax25_ds_set_timer(ax25_dev);
88
                return;
89
        }
90
 
91
        for (ax25=ax25_list; ax25 != NULL; ax25 = ax25->next) {
92
                if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
93
                        continue;
94
 
95
                ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
96
                ax25_disconnect(ax25, ETIMEDOUT);
97
        }
98
 
99
        ax25_dev_dama_off(ax25_dev);
100
}
101
 
102
void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
103
{
104
        switch (ax25->state) {
105
 
106
                case AX25_STATE_0:
107
                        /* Magic here: If we listen() and a new link dies before it
108
                           is accepted() it isn't 'dead' so doesn't get removed. */
109
                        if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
110
                                ax25_destroy_socket(ax25);
111
                                return;
112
                        }
113
                        break;
114
 
115
                case AX25_STATE_3:
116
                        /*
117
                         * Check the state of the receive buffer.
118
                         */
119
                        if (ax25->sk != NULL) {
120
                                if (atomic_read(&ax25->sk->rmem_alloc) < (ax25->sk->rcvbuf / 2) &&
121
                                    (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
122
                                        ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
123
                                        ax25->condition &= ~AX25_COND_ACK_PENDING;
124
                                        break;
125
                                }
126
                        }
127
                        break;
128
        }
129
 
130
        ax25_start_heartbeat(ax25);
131
}
132
 
133
/* dl1bke 960114: T3 works much like the IDLE timeout, but
134
 *                gets reloaded with every frame for this
135
 *                connection.
136
 */
137
void ax25_ds_t3timer_expiry(ax25_cb *ax25)
138
{
139
        ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
140
        ax25_dama_off(ax25);
141
        ax25_disconnect(ax25, ETIMEDOUT);
142
}
143
 
144
/* dl1bke 960228: close the connection when IDLE expires.
145
 *                unlike T3 this timer gets reloaded only on
146
 *                I frames.
147
 */
148
void ax25_ds_idletimer_expiry(ax25_cb *ax25)
149
{
150
        ax25_clear_queues(ax25);
151
 
152
        ax25->n2count = 0;
153
        ax25->state = AX25_STATE_2;
154
 
155
        ax25_calculate_t1(ax25);
156
        ax25_start_t1timer(ax25);
157
        ax25_stop_t3timer(ax25);
158
 
159
        if (ax25->sk != NULL) {
160
                ax25->sk->state     = TCP_CLOSE;
161
                ax25->sk->err       = 0;
162
                ax25->sk->shutdown |= SEND_SHUTDOWN;
163
                if (!ax25->sk->dead)
164
                        ax25->sk->state_change(ax25->sk);
165
                ax25->sk->dead      = 1;
166
        }
167
}
168
 
169
/* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
170
 *                within the poll of any connected channel. Remember
171
 *                that we are not allowed to send anything unless we
172
 *                get polled by the Master.
173
 *
174
 *                Thus we'll have to do parts of our T1 handling in
175
 *                ax25_enquiry_response().
176
 */
177
void ax25_ds_t1_timeout(ax25_cb *ax25)
178
{
179
        switch (ax25->state) {
180
 
181
                case AX25_STATE_1:
182
                        if (ax25->n2count == ax25->n2) {
183
                                if (ax25->modulus == AX25_MODULUS) {
184
                                        ax25_disconnect(ax25, ETIMEDOUT);
185
                                        return;
186
                                } else {
187
                                        ax25->modulus = AX25_MODULUS;
188
                                        ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
189
                                        ax25->n2count = 0;
190
                                        ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
191
                                }
192
                        } else {
193
                                ax25->n2count++;
194
                                if (ax25->modulus == AX25_MODULUS)
195
                                        ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
196
                                else
197
                                        ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
198
                        }
199
                        break;
200
 
201
                case AX25_STATE_2:
202
                        if (ax25->n2count == ax25->n2) {
203
                                ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
204
                                ax25_disconnect(ax25, ETIMEDOUT);
205
                                return;
206
                        } else {
207
                                ax25->n2count++;
208
                        }
209
                        break;
210
 
211
                case AX25_STATE_3:
212
                        if (ax25->n2count == ax25->n2) {
213
                                ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
214
                                ax25_disconnect(ax25, ETIMEDOUT);
215
                                return;
216
                        } else {
217
                                ax25->n2count++;
218
                        }
219
                        break;
220
        }
221
 
222
        ax25_calculate_t1(ax25);
223
        ax25_start_t1timer(ax25);
224
}

powered by: WebSVN 2.1.0

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