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