This source file includes following definitions.
- ax25_output
- ax25_send_iframe
- ax25_kick
- ax25_transmit_buffer
- ax25_nr_error_recovery
- ax25_establish_data_link
- ax25_transmit_enquiry
- ax25_enquiry_response
- ax25_timeout_response
- ax25_check_iframes_acked
- ax25_check_need_response
- dama_enquiry_response
- dama_check_need_response
- dama_establish_data_link
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/config.h>
31 #ifdef CONFIG_AX25
32 #include <linux/errno.h>
33 #include <linux/types.h>
34 #include <linux/socket.h>
35 #include <linux/in.h>
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/timer.h>
39 #include <linux/string.h>
40 #include <linux/sockios.h>
41 #include <linux/net.h>
42 #include <net/ax25.h>
43 #include <linux/inet.h>
44 #include <linux/netdevice.h>
45 #include <linux/skbuff.h>
46 #include <net/sock.h>
47 #include <asm/segment.h>
48 #include <asm/system.h>
49 #include <linux/fcntl.h>
50 #include <linux/mm.h>
51 #include <linux/interrupt.h>
52
53
54
55
56
57 void ax25_output(ax25_cb *ax25, struct sk_buff *skb)
58 {
59 struct sk_buff *skbn;
60 unsigned char *p;
61 int err, frontlen, mtu, len, fragno, first = 1;
62
63 mtu = ax25->device->mtu;
64
65 if ((skb->len - 1) > mtu) {
66 mtu -= 2;
67
68 fragno = skb->len / mtu;
69 if (skb->len % mtu == 0) fragno--;
70
71 frontlen = skb_headroom(skb);
72
73 while (skb->len > 0) {
74 if (skb->sk != NULL) {
75 if ((skbn = sock_alloc_send_skb(skb->sk, mtu + 2 + frontlen, 0, 0, &err)) == NULL)
76 return;
77 } else {
78 if ((skbn = alloc_skb(mtu + 2 + frontlen, GFP_ATOMIC)) == NULL)
79 return;
80 }
81
82 skbn->sk = skb->sk;
83 skbn->free = 1;
84 skbn->arp = 1;
85
86 skb_reserve(skbn, frontlen + 2);
87
88 len = (mtu > skb->len) ? skb->len : mtu;
89
90 memcpy(skb_put(skbn, len), skb->data, len);
91 skb_pull(skb, len);
92
93 p = skb_push(skbn, 2);
94
95 *p++ = AX25_P_SEGMENT;
96
97 *p = fragno--;
98 if (first) {
99 *p |= SEG_FIRST;
100 first = 0;
101 }
102
103 skb_queue_tail(&ax25->write_queue, skbn);
104 }
105
106 skb->free = 1;
107 kfree_skb(skb, FREE_WRITE);
108 } else {
109 skb_queue_tail(&ax25->write_queue, skb);
110 }
111
112 if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
113 if (!ax25->dama_slave)
114 ax25_kick(ax25);
115 }
116 }
117
118
119
120
121
122 static void ax25_send_iframe(ax25_cb *ax25, struct sk_buff *skb, int poll_bit)
123 {
124 unsigned char *frame;
125
126 if (skb == NULL)
127 return;
128
129 if (ax25->modulus == MODULUS) {
130 frame = skb_push(skb, 1);
131
132 *frame = I;
133 *frame |= (poll_bit) ? PF : 0;
134 *frame |= (ax25->vr << 5);
135 *frame |= (ax25->vs << 1);
136 } else {
137 frame = skb_push(skb, 2);
138
139 frame[0] = I;
140 frame[0] |= (ax25->vs << 1);
141 frame[1] = (poll_bit) ? EPF : 0;
142 frame[1] |= (ax25->vr << 1);
143 }
144
145 ax25_transmit_buffer(ax25, skb, C_COMMAND);
146 }
147
148 void ax25_kick(ax25_cb *ax25)
149 {
150 struct sk_buff *skb, *skbn;
151 int last = 1;
152 unsigned short start, end, next;
153
154 del_timer(&ax25->timer);
155
156 start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
157 end = (ax25->va + ax25->window) % ax25->modulus;
158
159 if (!(ax25->condition & PEER_RX_BUSY_CONDITION) &&
160 start != end &&
161 skb_peek(&ax25->write_queue) != NULL) {
162
163 ax25->vs = start;
164
165
166
167
168
169
170
171
172
173
174 skb = skb_dequeue(&ax25->write_queue);
175
176 do {
177 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
178 skb_queue_head(&ax25->write_queue, skb);
179 return;
180 }
181
182 next = (ax25->vs + 1) % ax25->modulus;
183 #ifdef notdef
184 last = (next == end) || skb_peek(&ax25->write_queue) == NULL;
185 #else
186 last = (next == end);
187 #endif
188
189
190
191
192
193 ax25_send_iframe(ax25, skbn, (last && !ax25->dama_slave) ? POLLON : POLLOFF);
194
195 ax25->vs = next;
196
197
198
199
200 skb_queue_tail(&ax25->ack_queue, skb);
201 #ifdef notdef
202 } while (!last);
203 #else
204 } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
205 #endif
206 ax25->condition &= ~ACK_PENDING_CONDITION;
207
208 if (ax25->t1timer == 0) {
209 ax25->t3timer = 0;
210 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
211 }
212 }
213
214 ax25_set_timer(ax25);
215 }
216
217 void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
218 {
219 unsigned char *ptr;
220
221 if (ax25->device == NULL) {
222 if (ax25->sk != NULL) {
223 ax25->sk->state = TCP_CLOSE;
224 ax25->sk->err = ENETUNREACH;
225 if (!ax25->sk->dead)
226 ax25->sk->state_change(ax25->sk);
227 ax25->sk->dead = 1;
228 }
229 return;
230 }
231
232 if (skb_headroom(skb) < size_ax25_addr(ax25->digipeat)) {
233 printk("ax25_transmit_buffer: not enough room for digi-peaters\n");
234 skb->free = 1;
235 kfree_skb(skb, FREE_WRITE);
236 return;
237 }
238
239 ptr = skb_push(skb, size_ax25_addr(ax25->digipeat));
240 build_ax25_addr(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
241
242 skb->arp = 1;
243
244 ax25_queue_xmit(skb, ax25->device, SOPRI_NORMAL);
245 }
246
247
248
249
250
251
252 void ax25_nr_error_recovery(ax25_cb *ax25)
253 {
254 ax25_establish_data_link(ax25);
255 }
256
257 void ax25_establish_data_link(ax25_cb *ax25)
258 {
259 ax25->condition = 0x00;
260 ax25->n2count = 0;
261
262 if (ax25->modulus == MODULUS) {
263 ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
264 } else {
265 ax25_send_control(ax25, SABME, POLLON, C_COMMAND);
266 }
267
268 ax25->t3timer = 0;
269 ax25->t2timer = 0;
270 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
271 }
272
273 void ax25_transmit_enquiry(ax25_cb *ax25)
274 {
275 if (ax25->condition & OWN_RX_BUSY_CONDITION)
276 ax25_send_control(ax25, RNR, POLLON, C_COMMAND);
277 else
278 ax25_send_control(ax25, RR, POLLON, C_COMMAND);
279
280 ax25->condition &= ~ACK_PENDING_CONDITION;
281
282 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
283 }
284
285 void ax25_enquiry_response(ax25_cb *ax25)
286 {
287 if (ax25->condition & OWN_RX_BUSY_CONDITION)
288 ax25_send_control(ax25, RNR, POLLON, C_RESPONSE);
289 else
290 ax25_send_control(ax25, RR, POLLON, C_RESPONSE);
291
292 ax25->condition &= ~ACK_PENDING_CONDITION;
293 }
294
295 void ax25_timeout_response(ax25_cb *ax25)
296 {
297 if (ax25->condition & OWN_RX_BUSY_CONDITION)
298 ax25_send_control(ax25, RNR, POLLOFF, C_RESPONSE);
299 else
300 ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
301
302 ax25->condition &= ~ACK_PENDING_CONDITION;
303 }
304
305 void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
306 {
307 if (ax25->vs == nr) {
308 ax25_frames_acked(ax25, nr);
309 ax25_calculate_rtt(ax25);
310 ax25->t1timer = 0;
311 ax25->t3timer = ax25->t3;
312 } else {
313 if (ax25->va != nr) {
314 ax25_frames_acked(ax25, nr);
315 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
316 }
317 }
318 }
319
320
321
322
323
324 void ax25_check_need_response(ax25_cb *ax25, int type, int pf)
325 {
326 if (!ax25->dama_slave && type == C_COMMAND && pf)
327 ax25_enquiry_response(ax25);
328 }
329
330
331
332
333 void dama_enquiry_response(ax25_cb *ax25)
334 {
335 ax25_cb *ax25o;
336
337 if (!(ax25->condition & PEER_RX_BUSY_CONDITION)) {
338 ax25_requeue_frames(ax25);
339 ax25_kick(ax25);
340 }
341
342 if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 ||
343 skb_peek(&ax25->ack_queue) != NULL) {
344 ax25_t1_timeout(ax25);
345 } else {
346 ax25->n2count = 0;
347 }
348
349 ax25->t3timer = ax25->t3;
350
351
352
353
354
355
356
357
358 #if 0
359 if (ax25->condition & REJECT_CONDITION)
360 ax25_send_control(ax25, REJ, POLLOFF, C_RESPONSE);
361 else
362 #endif
363 ax25_enquiry_response(ax25);
364
365
366
367
368
369 for (ax25o = ax25_list; ax25o != NULL; ax25o = ax25o->next) {
370 if (ax25o->device != ax25->device)
371 continue;
372
373 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
374 ax25_t1_timeout(ax25o);
375 continue;
376 }
377
378 if (!ax25o->dama_slave)
379 continue;
380
381 if ( !(ax25o->condition & PEER_RX_BUSY_CONDITION) &&
382 (ax25o->state == AX25_STATE_3 ||
383 (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0))) {
384 ax25_requeue_frames(ax25o);
385 ax25_kick(ax25o);
386 }
387
388 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 ||
389 skb_peek(&ax25o->ack_queue) != NULL) {
390 ax25_t1_timeout(ax25o);
391 }
392
393 ax25o->t3timer = ax25o->t3;
394 }
395 }
396
397 void dama_check_need_response(ax25_cb *ax25, int type, int pf)
398 {
399 if (ax25->dama_slave && type == C_COMMAND && pf)
400 dama_enquiry_response(ax25);
401 }
402
403 void dama_establish_data_link(ax25_cb *ax25)
404 {
405 ax25->condition = 0x00;
406 ax25->n2count = 0;
407
408 ax25->t3timer = 0;
409 ax25->t2timer = 0;
410 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
411 }
412
413 #endif