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 {
114 if (!ax25->dama_slave)
115 ax25_kick(ax25);
116 }
117 }
118
119
120
121
122
123 static void ax25_send_iframe(ax25_cb *ax25, struct sk_buff *skb, int poll_bit)
124 {
125 unsigned char *frame;
126
127 if (skb == NULL)
128 return;
129
130 if (ax25->modulus == MODULUS) {
131 frame = skb_push(skb, 1);
132
133 *frame = I;
134 *frame |= (poll_bit) ? PF : 0;
135 *frame |= (ax25->vr << 5);
136 *frame |= (ax25->vs << 1);
137 } else {
138 frame = skb_push(skb, 2);
139
140 frame[0] = I;
141 frame[0] |= (ax25->vs << 1);
142 frame[1] = (poll_bit) ? EPF : 0;
143 frame[1] |= (ax25->vr << 1);
144 }
145
146 ax25_transmit_buffer(ax25, skb, C_COMMAND);
147 }
148
149 void ax25_kick(ax25_cb *ax25)
150 {
151 struct sk_buff *skb, *skbn;
152 int last = 1;
153 unsigned short start, end, next;
154
155 del_timer(&ax25->timer);
156
157 start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
158 end = (ax25->va + ax25->window) % ax25->modulus;
159
160 if (!(ax25->condition & PEER_RX_BUSY_CONDITION) &&
161 start != end &&
162 skb_peek(&ax25->write_queue) != NULL) {
163
164 ax25->vs = start;
165
166
167
168
169
170
171
172
173
174
175 skb = skb_dequeue(&ax25->write_queue);
176
177 do {
178 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
179 skb_queue_head(&ax25->write_queue, skb);
180 return;
181 }
182
183 next = (ax25->vs + 1) % ax25->modulus;
184 #ifdef notdef
185 last = (next == end) || skb_peek(&ax25->write_queue) == NULL;
186 #else
187 last = (next == end);
188 #endif
189
190
191
192
193
194 ax25_send_iframe(ax25, skbn, (last && !ax25->dama_slave) ? POLLON : POLLOFF);
195
196 ax25->vs = next;
197
198
199
200
201 skb_queue_tail(&ax25->ack_queue, skb);
202 #ifdef notdef
203 } while (!last);
204 #else
205 } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
206 #endif
207 ax25->condition &= ~ACK_PENDING_CONDITION;
208
209 if (ax25->t1timer == 0) {
210 ax25->t3timer = 0;
211 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
212 }
213 }
214
215 ax25_set_timer(ax25);
216 }
217
218 void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
219 {
220 unsigned char *ptr;
221
222 if (ax25->device == NULL) {
223 if (ax25->sk != NULL) {
224 ax25->sk->state = TCP_CLOSE;
225 ax25->sk->err = ENETUNREACH;
226 if (!ax25->sk->dead)
227 ax25->sk->state_change(ax25->sk);
228 ax25->sk->dead = 1;
229 }
230 return;
231 }
232
233 if (skb_headroom(skb) < size_ax25_addr(ax25->digipeat)) {
234 printk("ax25_transmit_buffer: not enough room for digi-peaters\n");
235 skb->free = 1;
236 kfree_skb(skb, FREE_WRITE);
237 return;
238 }
239
240 ptr = skb_push(skb, size_ax25_addr(ax25->digipeat));
241 build_ax25_addr(ptr, &ax25->source_addr, &ax25->dest_addr, ax25->digipeat, type, ax25->modulus);
242
243 skb->arp = 1;
244
245 ax25_queue_xmit(skb, ax25->device, SOPRI_NORMAL);
246 }
247
248
249
250
251
252
253 void ax25_nr_error_recovery(ax25_cb *ax25)
254 {
255 ax25_establish_data_link(ax25);
256 }
257
258 void ax25_establish_data_link(ax25_cb *ax25)
259 {
260 ax25->condition = 0x00;
261 ax25->n2count = 0;
262
263 if (ax25->modulus == MODULUS) {
264 ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
265 } else {
266 ax25_send_control(ax25, SABME, POLLON, C_COMMAND);
267 }
268
269 ax25->t3timer = 0;
270 ax25->t2timer = 0;
271 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
272 }
273
274 void ax25_transmit_enquiry(ax25_cb *ax25)
275 {
276 if (ax25->condition & OWN_RX_BUSY_CONDITION)
277 ax25_send_control(ax25, RNR, POLLON, C_COMMAND);
278 else
279 ax25_send_control(ax25, RR, POLLON, C_COMMAND);
280
281 ax25->condition &= ~ACK_PENDING_CONDITION;
282
283 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
284 }
285
286 void ax25_enquiry_response(ax25_cb *ax25)
287 {
288 if (ax25->condition & OWN_RX_BUSY_CONDITION)
289 ax25_send_control(ax25, RNR, POLLON, C_RESPONSE);
290 else
291 ax25_send_control(ax25, RR, POLLON, C_RESPONSE);
292
293 ax25->condition &= ~ACK_PENDING_CONDITION;
294 }
295
296 void ax25_timeout_response(ax25_cb *ax25)
297 {
298 if (ax25->condition & OWN_RX_BUSY_CONDITION)
299 ax25_send_control(ax25, RNR, POLLOFF, C_RESPONSE);
300 else
301 ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
302
303 ax25->condition &= ~ACK_PENDING_CONDITION;
304 }
305
306 void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
307 {
308 if (ax25->vs == nr) {
309 ax25_frames_acked(ax25, nr);
310 ax25_calculate_rtt(ax25);
311 ax25->t1timer = 0;
312 ax25->t3timer = ax25->t3;
313 } else {
314 if (ax25->va != nr) {
315 ax25_frames_acked(ax25, nr);
316 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
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 void dama_enquiry_response(ax25_cb * ax25)
333 {
334 ax25_cb * ax25o = NULL;
335
336 if (!(ax25->condition & PEER_RX_BUSY_CONDITION) )
337 {
338 ax25_requeue_frames(ax25);
339 ax25_kick(ax25);
340 }
341 if (ax25->state == AX25_STATE_1 ||
342 ax25->state == AX25_STATE_2 ||
343 skb_peek(&ax25->ack_queue) != NULL)
344 {
345 ax25_t1_timeout(ax25);
346
347 } else
348 ax25->n2count = 0;
349
350 ax25->t3timer = ax25->t3;
351
352
353
354
355
356
357
358
359 #if 0
360 if (ax25->condition & REJECT_CONDITION)
361 ax25_send_control(ax25, REJ, POLLOFF, C_RESPONSE);
362 else
363 #endif
364 ax25_enquiry_response(ax25);
365
366
367
368
369
370 for (ax25o=ax25_list; ax25o; ax25o=ax25o->next)
371 {
372 if (ax25o->device != ax25->device)
373 continue;
374
375 if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2)
376 {
377 ax25_t1_timeout(ax25o);
378 continue;
379 }
380
381 if ( !ax25o->dama_slave)
382 continue;
383
384 if ( !(ax25o->condition & PEER_RX_BUSY_CONDITION) &&
385 (ax25o->state == AX25_STATE_3 ||
386 (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0)) )
387 {
388 ax25_requeue_frames(ax25o);
389 ax25_kick(ax25o);
390 }
391
392 if (ax25o->state == AX25_STATE_1 ||
393 ax25o->state == AX25_STATE_2 ||
394 skb_peek(&ax25o->ack_queue) != NULL) ax25_t1_timeout(ax25o);
395
396 ax25o->t3timer = ax25o->t3;
397 }
398 }
399
400 void dama_check_need_response(ax25_cb *ax25, int type, int pf)
401 {
402 if (ax25->dama_slave && type == C_COMMAND && pf)
403 dama_enquiry_response(ax25);
404 }
405
406 void dama_establish_data_link(ax25_cb *ax25)
407 {
408 ax25->condition = 0x00;
409 ax25->n2count = 0;
410
411 ax25->t3timer = 0;
412 ax25->t2timer = 0;
413 ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
414 }
415
416 #endif