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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [ax25/] [ax25_ds_timer.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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/spinlock.h>
14
#include <linux/in.h>
15
#include <linux/kernel.h>
16
#include <linux/jiffies.h>
17
#include <linux/timer.h>
18
#include <linux/string.h>
19
#include <linux/sockios.h>
20
#include <linux/net.h>
21
#include <net/tcp_states.h>
22
#include <net/ax25.h>
23
#include <linux/inet.h>
24
#include <linux/netdevice.h>
25
#include <linux/skbuff.h>
26
#include <net/sock.h>
27
#include <asm/uaccess.h>
28
#include <asm/system.h>
29
#include <linux/fcntl.h>
30
#include <linux/mm.h>
31
#include <linux/interrupt.h>
32
 
33
static void ax25_ds_timeout(unsigned long);
34
 
35
/*
36
 *      Add DAMA slave timeout timer to timer list.
37
 *      Unlike the connection based timers the timeout function gets
38
 *      triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT
39
 *      (aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in
40
 *      1/10th of a second.
41
 */
42
 
43
static void ax25_ds_add_timer(ax25_dev *ax25_dev)
44
{
45
        struct timer_list *t = &ax25_dev->dama.slave_timer;
46
        t->data         = (unsigned long) ax25_dev;
47
        t->function     = &ax25_ds_timeout;
48
        t->expires      = jiffies + HZ;
49
        add_timer(t);
50
}
51
 
52
void ax25_ds_del_timer(ax25_dev *ax25_dev)
53
{
54
        if (ax25_dev)
55
                del_timer(&ax25_dev->dama.slave_timer);
56
}
57
 
58
void ax25_ds_set_timer(ax25_dev *ax25_dev)
59
{
60
        if (ax25_dev == NULL)           /* paranoia */
61
                return;
62
 
63
        del_timer(&ax25_dev->dama.slave_timer);
64
        ax25_dev->dama.slave_timeout =
65
                msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
66
        ax25_ds_add_timer(ax25_dev);
67
}
68
 
69
/*
70
 *      DAMA Slave Timeout
71
 *      Silently discard all (slave) connections in case our master forgot us...
72
 */
73
 
74
static void ax25_ds_timeout(unsigned long arg)
75
{
76
        ax25_dev *ax25_dev = (struct ax25_dev *) arg;
77
        ax25_cb *ax25;
78
        struct hlist_node *node;
79
 
80
        if (ax25_dev == NULL || !ax25_dev->dama.slave)
81
                return;                 /* Yikes! */
82
 
83
        if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) {
84
                ax25_ds_set_timer(ax25_dev);
85
                return;
86
        }
87
 
88
        spin_lock(&ax25_list_lock);
89
        ax25_for_each(ax25, node, &ax25_list) {
90
                if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
91
                        continue;
92
 
93
                ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
94
                ax25_disconnect(ax25, ETIMEDOUT);
95
        }
96
        spin_unlock(&ax25_list_lock);
97
 
98
        ax25_dev_dama_off(ax25_dev);
99
}
100
 
101
void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
102
{
103
        struct sock *sk=ax25->sk;
104
 
105
        if (sk)
106
                bh_lock_sock(sk);
107
 
108
        switch (ax25->state) {
109
 
110
        case AX25_STATE_0:
111
                /* Magic here: If we listen() and a new link dies before it
112
                   is accepted() it isn't 'dead' so doesn't get removed. */
113
                if (!sk || sock_flag(sk, SOCK_DESTROY) ||
114
                    (sk->sk_state == TCP_LISTEN &&
115
                     sock_flag(sk, SOCK_DEAD))) {
116
                        if (sk) {
117
                                sock_hold(sk);
118
                                ax25_destroy_socket(ax25);
119
                                sock_put(sk);
120
                                bh_unlock_sock(sk);
121
                        } else
122
                                ax25_destroy_socket(ax25);
123
                        return;
124
                }
125
                break;
126
 
127
        case AX25_STATE_3:
128
                /*
129
                 * Check the state of the receive buffer.
130
                 */
131
                if (sk != NULL) {
132
                        if (atomic_read(&sk->sk_rmem_alloc) <
133
                            (sk->sk_rcvbuf / 2) &&
134
                            (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
135
                                ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
136
                                ax25->condition &= ~AX25_COND_ACK_PENDING;
137
                                break;
138
                        }
139
                }
140
                break;
141
        }
142
 
143
        if (sk)
144
                bh_unlock_sock(sk);
145
 
146
        ax25_start_heartbeat(ax25);
147
}
148
 
149
/* dl1bke 960114: T3 works much like the IDLE timeout, but
150
 *                gets reloaded with every frame for this
151
 *                connection.
152
 */
153
void ax25_ds_t3timer_expiry(ax25_cb *ax25)
154
{
155
        ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
156
        ax25_dama_off(ax25);
157
        ax25_disconnect(ax25, ETIMEDOUT);
158
}
159
 
160
/* dl1bke 960228: close the connection when IDLE expires.
161
 *                unlike T3 this timer gets reloaded only on
162
 *                I frames.
163
 */
164
void ax25_ds_idletimer_expiry(ax25_cb *ax25)
165
{
166
        ax25_clear_queues(ax25);
167
 
168
        ax25->n2count = 0;
169
        ax25->state = AX25_STATE_2;
170
 
171
        ax25_calculate_t1(ax25);
172
        ax25_start_t1timer(ax25);
173
        ax25_stop_t3timer(ax25);
174
 
175
        if (ax25->sk != NULL) {
176
                bh_lock_sock(ax25->sk);
177
                ax25->sk->sk_state     = TCP_CLOSE;
178
                ax25->sk->sk_err       = 0;
179
                ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
180
                if (!sock_flag(ax25->sk, SOCK_DEAD)) {
181
                        ax25->sk->sk_state_change(ax25->sk);
182
                        sock_set_flag(ax25->sk, SOCK_DEAD);
183
                }
184
                bh_unlock_sock(ax25->sk);
185
        }
186
}
187
 
188
/* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
189
 *                within the poll of any connected channel. Remember
190
 *                that we are not allowed to send anything unless we
191
 *                get polled by the Master.
192
 *
193
 *                Thus we'll have to do parts of our T1 handling in
194
 *                ax25_enquiry_response().
195
 */
196
void ax25_ds_t1_timeout(ax25_cb *ax25)
197
{
198
        switch (ax25->state) {
199
        case AX25_STATE_1:
200
                if (ax25->n2count == ax25->n2) {
201
                        if (ax25->modulus == AX25_MODULUS) {
202
                                ax25_disconnect(ax25, ETIMEDOUT);
203
                                return;
204
                        } else {
205
                                ax25->modulus = AX25_MODULUS;
206
                                ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
207
                                ax25->n2count = 0;
208
                                ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
209
                        }
210
                } else {
211
                        ax25->n2count++;
212
                        if (ax25->modulus == AX25_MODULUS)
213
                                ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
214
                        else
215
                                ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
216
                }
217
                break;
218
 
219
        case AX25_STATE_2:
220
                if (ax25->n2count == ax25->n2) {
221
                        ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
222
                        ax25_disconnect(ax25, ETIMEDOUT);
223
                        return;
224
                } else {
225
                        ax25->n2count++;
226
                }
227
                break;
228
 
229
        case AX25_STATE_3:
230
                if (ax25->n2count == ax25->n2) {
231
                        ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
232
                        ax25_disconnect(ax25, ETIMEDOUT);
233
                        return;
234
                } else {
235
                        ax25->n2count++;
236
                }
237
                break;
238
        }
239
 
240
        ax25_calculate_t1(ax25);
241
        ax25_start_t1timer(ax25);
242
}

powered by: WebSVN 2.1.0

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