1 /*
2 * X.25 Packet Layer release 002
3 *
4 * This is ALPHA test software. This code may break your machine, randomly fail to work with new
5 * releases, misbehave and/or generally screw up. It might even work.
6 *
7 * This code REQUIRES 2.1.15 or higher
8 *
9 * This module:
10 * This module is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 * History
16 * X.25 001 Jonathan Naylor Started coding.
17 * X.25 002 Jonathan Naylor New timer architecture.
18 * Centralised disconnection processing.
19 */
20
21 #include <linux/config.h>
22 #if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
23 #include <linux/errno.h>
24 #include <linux/types.h>
25 #include <linux/socket.h>
26 #include <linux/in.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/timer.h>
30 #include <linux/string.h>
31 #include <linux/sockios.h>
32 #include <linux/net.h>
33 #include <linux/inet.h>
34 #include <linux/netdevice.h>
35 #include <linux/skbuff.h>
36 #include <net/sock.h>
37 #include <asm/segment.h>
38 #include <asm/system.h>
39 #include <linux/fcntl.h>
40 #include <linux/mm.h>
41 #include <linux/interrupt.h>
42 #include <net/x25.h>
43
44 static void x25_heartbeat_expiry(unsigned long);
45 static void x25_timer_expiry(unsigned long);
46
47 void x25_start_heartbeat(struct sock *sk)
48 {
49 del_timer(&sk->timer);
50
51 sk->timer.data = (unsigned long)sk;
52 sk->timer.function = &x25_heartbeat_expiry;
53 sk->timer.expires = jiffies + 5 * HZ;
54
55 add_timer(&sk->timer);
56 }
57
58 void x25_stop_heartbeat(struct sock *sk)
59 {
60 del_timer(&sk->timer);
61 }
62
63 void x25_start_t2timer(struct sock *sk)
64 {
65 del_timer(&sk->protinfo.x25->timer);
66
67 sk->protinfo.x25->timer.data = (unsigned long)sk;
68 sk->protinfo.x25->timer.function = &x25_timer_expiry;
69 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t2;
70
71 add_timer(&sk->protinfo.x25->timer);
72 }
73
74 void x25_start_t21timer(struct sock *sk)
75 {
76 del_timer(&sk->protinfo.x25->timer);
77
78 sk->protinfo.x25->timer.data = (unsigned long)sk;
79 sk->protinfo.x25->timer.function = &x25_timer_expiry;
80 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t21;
81
82 add_timer(&sk->protinfo.x25->timer);
83 }
84
85 void x25_start_t22timer(struct sock *sk)
86 {
87 del_timer(&sk->protinfo.x25->timer);
88
89 sk->protinfo.x25->timer.data = (unsigned long)sk;
90 sk->protinfo.x25->timer.function = &x25_timer_expiry;
91 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t22;
92
93 add_timer(&sk->protinfo.x25->timer);
94 }
95
96 void x25_start_t23timer(struct sock *sk)
97 {
98 del_timer(&sk->protinfo.x25->timer);
99
100 sk->protinfo.x25->timer.data = (unsigned long)sk;
101 sk->protinfo.x25->timer.function = &x25_timer_expiry;
102 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t23;
103
104 add_timer(&sk->protinfo.x25->timer);
105 }
106
107 void x25_stop_timer(struct sock *sk)
108 {
109 del_timer(&sk->protinfo.x25->timer);
110 }
111
112 unsigned long x25_display_timer(struct sock *sk)
113 {
114 if (!timer_pending(&sk->protinfo.x25->timer))
115 return 0;
116
117 return sk->protinfo.x25->timer.expires - jiffies;
118 }
119
120 static void x25_heartbeat_expiry(unsigned long param)
121 {
122 struct sock *sk = (struct sock *)param;
123
124 switch (sk->protinfo.x25->state) {
125
126 case X25_STATE_0:
127 /* Magic here: If we listen() and a new link dies before it
128 is accepted() it isn't 'dead' so doesn't get removed. */
129 if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
130 x25_destroy_socket(sk);
131 return;
132 }
133 break;
134
135 case X25_STATE_3:
136 /*
137 * Check for the state of the receive buffer.
138 */
139 if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
140 (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) {
141 sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
142 sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
143 sk->protinfo.x25->vl = sk->protinfo.x25->vr;
144 x25_write_internal(sk, X25_RR);
145 x25_stop_timer(sk);
146 break;
147 }
148 break;
149 }
150
151 x25_start_heartbeat(sk);
152 }
153
154 /*
155 * Timer has expired, it may have been T2, T21, T22, or T23. We can tell
156 * by the state machine state.
157 */
158 static void x25_timer_expiry(unsigned long param)
159 {
160 struct sock *sk = (struct sock *)param;
161
162 switch (sk->protinfo.x25->state) {
163
164 case X25_STATE_3: /* T2 */
165 if (sk->protinfo.x25->condition & X25_COND_ACK_PENDING) {
166 sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
167 x25_enquiry_response(sk);
168 }
169 break;
170
171 case X25_STATE_1: /* T21 */
172 case X25_STATE_4: /* T22 */
173 x25_write_internal(sk, X25_CLEAR_REQUEST);
174 sk->protinfo.x25->state = X25_STATE_2;
175 x25_start_t23timer(sk);
176 break;
177
178 case X25_STATE_2: /* T23 */
179 x25_disconnect(sk, ETIMEDOUT, 0, 0);
180 break;
181 }
182 }
183
184 #endif
185
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.