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