This source file includes following definitions.
- nr_output
- nr_send_iframe
- nr_send_nak_frame
- nr_kick
- nr_transmit_buffer
- nr_nr_error_recovery
- nr_establish_data_link
- nr_enquiry_response
- nr_check_iframes_acked
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <linux/config.h>
20 #ifdef CONFIG_NETROM
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/socket.h>
24 #include <linux/in.h>
25 #include <linux/kernel.h>
26 #include <linux/sched.h>
27 #include <linux/timer.h>
28 #include <linux/string.h>
29 #include <linux/sockios.h>
30 #include <linux/net.h>
31 #include <net/ax25.h>
32 #include <linux/inet.h>
33 #include <linux/netdevice.h>
34 #include <linux/skbuff.h>
35 #include <net/sock.h>
36 #include <asm/segment.h>
37 #include <asm/system.h>
38 #include <linux/fcntl.h>
39 #include <linux/mm.h>
40 #include <linux/interrupt.h>
41 #include <net/netrom.h>
42
43 int nr_output(struct sock *sk, struct sk_buff *skb)
44 {
45 skb_queue_tail(&sk->write_queue, skb);
46
47 if (sk->nr->state == NR_STATE_3)
48 nr_kick(sk);
49
50 return 0;
51 }
52
53
54
55
56
57 static void nr_send_iframe(struct sock *sk, struct sk_buff *skb)
58 {
59 if (skb == NULL)
60 return;
61
62 skb->data[2] = sk->nr->vs;
63 skb->data[3] = sk->nr->vr;
64
65 nr_transmit_buffer(sk, skb);
66 }
67
68 void nr_send_nak_frame(struct sock *sk)
69 {
70 struct sk_buff *skb, *skbn;
71
72 if ((skb = skb_peek(&sk->nr->ack_queue)) == NULL)
73 return;
74
75 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL)
76 return;
77
78 nr_send_iframe(sk, skbn);
79
80 sk->nr->condition &= ~ACK_PENDING_CONDITION;
81 sk->nr->vl = sk->nr->vr;
82 sk->nr->t1timer = 0;
83 }
84
85 void nr_kick(struct sock *sk)
86 {
87 struct sk_buff *skb, *skbn;
88 int last = 1;
89 unsigned short start, end, next;
90
91 del_timer(&sk->timer);
92
93 start = (skb_peek(&sk->nr->ack_queue) == NULL) ? sk->nr->va : sk->nr->vs;
94 end = (sk->nr->va + sk->window) % NR_MODULUS;
95
96 if (!(sk->nr->condition & PEER_RX_BUSY_CONDITION) &&
97 start != end &&
98 skb_peek(&sk->write_queue) != NULL) {
99
100 sk->nr->vs = start;
101
102
103
104
105
106 do {
107
108
109
110 skb = skb_dequeue(&sk->write_queue);
111
112 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
113 skb_queue_head(&sk->write_queue, skb);
114 return;
115 }
116
117 next = (sk->nr->vs + 1) % NR_MODULUS;
118 last = (next == end);
119
120
121
122
123 nr_send_iframe(sk, skbn);
124
125 sk->nr->vs = next;
126
127
128
129
130 skb_queue_tail(&sk->nr->ack_queue, skb);
131
132 } while (!last && skb_peek(&sk->write_queue) != NULL);
133
134 sk->nr->vl = sk->nr->vr;
135 sk->nr->condition &= ~ACK_PENDING_CONDITION;
136
137 if (sk->nr->t1timer == 0) {
138 sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
139 }
140 }
141
142 nr_set_timer(sk);
143 }
144
145 void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
146 {
147 unsigned char *dptr;
148
149
150
151
152 dptr = skb_push(skb, NR_NETWORK_LEN);
153
154 memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
155 dptr[6] &= ~LAPB_C;
156 dptr[6] &= ~LAPB_E;
157 dptr[6] |= SSID_SPARE;
158 dptr += AX25_ADDR_LEN;
159
160 memcpy(dptr, &sk->nr->dest_addr, sizeof(ax25_address));
161 dptr[6] &= ~LAPB_C;
162 dptr[6] |= LAPB_E;
163 dptr[6] |= SSID_SPARE;
164 dptr += AX25_ADDR_LEN;
165
166 *dptr++ = nr_default.ttl;
167
168 skb->arp = 1;
169
170 if (!nr_route_frame(skb, NULL)) {
171 kfree_skb(skb, FREE_WRITE);
172
173 sk->state = TCP_CLOSE;
174 sk->err = ENETUNREACH;
175 if (!sk->dead)
176 sk->state_change(sk);
177 sk->dead = 1;
178 }
179 }
180
181
182
183
184
185
186 void nr_nr_error_recovery(struct sock *sk)
187 {
188 nr_establish_data_link(sk);
189 }
190
191 void nr_establish_data_link(struct sock *sk)
192 {
193 sk->nr->condition = 0x00;
194 sk->nr->n2count = 0;
195
196 nr_write_internal(sk, NR_CONNREQ);
197
198 sk->nr->t2timer = 0;
199 sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
200 }
201
202
203
204
205 void nr_enquiry_response(struct sock *sk)
206 {
207 int frametype = NR_INFOACK;
208
209 if (sk->nr->condition & OWN_RX_BUSY_CONDITION) {
210 frametype += NR_CHOKE_FLAG;
211 } else {
212 if (skb_peek(&sk->nr->reseq_queue) != NULL) {
213 frametype += NR_NAK_FLAG;
214 }
215 }
216
217 nr_write_internal(sk, frametype);
218
219 sk->nr->vl = sk->nr->vr;
220 sk->nr->condition &= ~ACK_PENDING_CONDITION;
221 }
222
223 void nr_check_iframes_acked(struct sock *sk, unsigned short nr)
224 {
225 if (sk->nr->vs == nr) {
226 nr_frames_acked(sk, nr);
227 nr_requeue_frames(sk);
228 nr_calculate_rtt(sk);
229 sk->nr->t1timer = 0;
230 sk->nr->n2count = 0;
231 } else {
232 if (sk->nr->va != nr) {
233 nr_frames_acked(sk, nr);
234 nr_requeue_frames(sk);
235 sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
236 }
237 }
238 }
239
240 #endif