* better
[mascara-docs.git] / i386 / linux-2.3.21 / net / lapb / lapb_in.c
blob4e7a9ca4d2c5bcf16f64eaead188b2cfea56b105
1 /*
2 * LAPB release 002
4 * This code REQUIRES 2.1.15 or higher/ NET3.038
6 * This module:
7 * This module is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 * History
13 * LAPB 001 Jonathan Naulor Started Coding
14 * LAPB 002 Jonathan Naylor New timer architecture.
17 #include <linux/config.h>
18 #if defined(CONFIG_LAPB) || defined(CONFIG_LAPB_MODULE)
19 #include <linux/errno.h>
20 #include <linux/types.h>
21 #include <linux/socket.h>
22 #include <linux/in.h>
23 #include <linux/kernel.h>
24 #include <linux/sched.h>
25 #include <linux/timer.h>
26 #include <linux/string.h>
27 #include <linux/sockios.h>
28 #include <linux/net.h>
29 #include <linux/inet.h>
30 #include <linux/netdevice.h>
31 #include <linux/skbuff.h>
32 #include <net/sock.h>
33 #include <asm/uaccess.h>
34 #include <asm/system.h>
35 #include <linux/fcntl.h>
36 #include <linux/mm.h>
37 #include <linux/interrupt.h>
38 #include <net/lapb.h>
41 * State machine for state 0, Disconnected State.
42 * The handling of the timer(s) is in file lapb_timer.c.
44 static void lapb_state0_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
46 switch (frame->type) {
47 case LAPB_SABM:
48 #if LAPB_DEBUG > 1
49 printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)\n", lapb->token, frame->pf);
50 #endif
51 if (lapb->mode & LAPB_EXTENDED) {
52 #if LAPB_DEBUG > 1
53 printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", lapb->token, frame->pf);
54 #endif
55 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
56 } else {
57 #if LAPB_DEBUG > 1
58 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", lapb->token, frame->pf);
59 #endif
60 #if LAPB_DEBUG > 0
61 printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->token);
62 #endif
63 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
64 lapb_stop_t1timer(lapb);
65 lapb_stop_t2timer(lapb);
66 lapb->state = LAPB_STATE_3;
67 lapb->condition = 0x00;
68 lapb->n2count = 0;
69 lapb->vs = 0;
70 lapb->vr = 0;
71 lapb->va = 0;
72 lapb_connect_indication(lapb, LAPB_OK);
74 break;
76 case LAPB_SABME:
77 #if LAPB_DEBUG > 1
78 printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)\n", lapb->token, frame->pf);
79 #endif
80 if (lapb->mode & LAPB_EXTENDED) {
81 #if LAPB_DEBUG > 1
82 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", lapb->token, frame->pf);
83 #endif
84 #if LAPB_DEBUG > 0
85 printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->token);
86 #endif
87 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
88 lapb_stop_t1timer(lapb);
89 lapb_stop_t2timer(lapb);
90 lapb->state = LAPB_STATE_3;
91 lapb->condition = 0x00;
92 lapb->n2count = 0;
93 lapb->vs = 0;
94 lapb->vr = 0;
95 lapb->va = 0;
96 lapb_connect_indication(lapb, LAPB_OK);
97 } else {
98 #if LAPB_DEBUG > 1
99 printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", lapb->token, frame->pf);
100 #endif
101 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
103 break;
105 case LAPB_DISC:
106 #if LAPB_DEBUG > 1
107 printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)\n", lapb->token, frame->pf);
108 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", lapb->token, frame->pf);
109 #endif
110 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
111 break;
113 default:
114 break;
117 kfree_skb(skb);
121 * State machine for state 1, Awaiting Connection State.
122 * The handling of the timer(s) is in file lapb_timer.c.
124 static void lapb_state1_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
126 switch (frame->type) {
127 case LAPB_SABM:
128 #if LAPB_DEBUG > 1
129 printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)\n", lapb->token, frame->pf);
130 #endif
131 if (lapb->mode & LAPB_EXTENDED) {
132 #if LAPB_DEBUG > 1
133 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", lapb->token, frame->pf);
134 #endif
135 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
136 } else {
137 #if LAPB_DEBUG > 1
138 printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", lapb->token, frame->pf);
139 #endif
140 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
142 break;
144 case LAPB_SABME:
145 #if LAPB_DEBUG > 1
146 printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)\n", lapb->token, frame->pf);
147 #endif
148 if (lapb->mode & LAPB_EXTENDED) {
149 #if LAPB_DEBUG > 1
150 printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", lapb->token, frame->pf);
151 #endif
152 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
153 } else {
154 #if LAPB_DEBUG > 1
155 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", lapb->token, frame->pf);
156 #endif
157 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
159 break;
161 case LAPB_DISC:
162 #if LAPB_DEBUG > 1
163 printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)\n", lapb->token, frame->pf);
164 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", lapb->token, frame->pf);
165 #endif
166 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
167 break;
169 case LAPB_UA:
170 #if LAPB_DEBUG > 1
171 printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)\n", lapb->token, frame->pf);
172 #endif
173 if (frame->pf) {
174 #if LAPB_DEBUG > 0
175 printk(KERN_DEBUG "lapb: (%p) S1 -> S3\n", lapb->token);
176 #endif
177 lapb_stop_t1timer(lapb);
178 lapb_stop_t2timer(lapb);
179 lapb->state = LAPB_STATE_3;
180 lapb->condition = 0x00;
181 lapb->n2count = 0;
182 lapb->vs = 0;
183 lapb->vr = 0;
184 lapb->va = 0;
185 lapb_connect_confirmation(lapb, LAPB_OK);
187 break;
189 case LAPB_DM:
190 #if LAPB_DEBUG > 1
191 printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)\n", lapb->token, frame->pf);
192 #endif
193 if (frame->pf) {
194 #if LAPB_DEBUG > 0
195 printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->token);
196 #endif
197 lapb_clear_queues(lapb);
198 lapb->state = LAPB_STATE_0;
199 lapb_start_t1timer(lapb);
200 lapb_stop_t2timer(lapb);
201 lapb_disconnect_indication(lapb, LAPB_REFUSED);
203 break;
205 default:
206 break;
209 kfree_skb(skb);
213 * State machine for state 2, Awaiting Release State.
214 * The handling of the timer(s) is in file lapb_timer.c
216 static void lapb_state2_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
218 switch (frame->type) {
219 case LAPB_SABM:
220 case LAPB_SABME:
221 #if LAPB_DEBUG > 1
222 printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)\n", lapb->token, frame->pf);
223 printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)\n", lapb->token, frame->pf);
224 #endif
225 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
226 break;
228 case LAPB_DISC:
229 #if LAPB_DEBUG > 1
230 printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)\n", lapb->token, frame->pf);
231 printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)\n", lapb->token, frame->pf);
232 #endif
233 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
234 break;
236 case LAPB_UA:
237 #if LAPB_DEBUG > 1
238 printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)\n", lapb->token, frame->pf);
239 #endif
240 if (frame->pf) {
241 #if LAPB_DEBUG > 0
242 printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->token);
243 #endif
244 lapb->state = LAPB_STATE_0;
245 lapb_start_t1timer(lapb);
246 lapb_stop_t2timer(lapb);
247 lapb_disconnect_confirmation(lapb, LAPB_OK);
249 break;
251 case LAPB_DM:
252 #if LAPB_DEBUG > 1
253 printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", lapb->token, frame->pf);
254 #endif
255 if (frame->pf) {
256 #if LAPB_DEBUG > 0
257 printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->token);
258 #endif
259 lapb->state = LAPB_STATE_0;
260 lapb_start_t1timer(lapb);
261 lapb_stop_t2timer(lapb);
262 lapb_disconnect_confirmation(lapb, LAPB_NOTCONNECTED);
264 break;
266 case LAPB_I:
267 case LAPB_REJ:
268 case LAPB_RNR:
269 case LAPB_RR:
270 #if LAPB_DEBUG > 1
271 printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)\n", lapb->token, frame->pf);
272 printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", lapb->token, frame->pf);
273 #endif
274 if (frame->pf) lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
275 break;
277 default:
278 break;
281 kfree_skb(skb);
285 * State machine for state 3, Connected State.
286 * The handling of the timer(s) is in file lapb_timer.c
288 static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
290 int queued = 0;
291 int modulus;
293 modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
295 switch (frame->type) {
296 case LAPB_SABM:
297 #if LAPB_DEBUG > 1
298 printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)\n", lapb->token, frame->pf);
299 #endif
300 if (lapb->mode & LAPB_EXTENDED) {
301 #if LAPB_DEBUG > 1
302 printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", lapb->token, frame->pf);
303 #endif
304 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
305 } else {
306 #if LAPB_DEBUG > 1
307 printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", lapb->token, frame->pf);
308 #endif
309 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
310 lapb_stop_t1timer(lapb);
311 lapb_stop_t2timer(lapb);
312 lapb->condition = 0x00;
313 lapb->n2count = 0;
314 lapb->vs = 0;
315 lapb->vr = 0;
316 lapb->va = 0;
317 lapb_requeue_frames(lapb);
319 break;
321 case LAPB_SABME:
322 #if LAPB_DEBUG > 1
323 printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)\n", lapb->token, frame->pf);
324 #endif
325 if (lapb->mode & LAPB_EXTENDED) {
326 #if LAPB_DEBUG > 1
327 printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", lapb->token, frame->pf);
328 #endif
329 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
330 lapb_stop_t1timer(lapb);
331 lapb_stop_t2timer(lapb);
332 lapb->condition = 0x00;
333 lapb->n2count = 0;
334 lapb->vs = 0;
335 lapb->vr = 0;
336 lapb->va = 0;
337 lapb_requeue_frames(lapb);
338 } else {
339 #if LAPB_DEBUG > 1
340 printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", lapb->token, frame->pf);
341 #endif
342 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
344 break;
346 case LAPB_DISC:
347 #if LAPB_DEBUG > 1
348 printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)\n", lapb->token, frame->pf);
349 #endif
350 #if LAPB_DEBUG > 0
351 printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->token);
352 #endif
353 lapb_clear_queues(lapb);
354 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
355 lapb_start_t1timer(lapb);
356 lapb_stop_t2timer(lapb);
357 lapb->state = LAPB_STATE_0;
358 lapb_disconnect_indication(lapb, LAPB_OK);
359 break;
361 case LAPB_DM:
362 #if LAPB_DEBUG > 1
363 printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)\n", lapb->token, frame->pf);
364 #endif
365 #if LAPB_DEBUG > 0
366 printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->token);
367 #endif
368 lapb_clear_queues(lapb);
369 lapb->state = LAPB_STATE_0;
370 lapb_start_t1timer(lapb);
371 lapb_stop_t2timer(lapb);
372 lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
373 break;
375 case LAPB_RNR:
376 #if LAPB_DEBUG > 1
377 printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d\n", lapb->token, frame->pf, frame->nr);
378 #endif
379 lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
380 lapb_check_need_response(lapb, frame->cr, frame->pf);
381 if (lapb_validate_nr(lapb, frame->nr)) {
382 lapb_check_iframes_acked(lapb, frame->nr);
383 } else {
384 lapb->frmr_data = *frame;
385 lapb->frmr_type = LAPB_FRMR_Z;
386 lapb_transmit_frmr(lapb);
387 #if LAPB_DEBUG > 0
388 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
389 #endif
390 lapb_start_t1timer(lapb);
391 lapb_stop_t2timer(lapb);
392 lapb->state = LAPB_STATE_4;
393 lapb->n2count = 0;
395 break;
397 case LAPB_RR:
398 #if LAPB_DEBUG > 1
399 printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d\n", lapb->token, frame->pf, frame->nr);
400 #endif
401 lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
402 lapb_check_need_response(lapb, frame->cr, frame->pf);
403 if (lapb_validate_nr(lapb, frame->nr)) {
404 lapb_check_iframes_acked(lapb, frame->nr);
405 } else {
406 lapb->frmr_data = *frame;
407 lapb->frmr_type = LAPB_FRMR_Z;
408 lapb_transmit_frmr(lapb);
409 #if LAPB_DEBUG > 0
410 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
411 #endif
412 lapb_start_t1timer(lapb);
413 lapb_stop_t2timer(lapb);
414 lapb->state = LAPB_STATE_4;
415 lapb->n2count = 0;
417 break;
419 case LAPB_REJ:
420 #if LAPB_DEBUG > 1
421 printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d\n", lapb->token, frame->pf, frame->nr);
422 #endif
423 lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
424 lapb_check_need_response(lapb, frame->cr, frame->pf);
425 if (lapb_validate_nr(lapb, frame->nr)) {
426 lapb_frames_acked(lapb, frame->nr);
427 lapb_stop_t1timer(lapb);
428 lapb->n2count = 0;
429 lapb_requeue_frames(lapb);
430 } else {
431 lapb->frmr_data = *frame;
432 lapb->frmr_type = LAPB_FRMR_Z;
433 lapb_transmit_frmr(lapb);
434 #if LAPB_DEBUG > 0
435 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
436 #endif
437 lapb_start_t1timer(lapb);
438 lapb_stop_t2timer(lapb);
439 lapb->state = LAPB_STATE_4;
440 lapb->n2count = 0;
442 break;
444 case LAPB_I:
445 #if LAPB_DEBUG > 1
446 printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d\n", lapb->token, frame->pf, frame->ns, frame->nr);
447 #endif
448 if (!lapb_validate_nr(lapb, frame->nr)) {
449 lapb->frmr_data = *frame;
450 lapb->frmr_type = LAPB_FRMR_Z;
451 lapb_transmit_frmr(lapb);
452 #if LAPB_DEBUG > 0
453 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
454 #endif
455 lapb_start_t1timer(lapb);
456 lapb_stop_t2timer(lapb);
457 lapb->state = LAPB_STATE_4;
458 lapb->n2count = 0;
459 break;
461 if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) {
462 lapb_frames_acked(lapb, frame->nr);
463 } else {
464 lapb_check_iframes_acked(lapb, frame->nr);
466 if (frame->ns == lapb->vr) {
467 lapb->vr = (lapb->vr + 1) % modulus;
468 queued = lapb_data_indication(lapb, skb);
469 lapb->condition &= ~LAPB_REJECT_CONDITION;
470 if (frame->pf) {
471 lapb_enquiry_response(lapb);
472 } else {
473 if (!(lapb->condition & LAPB_ACK_PENDING_CONDITION)) {
474 lapb->condition |= LAPB_ACK_PENDING_CONDITION;
475 lapb_start_t2timer(lapb);
478 } else {
479 if (lapb->condition & LAPB_REJECT_CONDITION) {
480 if (frame->pf)
481 lapb_enquiry_response(lapb);
482 } else {
483 #if LAPB_DEBUG > 1
484 printk(KERN_DEBUG "lapb: (%p) S3 TX REJ(%d) R%d\n", lapb->token, frame->pf, lapb->vr);
485 #endif
486 lapb->condition |= LAPB_REJECT_CONDITION;
487 lapb_send_control(lapb, LAPB_REJ, frame->pf, LAPB_RESPONSE);
488 lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
491 break;
493 case LAPB_FRMR:
494 #if LAPB_DEBUG > 1
495 printk(KERN_DEBUG "lapb: (%p) S3 RX FRMR(%d) %02X %02X %02X %02X %02X\n", lapb->token, frame->pf, skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4]);
496 #endif
497 lapb_establish_data_link(lapb);
498 #if LAPB_DEBUG > 0
499 printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token);
500 #endif
501 lapb_requeue_frames(lapb);
502 lapb->state = LAPB_STATE_1;
503 break;
505 case LAPB_ILLEGAL:
506 #if LAPB_DEBUG > 1
507 printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)\n", lapb->token, frame->pf);
508 #endif
509 lapb->frmr_data = *frame;
510 lapb->frmr_type = LAPB_FRMR_W;
511 lapb_transmit_frmr(lapb);
512 #if LAPB_DEBUG > 0
513 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
514 #endif
515 lapb_start_t1timer(lapb);
516 lapb_stop_t2timer(lapb);
517 lapb->state = LAPB_STATE_4;
518 lapb->n2count = 0;
519 break;
521 default:
522 break;
525 if (!queued)
526 kfree_skb(skb);
530 * State machine for state 4, Frame Reject State.
531 * The handling of the timer(s) is in file lapb_timer.c.
533 static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
535 switch (frame->type) {
536 case LAPB_SABM:
537 #if LAPB_DEBUG > 1
538 printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n", lapb->token, frame->pf);
539 #endif
540 if (lapb->mode & LAPB_EXTENDED) {
541 #if LAPB_DEBUG > 1
542 printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, frame->pf);
543 #endif
544 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
545 } else {
546 #if LAPB_DEBUG > 1
547 printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, frame->pf);
548 #endif
549 #if LAPB_DEBUG > 0
550 printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
551 #endif
552 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
553 lapb_stop_t1timer(lapb);
554 lapb_stop_t2timer(lapb);
555 lapb->state = LAPB_STATE_3;
556 lapb->condition = 0x00;
557 lapb->n2count = 0;
558 lapb->vs = 0;
559 lapb->vr = 0;
560 lapb->va = 0;
561 lapb_connect_indication(lapb, LAPB_OK);
563 break;
565 case LAPB_SABME:
566 #if LAPB_DEBUG > 1
567 printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n", lapb->token, frame->pf);
568 #endif
569 if (lapb->mode & LAPB_EXTENDED) {
570 #if LAPB_DEBUG > 1
571 printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, frame->pf);
572 #endif
573 #if LAPB_DEBUG > 0
574 printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
575 #endif
576 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
577 lapb_stop_t1timer(lapb);
578 lapb_stop_t2timer(lapb);
579 lapb->state = LAPB_STATE_3;
580 lapb->condition = 0x00;
581 lapb->n2count = 0;
582 lapb->vs = 0;
583 lapb->vr = 0;
584 lapb->va = 0;
585 lapb_connect_indication(lapb, LAPB_OK);
586 } else {
587 #if LAPB_DEBUG > 1
588 printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, frame->pf);
589 #endif
590 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
592 break;
594 default:
595 break;
598 kfree_skb(skb);
602 * Process an incoming LAPB frame
604 void lapb_data_input(lapb_cb *lapb, struct sk_buff *skb)
606 struct lapb_frame frame;
608 lapb_decode(lapb, skb, &frame);
610 switch (lapb->state) {
611 case LAPB_STATE_0:
612 lapb_state0_machine(lapb, skb, &frame);
613 break;
614 case LAPB_STATE_1:
615 lapb_state1_machine(lapb, skb, &frame);
616 break;
617 case LAPB_STATE_2:
618 lapb_state2_machine(lapb, skb, &frame);
619 break;
620 case LAPB_STATE_3:
621 lapb_state3_machine(lapb, skb, &frame);
622 break;
623 case LAPB_STATE_4:
624 lapb_state4_machine(lapb, skb, &frame);
625 break;
628 lapb_kick(lapb);
631 #endif