Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
x25
x25_timer.c
Go to the documentation of this file.
1
/*
2
* X.25 Packet Layer release 002
3
*
4
* This is ALPHA test software. This code may break your machine,
5
* randomly fail to work with new releases, misbehave and/or generally
6
* screw up. It might even work.
7
*
8
* This code REQUIRES 2.1.15 or higher
9
*
10
* This module:
11
* This module is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU General Public License
13
* as published by the Free Software Foundation; either version
14
* 2 of the License, or (at your option) any later version.
15
*
16
* History
17
* X.25 001 Jonathan Naylor Started coding.
18
* X.25 002 Jonathan Naylor New timer architecture.
19
* Centralised disconnection processing.
20
*/
21
22
#include <linux/errno.h>
23
#include <
linux/jiffies.h
>
24
#include <
linux/timer.h
>
25
#include <
net/sock.h
>
26
#include <
net/tcp_states.h
>
27
#include <
net/x25.h
>
28
29
static
void
x25_heartbeat_expiry(
unsigned
long
);
30
static
void
x25_timer_expiry(
unsigned
long
);
31
32
void
x25_init_timers
(
struct
sock
*
sk
)
33
{
34
struct
x25_sock
*x25 = x25_sk(sk);
35
36
setup_timer
(&x25->
timer
, x25_timer_expiry, (
unsigned
long
)sk);
37
38
/* initialized by sock_init_data */
39
sk->sk_timer.data = (
unsigned
long
)sk;
40
sk->sk_timer.function = &x25_heartbeat_expiry;
41
}
42
43
void
x25_start_heartbeat
(
struct
sock
*
sk
)
44
{
45
mod_timer
(&sk->
sk_timer
,
jiffies
+ 5 *
HZ
);
46
}
47
48
void
x25_stop_heartbeat
(
struct
sock
*
sk
)
49
{
50
del_timer
(&sk->
sk_timer
);
51
}
52
53
void
x25_start_t2timer
(
struct
sock
*
sk
)
54
{
55
struct
x25_sock
*x25 = x25_sk(sk);
56
57
mod_timer
(&x25->
timer
,
jiffies
+ x25->
t2
);
58
}
59
60
void
x25_start_t21timer
(
struct
sock
*
sk
)
61
{
62
struct
x25_sock
*x25 = x25_sk(sk);
63
64
mod_timer
(&x25->
timer
,
jiffies
+ x25->
t21
);
65
}
66
67
void
x25_start_t22timer
(
struct
sock
*
sk
)
68
{
69
struct
x25_sock
*x25 = x25_sk(sk);
70
71
mod_timer
(&x25->
timer
,
jiffies
+ x25->
t22
);
72
}
73
74
void
x25_start_t23timer
(
struct
sock
*
sk
)
75
{
76
struct
x25_sock
*x25 = x25_sk(sk);
77
78
mod_timer
(&x25->
timer
,
jiffies
+ x25->
t23
);
79
}
80
81
void
x25_stop_timer
(
struct
sock
*
sk
)
82
{
83
del_timer
(&x25_sk(sk)->
timer
);
84
}
85
86
unsigned
long
x25_display_timer
(
struct
sock
*
sk
)
87
{
88
struct
x25_sock
*x25 = x25_sk(sk);
89
90
if
(!timer_pending(&x25->
timer
))
91
return
0;
92
93
return
x25->
timer
.expires -
jiffies
;
94
}
95
96
static
void
x25_heartbeat_expiry(
unsigned
long
param
)
97
{
98
struct
sock
*
sk
= (
struct
sock
*)param;
99
100
bh_lock_sock
(sk);
101
if
(
sock_owned_by_user
(sk))
/* can currently only occur in state 3 */
102
goto
restart_heartbeat;
103
104
switch
(x25_sk(sk)->
state
) {
105
106
case
X25_STATE_0
:
107
/*
108
* Magic here: If we listen() and a new link dies
109
* before it is accepted() it isn't 'dead' so doesn't
110
* get removed.
111
*/
112
if
(sock_flag(sk,
SOCK_DESTROY
) ||
113
(sk->sk_state ==
TCP_LISTEN
&&
114
sock_flag(sk,
SOCK_DEAD
))) {
115
bh_unlock_sock
(sk);
116
x25_destroy_socket_from_timer
(sk);
117
return
;
118
}
119
break
;
120
121
case
X25_STATE_3
:
122
/*
123
* Check for the state of the receive buffer.
124
*/
125
x25_check_rbuf
(sk);
126
break
;
127
}
128
restart_heartbeat:
129
x25_start_heartbeat
(sk);
130
bh_unlock_sock
(sk);
131
}
132
133
/*
134
* Timer has expired, it may have been T2, T21, T22, or T23. We can tell
135
* by the state machine state.
136
*/
137
static
inline
void
x25_do_timer_expiry(
struct
sock
* sk)
138
{
139
struct
x25_sock
*x25 = x25_sk(sk);
140
141
switch
(x25->
state
) {
142
143
case
X25_STATE_3
:
/* T2 */
144
if
(x25->
condition
&
X25_COND_ACK_PENDING
) {
145
x25->
condition
&= ~
X25_COND_ACK_PENDING
;
146
x25_enquiry_response
(sk);
147
}
148
break
;
149
150
case
X25_STATE_1
:
/* T21 */
151
case
X25_STATE_4
:
/* T22 */
152
x25_write_internal
(sk,
X25_CLEAR_REQUEST
);
153
x25->
state
=
X25_STATE_2
;
154
x25_start_t23timer
(sk);
155
break
;
156
157
case
X25_STATE_2
:
/* T23 */
158
x25_disconnect
(sk,
ETIMEDOUT
, 0, 0);
159
break
;
160
}
161
}
162
163
static
void
x25_timer_expiry(
unsigned
long
param)
164
{
165
struct
sock
*sk = (
struct
sock
*)param;
166
167
bh_lock_sock
(sk);
168
if
(
sock_owned_by_user
(sk)) {
/* can currently only occur in state 3 */
169
if
(x25_sk(sk)->
state
==
X25_STATE_3
)
170
x25_start_t2timer
(sk);
171
}
else
172
x25_do_timer_expiry(sk);
173
bh_unlock_sock
(sk);
174
}
Generated on Thu Jan 10 2013 15:02:38 for Linux Kernel by
1.8.2