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
rose
rose_out.c
Go to the documentation of this file.
1
/*
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
*/
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/in.h>
13
#include <linux/kernel.h>
14
#include <
linux/timer.h
>
15
#include <linux/string.h>
16
#include <
linux/sockios.h
>
17
#include <linux/net.h>
18
#include <
linux/gfp.h
>
19
#include <
net/ax25.h
>
20
#include <
linux/inet.h
>
21
#include <linux/netdevice.h>
22
#include <
linux/skbuff.h
>
23
#include <
net/sock.h
>
24
#include <linux/fcntl.h>
25
#include <
linux/mm.h
>
26
#include <
linux/interrupt.h
>
27
#include <
net/rose.h
>
28
29
/*
30
* This procedure is passed a buffer descriptor for an iframe. It builds
31
* the rest of the control part of the frame and then writes it out.
32
*/
33
static
void
rose_send_iframe(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
34
{
35
struct
rose_sock
*rose =
rose_sk
(sk);
36
37
if
(skb ==
NULL
)
38
return
;
39
40
skb->
data
[2] |= (rose->
vr
<< 5) & 0xE0;
41
skb->
data
[2] |= (rose->
vs
<< 1) & 0x0E;
42
43
rose_start_idletimer
(sk);
44
45
rose_transmit_link
(skb, rose->
neighbour
);
46
}
47
48
void
rose_kick
(
struct
sock
*sk)
49
{
50
struct
rose_sock
*rose =
rose_sk
(sk);
51
struct
sk_buff
*
skb
, *skbn;
52
unsigned
short
start
,
end
;
53
54
if
(rose->
state
!=
ROSE_STATE_3
)
55
return
;
56
57
if
(rose->
condition
&
ROSE_COND_PEER_RX_BUSY
)
58
return
;
59
60
if
(!skb_peek(&sk->
sk_write_queue
))
61
return
;
62
63
start = (skb_peek(&rose->
ack_queue
) ==
NULL
) ? rose->
va
: rose->
vs
;
64
end = (rose->
va
+
sysctl_rose_window_size
) %
ROSE_MODULUS
;
65
66
if
(start == end)
67
return
;
68
69
rose->
vs
=
start
;
70
71
/*
72
* Transmit data until either we're out of data to send or
73
* the window is full.
74
*/
75
76
skb =
skb_dequeue
(&sk->
sk_write_queue
);
77
78
do
{
79
if
((skbn =
skb_clone
(skb,
GFP_ATOMIC
)) ==
NULL
) {
80
skb_queue_head
(&sk->
sk_write_queue
, skb);
81
break
;
82
}
83
84
skb_set_owner_w(skbn, sk);
85
86
/*
87
* Transmit the frame copy.
88
*/
89
rose_send_iframe(sk, skbn);
90
91
rose->
vs
= (rose->
vs
+ 1) %
ROSE_MODULUS
;
92
93
/*
94
* Requeue the original data frame.
95
*/
96
skb_queue_tail
(&rose->
ack_queue
, skb);
97
98
}
while
(rose->
vs
!= end &&
99
(skb =
skb_dequeue
(&sk->
sk_write_queue
)) !=
NULL
);
100
101
rose->
vl
= rose->
vr
;
102
rose->
condition
&= ~
ROSE_COND_ACK_PENDING
;
103
104
rose_stop_timer
(sk);
105
}
106
107
/*
108
* The following routines are taken from page 170 of the 7th ARRL Computer
109
* Networking Conference paper, as is the whole state machine.
110
*/
111
112
void
rose_enquiry_response
(
struct
sock
*sk)
113
{
114
struct
rose_sock
*rose =
rose_sk
(sk);
115
116
if
(rose->
condition
&
ROSE_COND_OWN_RX_BUSY
)
117
rose_write_internal
(sk,
ROSE_RNR
);
118
else
119
rose_write_internal
(sk,
ROSE_RR
);
120
121
rose->
vl
= rose->
vr
;
122
rose->
condition
&= ~
ROSE_COND_ACK_PENDING
;
123
124
rose_stop_timer
(sk);
125
}
Generated on Thu Jan 10 2013 15:01:34 for Linux Kernel by
1.8.2