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 (
[email protected]
)
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