~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/lapb/lapb_in.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      LAPB release 002
  3  *
  4  *      This code REQUIRES 2.1.15 or higher/ NET3.038
  5  *
  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.
 11  *
 12  *      History
 13  *      LAPB 001        Jonathan Naulor Started Coding
 14  *      LAPB 002        Jonathan Naylor New timer architecture.
 15  *      2000-10-29      Henner Eisen    lapb_data_indication() return status.
 16  */
 17 
 18 #include <linux/config.h>
 19 #if defined(CONFIG_LAPB) || defined(CONFIG_LAPB_MODULE)
 20 #include <linux/errno.h>
 21 #include <linux/types.h>
 22 #include <linux/socket.h>
 23 #include <linux/in.h>
 24 #include <linux/kernel.h>
 25 #include <linux/sched.h>
 26 #include <linux/timer.h>
 27 #include <linux/string.h>
 28 #include <linux/sockios.h>
 29 #include <linux/net.h>
 30 #include <linux/inet.h>
 31 #include <linux/netdevice.h>
 32 #include <linux/skbuff.h>
 33 #include <net/sock.h>
 34 #include <asm/uaccess.h>
 35 #include <asm/system.h>
 36 #include <linux/fcntl.h>
 37 #include <linux/mm.h>
 38 #include <linux/interrupt.h>
 39 #include <net/lapb.h>
 40 
 41 /*
 42  *      State machine for state 0, Disconnected State.
 43  *      The handling of the timer(s) is in file lapb_timer.c.
 44  */
 45 static void lapb_state0_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
 46 {
 47         switch (frame->type) {
 48                 case LAPB_SABM:
 49 #if LAPB_DEBUG > 1
 50                         printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)\n", lapb->token, frame->pf);
 51 #endif
 52                         if (lapb->mode & LAPB_EXTENDED) {
 53 #if LAPB_DEBUG > 1
 54                                 printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", lapb->token, frame->pf);
 55 #endif
 56                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
 57                         } else {
 58 #if LAPB_DEBUG > 1
 59                                 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", lapb->token, frame->pf);
 60 #endif
 61 #if LAPB_DEBUG > 0
 62                                 printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->token);
 63 #endif
 64                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 65                                 lapb_stop_t1timer(lapb);
 66                                 lapb_stop_t2timer(lapb);
 67                                 lapb->state     = LAPB_STATE_3;
 68                                 lapb->condition = 0x00;
 69                                 lapb->n2count   = 0;
 70                                 lapb->vs        = 0;
 71                                 lapb->vr        = 0;
 72                                 lapb->va        = 0;
 73                                 lapb_connect_indication(lapb, LAPB_OK);
 74                         }
 75                         break;
 76 
 77                 case LAPB_SABME:
 78 #if LAPB_DEBUG > 1
 79                         printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)\n", lapb->token, frame->pf);
 80 #endif
 81                         if (lapb->mode & LAPB_EXTENDED) {
 82 #if LAPB_DEBUG > 1
 83                                 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", lapb->token, frame->pf);
 84 #endif
 85 #if LAPB_DEBUG > 0
 86                                 printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n", lapb->token);
 87 #endif
 88                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
 89                                 lapb_stop_t1timer(lapb);
 90                                 lapb_stop_t2timer(lapb);
 91                                 lapb->state     = LAPB_STATE_3;
 92                                 lapb->condition = 0x00;
 93                                 lapb->n2count   = 0;
 94                                 lapb->vs        = 0;
 95                                 lapb->vr        = 0;
 96                                 lapb->va        = 0;
 97                                 lapb_connect_indication(lapb, LAPB_OK);
 98                         } else {
 99 #if LAPB_DEBUG > 1
100                                 printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n", lapb->token, frame->pf);
101 #endif
102                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
103                         }
104                         break;
105 
106                 case LAPB_DISC:
107 #if LAPB_DEBUG > 1
108                         printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)\n", lapb->token, frame->pf);
109                         printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n", lapb->token, frame->pf);
110 #endif
111                         lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
112                         break;
113 
114                 default:
115                         break;
116         }
117 
118         kfree_skb(skb);
119 }
120 
121 /*
122  *      State machine for state 1, Awaiting Connection State.
123  *      The handling of the timer(s) is in file lapb_timer.c.
124  */
125 static void lapb_state1_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
126 {
127         switch (frame->type) {
128                 case LAPB_SABM:
129 #if LAPB_DEBUG > 1
130                         printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)\n", lapb->token, frame->pf);
131 #endif
132                         if (lapb->mode & LAPB_EXTENDED) {
133 #if LAPB_DEBUG > 1
134                                 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", lapb->token, frame->pf);
135 #endif
136                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
137                         } else {
138 #if LAPB_DEBUG > 1
139                                 printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", lapb->token, frame->pf);
140 #endif
141                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
142                         }
143                         break;
144 
145                 case LAPB_SABME:
146 #if LAPB_DEBUG > 1
147                         printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)\n", lapb->token, frame->pf);
148 #endif
149                         if (lapb->mode & LAPB_EXTENDED) {
150 #if LAPB_DEBUG > 1
151                                 printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n", lapb->token, frame->pf);
152 #endif
153                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
154                         } else {
155 #if LAPB_DEBUG > 1
156                                 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", lapb->token, frame->pf);
157 #endif
158                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
159                         }
160                         break;
161 
162                 case LAPB_DISC:
163 #if LAPB_DEBUG > 1
164                         printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)\n", lapb->token, frame->pf);
165                         printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n", lapb->token, frame->pf);
166 #endif
167                         lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
168                         break;
169 
170                 case LAPB_UA:
171 #if LAPB_DEBUG > 1
172                         printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)\n", lapb->token, frame->pf);
173 #endif
174                         if (frame->pf) {
175 #if LAPB_DEBUG > 0
176                                 printk(KERN_DEBUG "lapb: (%p) S1 -> S3\n", lapb->token);
177 #endif
178                                 lapb_stop_t1timer(lapb);
179                                 lapb_stop_t2timer(lapb);
180                                 lapb->state     = LAPB_STATE_3;
181                                 lapb->condition = 0x00;
182                                 lapb->n2count   = 0;
183                                 lapb->vs        = 0;
184                                 lapb->vr        = 0;
185                                 lapb->va        = 0;
186                                 lapb_connect_confirmation(lapb, LAPB_OK);
187                         }
188                         break;
189 
190                 case LAPB_DM:
191 #if LAPB_DEBUG > 1
192                         printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)\n", lapb->token, frame->pf);
193 #endif
194                         if (frame->pf) {
195 #if LAPB_DEBUG > 0
196                                 printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n", lapb->token);
197 #endif
198                                 lapb_clear_queues(lapb);
199                                 lapb->state = LAPB_STATE_0;
200                                 lapb_start_t1timer(lapb);
201                                 lapb_stop_t2timer(lapb);
202                                 lapb_disconnect_indication(lapb, LAPB_REFUSED);
203                         }
204                         break;
205 
206                 default:
207                         break;
208         }
209 
210         kfree_skb(skb);
211 }
212 
213 /*
214  *      State machine for state 2, Awaiting Release State.
215  *      The handling of the timer(s) is in file lapb_timer.c
216  */
217 static void lapb_state2_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
218 {
219         switch (frame->type) {
220                 case LAPB_SABM:
221                 case LAPB_SABME:
222 #if LAPB_DEBUG > 1
223                         printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)\n", lapb->token, frame->pf);
224                         printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)\n", lapb->token, frame->pf);
225 #endif
226                         lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
227                         break;
228 
229                 case LAPB_DISC:
230 #if LAPB_DEBUG > 1
231                         printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)\n", lapb->token, frame->pf);
232                         printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)\n", lapb->token, frame->pf);
233 #endif
234                         lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
235                         break;
236 
237                 case LAPB_UA:
238 #if LAPB_DEBUG > 1
239                         printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)\n", lapb->token, frame->pf);
240 #endif
241                         if (frame->pf) {
242 #if LAPB_DEBUG > 0
243                                 printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->token);
244 #endif
245                                 lapb->state = LAPB_STATE_0;
246                                 lapb_start_t1timer(lapb);
247                                 lapb_stop_t2timer(lapb);
248                                 lapb_disconnect_confirmation(lapb, LAPB_OK);
249                         }
250                         break;
251 
252                 case LAPB_DM:
253 #if LAPB_DEBUG > 1
254                         printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", lapb->token, frame->pf);
255 #endif
256                         if (frame->pf) {
257 #if LAPB_DEBUG > 0
258                                 printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n", lapb->token);
259 #endif
260                                 lapb->state = LAPB_STATE_0;
261                                 lapb_start_t1timer(lapb);
262                                 lapb_stop_t2timer(lapb);
263                                 lapb_disconnect_confirmation(lapb, LAPB_NOTCONNECTED);
264                         }
265                         break;
266 
267                 case LAPB_I:
268                 case LAPB_REJ:
269                 case LAPB_RNR:
270                 case LAPB_RR:
271 #if LAPB_DEBUG > 1
272                         printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)\n", lapb->token, frame->pf);
273                         printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n", lapb->token, frame->pf);
274 #endif
275                         if (frame->pf) lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
276                         break;
277                                 
278                 default:
279                         break;
280         }
281 
282         kfree_skb(skb);
283 }
284 
285 /*
286  *      State machine for state 3, Connected State.
287  *      The handling of the timer(s) is in file lapb_timer.c
288  */
289 static void lapb_state3_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
290 {
291         int queued = 0;
292         int modulus;
293         
294         modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
295 
296         switch (frame->type) {
297                 case LAPB_SABM:
298 #if LAPB_DEBUG > 1
299                         printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)\n", lapb->token, frame->pf);
300 #endif
301                         if (lapb->mode & LAPB_EXTENDED) {
302 #if LAPB_DEBUG > 1
303                                 printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", lapb->token, frame->pf);
304 #endif
305                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
306                         } else {
307 #if LAPB_DEBUG > 1
308                                 printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", lapb->token, frame->pf);
309 #endif
310                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
311                                 lapb_stop_t1timer(lapb);
312                                 lapb_stop_t2timer(lapb);
313                                 lapb->condition = 0x00;
314                                 lapb->n2count   = 0;
315                                 lapb->vs        = 0;
316                                 lapb->vr        = 0;
317                                 lapb->va        = 0;
318                                 lapb_requeue_frames(lapb);
319                         }
320                         break;
321 
322                 case LAPB_SABME:
323 #if LAPB_DEBUG > 1
324                         printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)\n", lapb->token, frame->pf);
325 #endif
326                         if (lapb->mode & LAPB_EXTENDED) {
327 #if LAPB_DEBUG > 1
328                                 printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n", lapb->token, frame->pf);
329 #endif
330                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
331                                 lapb_stop_t1timer(lapb);
332                                 lapb_stop_t2timer(lapb);
333                                 lapb->condition = 0x00;
334                                 lapb->n2count   = 0;
335                                 lapb->vs        = 0;
336                                 lapb->vr        = 0;
337                                 lapb->va        = 0;
338                                 lapb_requeue_frames(lapb);
339                         } else {
340 #if LAPB_DEBUG > 1
341                                 printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n", lapb->token, frame->pf);
342 #endif
343                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
344                         }
345                         break;
346 
347                 case LAPB_DISC:
348 #if LAPB_DEBUG > 1
349                         printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)\n", lapb->token, frame->pf);
350 #endif
351 #if LAPB_DEBUG > 0
352                         printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->token);
353 #endif
354                         lapb_clear_queues(lapb);
355                         lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
356                         lapb_start_t1timer(lapb);
357                         lapb_stop_t2timer(lapb);
358                         lapb->state = LAPB_STATE_0;
359                         lapb_disconnect_indication(lapb, LAPB_OK);
360                         break;
361 
362                 case LAPB_DM:
363 #if LAPB_DEBUG > 1
364                         printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)\n", lapb->token, frame->pf);
365 #endif
366 #if LAPB_DEBUG > 0
367                         printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->token);
368 #endif
369                         lapb_clear_queues(lapb);
370                         lapb->state = LAPB_STATE_0;
371                         lapb_start_t1timer(lapb);
372                         lapb_stop_t2timer(lapb);
373                         lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
374                         break;
375 
376                 case LAPB_RNR:
377 #if LAPB_DEBUG > 1
378                         printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d\n", lapb->token, frame->pf, frame->nr);
379 #endif
380                         lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
381                         lapb_check_need_response(lapb, frame->cr, frame->pf);
382                         if (lapb_validate_nr(lapb, frame->nr)) {
383                                 lapb_check_iframes_acked(lapb, frame->nr);
384                         } else {
385                                 lapb->frmr_data = *frame;
386                                 lapb->frmr_type = LAPB_FRMR_Z;
387                                 lapb_transmit_frmr(lapb);
388 #if LAPB_DEBUG > 0
389                                 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
390 #endif
391                                 lapb_start_t1timer(lapb);
392                                 lapb_stop_t2timer(lapb);
393                                 lapb->state   = LAPB_STATE_4;
394                                 lapb->n2count = 0;
395                         }
396                         break;
397 
398                 case LAPB_RR:
399 #if LAPB_DEBUG > 1
400                         printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d\n", lapb->token, frame->pf, frame->nr);
401 #endif
402                         lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
403                         lapb_check_need_response(lapb, frame->cr, frame->pf);
404                         if (lapb_validate_nr(lapb, frame->nr)) {
405                                 lapb_check_iframes_acked(lapb, frame->nr);
406                         } else {
407                                 lapb->frmr_data = *frame;
408                                 lapb->frmr_type = LAPB_FRMR_Z;
409                                 lapb_transmit_frmr(lapb);
410 #if LAPB_DEBUG > 0
411                                 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
412 #endif
413                                 lapb_start_t1timer(lapb);
414                                 lapb_stop_t2timer(lapb);
415                                 lapb->state   = LAPB_STATE_4;
416                                 lapb->n2count = 0;
417                         }
418                         break;
419 
420                 case LAPB_REJ:
421 #if LAPB_DEBUG > 1
422                         printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d\n", lapb->token, frame->pf, frame->nr);
423 #endif
424                         lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
425                         lapb_check_need_response(lapb, frame->cr, frame->pf);
426                         if (lapb_validate_nr(lapb, frame->nr)) {
427                                 lapb_frames_acked(lapb, frame->nr);
428                                 lapb_stop_t1timer(lapb);
429                                 lapb->n2count = 0;
430                                 lapb_requeue_frames(lapb);
431                         } else {
432                                 lapb->frmr_data = *frame;
433                                 lapb->frmr_type = LAPB_FRMR_Z;
434                                 lapb_transmit_frmr(lapb);
435 #if LAPB_DEBUG > 0
436                                 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
437 #endif
438                                 lapb_start_t1timer(lapb);
439                                 lapb_stop_t2timer(lapb);
440                                 lapb->state   = LAPB_STATE_4;
441                                 lapb->n2count = 0;
442                         }
443                         break;
444 
445                 case LAPB_I:
446 #if LAPB_DEBUG > 1
447                         printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d\n", lapb->token, frame->pf, frame->ns, frame->nr);
448 #endif
449                         if (!lapb_validate_nr(lapb, frame->nr)) {
450                                 lapb->frmr_data = *frame;
451                                 lapb->frmr_type = LAPB_FRMR_Z;
452                                 lapb_transmit_frmr(lapb);
453 #if LAPB_DEBUG > 0
454                                 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
455 #endif
456                                 lapb_start_t1timer(lapb);
457                                 lapb_stop_t2timer(lapb);
458                                 lapb->state   = LAPB_STATE_4;
459                                 lapb->n2count = 0;
460                                 break;
461                         }
462                         if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) {
463                                 lapb_frames_acked(lapb, frame->nr);
464                         } else {
465                                 lapb_check_iframes_acked(lapb, frame->nr);
466                         }
467                         if (frame->ns == lapb->vr) {
468                                 int cn;
469                                 cn = lapb_data_indication(lapb, skb);
470                                 queued = 1;
471                                 /*
472                                  * If upper layer has dropped the frame, we
473                                  * basically ignore any further protocol
474                                  * processing. This will cause the peer
475                                  * to re-transmit the frame later like
476                                  * a frame lost on the wire.
477                                  */
478                                 if(cn == NET_RX_DROP){
479                                         printk(KERN_DEBUG "LAPB: rx congestion\n");
480                                         break;
481                                 }
482                                 lapb->vr = (lapb->vr + 1) % modulus;
483                                 lapb->condition &= ~LAPB_REJECT_CONDITION;
484                                 if (frame->pf) {
485                                         lapb_enquiry_response(lapb);
486                                 } else {
487                                         if (!(lapb->condition & LAPB_ACK_PENDING_CONDITION)) {
488                                                 lapb->condition |= LAPB_ACK_PENDING_CONDITION;
489                                                 lapb_start_t2timer(lapb);
490                                         }
491                                 }
492                         } else {
493                                 if (lapb->condition & LAPB_REJECT_CONDITION) {
494                                         if (frame->pf)
495                                                 lapb_enquiry_response(lapb);
496                                 } else {
497 #if LAPB_DEBUG > 1
498                                         printk(KERN_DEBUG "lapb: (%p) S3 TX REJ(%d) R%d\n", lapb->token, frame->pf, lapb->vr);
499 #endif
500                                         lapb->condition |= LAPB_REJECT_CONDITION;
501                                         lapb_send_control(lapb, LAPB_REJ, frame->pf, LAPB_RESPONSE);
502                                         lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
503                                 }
504                         }
505                         break;
506 
507                 case LAPB_FRMR:
508 #if LAPB_DEBUG > 1
509                         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]);
510 #endif
511                         lapb_establish_data_link(lapb);
512 #if LAPB_DEBUG > 0
513                         printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token);
514 #endif
515                         lapb_requeue_frames(lapb);
516                         lapb->state = LAPB_STATE_1;
517                         break;
518 
519                 case LAPB_ILLEGAL:
520 #if LAPB_DEBUG > 1
521                         printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)\n", lapb->token, frame->pf);
522 #endif
523                         lapb->frmr_data = *frame;
524                         lapb->frmr_type = LAPB_FRMR_W;
525                         lapb_transmit_frmr(lapb);
526 #if LAPB_DEBUG > 0
527                         printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
528 #endif
529                         lapb_start_t1timer(lapb);
530                         lapb_stop_t2timer(lapb);
531                         lapb->state   = LAPB_STATE_4;
532                         lapb->n2count = 0;
533                         break;
534 
535                 default:
536                         break;
537         }
538 
539         if (!queued)
540                 kfree_skb(skb);
541 }
542 
543 /*
544  *      State machine for state 4, Frame Reject State.
545  *      The handling of the timer(s) is in file lapb_timer.c.
546  */
547 static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
548 {
549         switch (frame->type) {
550                 case LAPB_SABM:
551 #if LAPB_DEBUG > 1
552                         printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n", lapb->token, frame->pf);
553 #endif
554                         if (lapb->mode & LAPB_EXTENDED) {
555 #if LAPB_DEBUG > 1
556                                 printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, frame->pf);
557 #endif
558                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
559                         } else {
560 #if LAPB_DEBUG > 1
561                                 printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, frame->pf);
562 #endif
563 #if LAPB_DEBUG > 0
564                                 printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
565 #endif
566                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
567                                 lapb_stop_t1timer(lapb);
568                                 lapb_stop_t2timer(lapb);
569                                 lapb->state     = LAPB_STATE_3;
570                                 lapb->condition = 0x00;
571                                 lapb->n2count   = 0;
572                                 lapb->vs        = 0;
573                                 lapb->vr        = 0;
574                                 lapb->va        = 0;
575                                 lapb_connect_indication(lapb, LAPB_OK);
576                         }
577                         break;
578 
579                 case LAPB_SABME:
580 #if LAPB_DEBUG > 1
581                         printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n", lapb->token, frame->pf);
582 #endif
583                         if (lapb->mode & LAPB_EXTENDED) {
584 #if LAPB_DEBUG > 1
585                                 printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, frame->pf);
586 #endif
587 #if LAPB_DEBUG > 0
588                                 printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
589 #endif
590                                 lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
591                                 lapb_stop_t1timer(lapb);
592                                 lapb_stop_t2timer(lapb);
593                                 lapb->state     = LAPB_STATE_3;
594                                 lapb->condition = 0x00;
595                                 lapb->n2count   = 0;
596                                 lapb->vs        = 0;
597                                 lapb->vr        = 0;
598                                 lapb->va        = 0;
599                                 lapb_connect_indication(lapb, LAPB_OK);
600                         } else {
601 #if LAPB_DEBUG > 1
602                                 printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, frame->pf);
603 #endif
604                                 lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
605                         }
606                         break;
607 
608                 default:
609                         break;
610         }
611 
612         kfree_skb(skb);
613 }
614 
615 /*
616  *      Process an incoming LAPB frame
617  */
618 void lapb_data_input(lapb_cb *lapb, struct sk_buff *skb)
619 {
620         struct lapb_frame frame;
621 
622         lapb_decode(lapb, skb, &frame);
623 
624         switch (lapb->state) {
625                 case LAPB_STATE_0:
626                         lapb_state0_machine(lapb, skb, &frame);
627                         break;
628                 case LAPB_STATE_1:
629                         lapb_state1_machine(lapb, skb, &frame);
630                         break;
631                 case LAPB_STATE_2:
632                         lapb_state2_machine(lapb, skb, &frame);
633                         break;
634                 case LAPB_STATE_3:
635                         lapb_state3_machine(lapb, skb, &frame);
636                         break;
637                 case LAPB_STATE_4:
638                         lapb_state4_machine(lapb, skb, &frame);
639                         break;
640         }
641 
642         lapb_kick(lapb);
643 }
644 
645 #endif
646 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.