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#include <linux/string.h>
29#include <linux/kernel.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/slab.h>
33
34#include <net/irda/irda.h>
35#include <net/irda/irlap_event.h>
36
37#include <net/irda/timer.h>
38#include <net/irda/irlap.h>
39#include <net/irda/irlap_frame.h>
40#include <net/irda/qos.h>
41#include <net/irda/parameters.h>
42#include <net/irda/irlmp.h>
43
44#include <net/irda/irda_device.h>
45
46#ifdef CONFIG_IRDA_FAST_RR
47int sysctl_fast_poll_increase = 50;
48#endif
49
50static int irlap_state_ndm (struct irlap_cb *self, IRLAP_EVENT event,
51 struct sk_buff *skb, struct irlap_info *info);
52static int irlap_state_query (struct irlap_cb *self, IRLAP_EVENT event,
53 struct sk_buff *skb, struct irlap_info *info);
54static int irlap_state_reply (struct irlap_cb *self, IRLAP_EVENT event,
55 struct sk_buff *skb, struct irlap_info *info);
56static int irlap_state_conn (struct irlap_cb *self, IRLAP_EVENT event,
57 struct sk_buff *skb, struct irlap_info *info);
58static int irlap_state_setup (struct irlap_cb *self, IRLAP_EVENT event,
59 struct sk_buff *skb, struct irlap_info *info);
60static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event,
61 struct sk_buff *skb, struct irlap_info *info);
62static int irlap_state_xmit_p (struct irlap_cb *self, IRLAP_EVENT event,
63 struct sk_buff *skb, struct irlap_info *info);
64static int irlap_state_pclose (struct irlap_cb *self, IRLAP_EVENT event,
65 struct sk_buff *skb, struct irlap_info *info);
66static int irlap_state_nrm_p (struct irlap_cb *self, IRLAP_EVENT event,
67 struct sk_buff *skb, struct irlap_info *info);
68static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
69 struct sk_buff *skb, struct irlap_info *info);
70static int irlap_state_reset (struct irlap_cb *self, IRLAP_EVENT event,
71 struct sk_buff *skb, struct irlap_info *info);
72static int irlap_state_nrm_s (struct irlap_cb *self, IRLAP_EVENT event,
73 struct sk_buff *skb, struct irlap_info *info);
74static int irlap_state_xmit_s (struct irlap_cb *self, IRLAP_EVENT event,
75 struct sk_buff *skb, struct irlap_info *info);
76static int irlap_state_sclose (struct irlap_cb *self, IRLAP_EVENT event,
77 struct sk_buff *skb, struct irlap_info *info);
78static int irlap_state_reset_check(struct irlap_cb *, IRLAP_EVENT event,
79 struct sk_buff *, struct irlap_info *);
80
81#ifdef CONFIG_IRDA_DEBUG
82static const char *const irlap_event[] = {
83 "DISCOVERY_REQUEST",
84 "CONNECT_REQUEST",
85 "CONNECT_RESPONSE",
86 "DISCONNECT_REQUEST",
87 "DATA_REQUEST",
88 "RESET_REQUEST",
89 "RESET_RESPONSE",
90 "SEND_I_CMD",
91 "SEND_UI_FRAME",
92 "RECV_DISCOVERY_XID_CMD",
93 "RECV_DISCOVERY_XID_RSP",
94 "RECV_SNRM_CMD",
95 "RECV_TEST_CMD",
96 "RECV_TEST_RSP",
97 "RECV_UA_RSP",
98 "RECV_DM_RSP",
99 "RECV_RD_RSP",
100 "RECV_I_CMD",
101 "RECV_I_RSP",
102 "RECV_UI_FRAME",
103 "RECV_FRMR_RSP",
104 "RECV_RR_CMD",
105 "RECV_RR_RSP",
106 "RECV_RNR_CMD",
107 "RECV_RNR_RSP",
108 "RECV_REJ_CMD",
109 "RECV_REJ_RSP",
110 "RECV_SREJ_CMD",
111 "RECV_SREJ_RSP",
112 "RECV_DISC_CMD",
113 "SLOT_TIMER_EXPIRED",
114 "QUERY_TIMER_EXPIRED",
115 "FINAL_TIMER_EXPIRED",
116 "POLL_TIMER_EXPIRED",
117 "DISCOVERY_TIMER_EXPIRED",
118 "WD_TIMER_EXPIRED",
119 "BACKOFF_TIMER_EXPIRED",
120 "MEDIA_BUSY_TIMER_EXPIRED",
121};
122#endif
123
124const char *const irlap_state[] = {
125 "LAP_NDM",
126 "LAP_QUERY",
127 "LAP_REPLY",
128 "LAP_CONN",
129 "LAP_SETUP",
130 "LAP_OFFLINE",
131 "LAP_XMIT_P",
132 "LAP_PCLOSE",
133 "LAP_NRM_P",
134 "LAP_RESET_WAIT",
135 "LAP_RESET",
136 "LAP_NRM_S",
137 "LAP_XMIT_S",
138 "LAP_SCLOSE",
139 "LAP_RESET_CHECK",
140};
141
142static int (*state[])(struct irlap_cb *self, IRLAP_EVENT event,
143 struct sk_buff *skb, struct irlap_info *info) =
144{
145 irlap_state_ndm,
146 irlap_state_query,
147 irlap_state_reply,
148 irlap_state_conn,
149 irlap_state_setup,
150 irlap_state_offline,
151 irlap_state_xmit_p,
152 irlap_state_pclose,
153 irlap_state_nrm_p,
154 irlap_state_reset_wait,
155 irlap_state_reset,
156 irlap_state_nrm_s,
157 irlap_state_xmit_s,
158 irlap_state_sclose,
159 irlap_state_reset_check,
160};
161
162
163
164
165
166
167
168static void irlap_poll_timer_expired(void *data)
169{
170 struct irlap_cb *self = (struct irlap_cb *) data;
171
172 IRDA_ASSERT(self != NULL, return;);
173 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
174
175 irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
176}
177
178
179
180
181
182
183
184static void irlap_start_poll_timer(struct irlap_cb *self, int timeout)
185{
186 IRDA_ASSERT(self != NULL, return;);
187 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
188
189#ifdef CONFIG_IRDA_FAST_RR
190
191
192
193
194 if (skb_queue_empty(&self->txq) || self->remote_busy) {
195 if (self->fast_RR == TRUE) {
196
197
198
199
200 if (self->fast_RR_timeout < timeout) {
201
202
203
204
205 self->fast_RR_timeout +=
206 (sysctl_fast_poll_increase * HZ/1000);
207
208
209 timeout = self->fast_RR_timeout;
210 }
211 } else {
212 self->fast_RR = TRUE;
213
214
215 self->fast_RR_timeout = 0;
216 timeout = 0;
217 }
218 } else
219 self->fast_RR = FALSE;
220
221 IRDA_DEBUG(3, "%s(), timeout=%d (%ld)\n", __func__, timeout, jiffies);
222#endif
223
224 if (timeout == 0)
225 irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
226 else
227 irda_start_timer(&self->poll_timer, timeout, self,
228 irlap_poll_timer_expired);
229}
230
231
232
233
234
235
236
237void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
238 struct sk_buff *skb, struct irlap_info *info)
239{
240 int ret;
241
242 if (!self || self->magic != LAP_MAGIC)
243 return;
244
245 IRDA_DEBUG(3, "%s(), event = %s, state = %s\n", __func__,
246 irlap_event[event], irlap_state[self->state]);
247
248 ret = (*state[self->state])(self, event, skb, info);
249
250
251
252
253 switch (self->state) {
254 case LAP_XMIT_P:
255 case LAP_XMIT_S:
256
257
258
259
260
261
262
263 IRDA_DEBUG(2, "%s() : queue len = %d\n", __func__,
264 skb_queue_len(&self->txq));
265
266 if (!skb_queue_empty(&self->txq)) {
267
268 self->local_busy = TRUE;
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 while ((skb = skb_dequeue(&self->txq)) != NULL) {
287
288 ret = (*state[self->state])(self, SEND_I_CMD,
289 skb, NULL);
290
291
292
293 kfree_skb(skb);
294
295
296 irlmp_flow_indication(self->notify.instance,
297 FLOW_START);
298
299 if (ret == -EPROTO)
300 break;
301 }
302
303 self->local_busy = FALSE;
304 } else if (self->disconnect_pending) {
305 self->disconnect_pending = FALSE;
306
307 ret = (*state[self->state])(self, DISCONNECT_REQUEST,
308 NULL, NULL);
309 }
310 break;
311
312
313
314
315 default:
316 break;
317 }
318}
319
320
321
322
323
324
325
326static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
327 struct sk_buff *skb, struct irlap_info *info)
328{
329 discovery_t *discovery_rsp;
330 int ret = 0;
331
332 IRDA_ASSERT(self != NULL, return -1;);
333 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
334
335 switch (event) {
336 case CONNECT_REQUEST:
337 IRDA_ASSERT(self->netdev != NULL, return -1;);
338
339 if (self->media_busy) {
340
341
342
343 IRDA_DEBUG(0, "%s(), CONNECT_REQUEST: media busy!\n",
344 __func__);
345
346
347 irlap_next_state(self, LAP_NDM);
348
349 irlap_disconnect_indication(self, LAP_MEDIA_BUSY);
350 } else {
351 irlap_send_snrm_frame(self, &self->qos_rx);
352
353
354 irlap_start_final_timer(self, self->final_timeout);
355
356 self->retry_count = 0;
357 irlap_next_state(self, LAP_SETUP);
358 }
359 break;
360 case RECV_SNRM_CMD:
361
362 if (info) {
363 self->daddr = info->daddr;
364 self->caddr = info->caddr;
365
366 irlap_next_state(self, LAP_CONN);
367
368 irlap_connect_indication(self, skb);
369 } else {
370 IRDA_DEBUG(0, "%s(), SNRM frame does not "
371 "contain an I field!\n", __func__);
372 }
373 break;
374 case DISCOVERY_REQUEST:
375 IRDA_ASSERT(info != NULL, return -1;);
376
377 if (self->media_busy) {
378 IRDA_DEBUG(1, "%s(), DISCOVERY_REQUEST: media busy!\n",
379 __func__);
380
381
382
383 irlap_discovery_confirm(self, NULL);
384
385
386
387 return 0;
388 }
389
390 self->S = info->S;
391 self->s = info->s;
392 irlap_send_discovery_xid_frame(self, info->S, info->s, TRUE,
393 info->discovery);
394 self->frame_sent = FALSE;
395 self->s++;
396
397 irlap_start_slot_timer(self, self->slot_timeout);
398 irlap_next_state(self, LAP_QUERY);
399 break;
400 case RECV_DISCOVERY_XID_CMD:
401 IRDA_ASSERT(info != NULL, return -1;);
402
403
404 if (info->s <= info->S) {
405 self->slot = irlap_generate_rand_time_slot(info->S,
406 info->s);
407 if (self->slot == info->s) {
408 discovery_rsp = irlmp_get_discovery_response();
409 discovery_rsp->data.daddr = info->daddr;
410
411 irlap_send_discovery_xid_frame(self, info->S,
412 self->slot,
413 FALSE,
414 discovery_rsp);
415 self->frame_sent = TRUE;
416 } else
417 self->frame_sent = FALSE;
418
419
420
421
422
423
424 irlap_start_query_timer(self, info->S, info->s);
425 irlap_next_state(self, LAP_REPLY);
426 } else {
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 IRDA_DEBUG(1, "%s(), Receiving final discovery request, missed the discovery slots :-(\n", __func__);
446
447
448 irlap_discovery_indication(self, info->discovery);
449 }
450 break;
451 case MEDIA_BUSY_TIMER_EXPIRED:
452
453
454
455
456
457
458
459
460
461#ifdef CONFIG_IRDA_ULTRA
462
463 if (!skb_queue_empty(&self->txq_ultra)) {
464
465
466
467 ret = (*state[self->state])(self, SEND_UI_FRAME,
468 NULL, NULL);
469 }
470#endif
471
472
473 if (self->connect_pending) {
474 self->connect_pending = FALSE;
475
476
477
478
479 if (self->disconnect_pending)
480 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
481 else
482 ret = (*state[self->state])(self,
483 CONNECT_REQUEST,
484 NULL, NULL);
485 self->disconnect_pending = FALSE;
486 }
487
488
489
490
491
492
493
494
495
496
497
498 break;
499#ifdef CONFIG_IRDA_ULTRA
500 case SEND_UI_FRAME:
501 {
502 int i;
503
504 for (i=0; ((i<2) && (self->media_busy == FALSE)); i++) {
505 skb = skb_dequeue(&self->txq_ultra);
506 if (skb)
507 irlap_send_ui_frame(self, skb, CBROADCAST,
508 CMD_FRAME);
509 else
510 break;
511
512
513 }
514 if (i == 2) {
515
516 irda_device_set_media_busy(self->netdev, TRUE);
517 }
518 break;
519 }
520 case RECV_UI_FRAME:
521
522 if (info->caddr != CBROADCAST) {
523 IRDA_DEBUG(0, "%s(), not a broadcast frame!\n",
524 __func__);
525 } else
526 irlap_unitdata_indication(self, skb);
527 break;
528#endif
529 case RECV_TEST_CMD:
530
531 skb_pull(skb, sizeof(struct test_frame));
532
533
534
535
536
537 irlap_send_test_frame(self, CBROADCAST, info->daddr, skb);
538 break;
539 case RECV_TEST_RSP:
540 IRDA_DEBUG(0, "%s() not implemented!\n", __func__);
541 break;
542 default:
543 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __func__,
544 irlap_event[event]);
545
546 ret = -1;
547 break;
548 }
549 return ret;
550}
551
552
553
554
555
556
557
558static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
559 struct sk_buff *skb, struct irlap_info *info)
560{
561 int ret = 0;
562
563 IRDA_ASSERT(self != NULL, return -1;);
564 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
565
566 switch (event) {
567 case RECV_DISCOVERY_XID_RSP:
568 IRDA_ASSERT(info != NULL, return -1;);
569 IRDA_ASSERT(info->discovery != NULL, return -1;);
570
571 IRDA_DEBUG(4, "%s(), daddr=%08x\n", __func__,
572 info->discovery->data.daddr);
573
574 if (!self->discovery_log) {
575 IRDA_WARNING("%s: discovery log is gone! "
576 "maybe the discovery timeout has been set"
577 " too short?\n", __func__);
578 break;
579 }
580 hashbin_insert(self->discovery_log,
581 (irda_queue_t *) info->discovery,
582 info->discovery->data.daddr, NULL);
583
584
585
586
587 break;
588 case RECV_DISCOVERY_XID_CMD:
589
590
591
592
593
594
595
596
597
598
599
600 IRDA_ASSERT(info != NULL, return -1;);
601
602 IRDA_DEBUG(1, "%s(), Receiving discovery request (s = %d) while performing discovery :-(\n", __func__, info->s);
603
604
605 if (info->s == 0xff)
606 irlap_discovery_indication(self, info->discovery);
607 break;
608 case SLOT_TIMER_EXPIRED:
609
610
611
612
613
614
615 if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
616 IRDA_DEBUG(2, "%s(), device is slow to answer, "
617 "waiting some more!\n", __func__);
618 irlap_start_slot_timer(self, msecs_to_jiffies(10));
619 self->add_wait = TRUE;
620 return ret;
621 }
622 self->add_wait = FALSE;
623
624 if (self->s < self->S) {
625 irlap_send_discovery_xid_frame(self, self->S,
626 self->s, TRUE,
627 self->discovery_cmd);
628 self->s++;
629 irlap_start_slot_timer(self, self->slot_timeout);
630
631
632 irlap_next_state(self, LAP_QUERY);
633 } else {
634
635 irlap_send_discovery_xid_frame(self, self->S, 0xff,
636 TRUE,
637 self->discovery_cmd);
638
639
640 irlap_next_state(self, LAP_NDM);
641
642
643
644
645
646 irlap_discovery_confirm(self, self->discovery_log);
647
648
649 self->discovery_log = NULL;
650 }
651 break;
652 default:
653 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __func__,
654 irlap_event[event]);
655
656 ret = -1;
657 break;
658 }
659 return ret;
660}
661
662
663
664
665
666
667
668
669static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
670 struct sk_buff *skb, struct irlap_info *info)
671{
672 discovery_t *discovery_rsp;
673 int ret=0;
674
675 IRDA_DEBUG(4, "%s()\n", __func__);
676
677 IRDA_ASSERT(self != NULL, return -1;);
678 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
679
680 switch (event) {
681 case QUERY_TIMER_EXPIRED:
682 IRDA_DEBUG(0, "%s(), QUERY_TIMER_EXPIRED <%ld>\n",
683 __func__, jiffies);
684 irlap_next_state(self, LAP_NDM);
685 break;
686 case RECV_DISCOVERY_XID_CMD:
687 IRDA_ASSERT(info != NULL, return -1;);
688
689 if (info->s == 0xff) {
690 del_timer(&self->query_timer);
691
692
693
694
695 irlap_next_state(self, LAP_NDM);
696
697 irlap_discovery_indication(self, info->discovery);
698 } else {
699
700 if ((info->s >= self->slot) && (!self->frame_sent)) {
701 discovery_rsp = irlmp_get_discovery_response();
702 discovery_rsp->data.daddr = info->daddr;
703
704 irlap_send_discovery_xid_frame(self, info->S,
705 self->slot,
706 FALSE,
707 discovery_rsp);
708
709 self->frame_sent = TRUE;
710 }
711
712
713
714 irlap_start_query_timer(self, info->S, info->s);
715
716
717
718 }
719 break;
720 default:
721 IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __func__,
722 event, irlap_event[event]);
723
724 ret = -1;
725 break;
726 }
727 return ret;
728}
729
730
731
732
733
734
735
736
737static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event,
738 struct sk_buff *skb, struct irlap_info *info)
739{
740 int ret = 0;
741
742 IRDA_DEBUG(4, "%s(), event=%s\n", __func__, irlap_event[ event]);
743
744 IRDA_ASSERT(self != NULL, return -1;);
745 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
746
747 switch (event) {
748 case CONNECT_RESPONSE:
749 skb_pull(skb, sizeof(struct snrm_frame));
750
751 IRDA_ASSERT(self->netdev != NULL, return -1;);
752
753 irlap_qos_negotiate(self, skb);
754
755 irlap_initiate_connection_state(self);
756
757
758
759
760
761 irlap_apply_connection_parameters(self, FALSE);
762
763
764
765
766
767 irlap_send_ua_response_frame(self, &self->qos_rx);
768
769#if 0
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789 irlap_send_ua_response_frame(self, &self->qos_rx);
790#endif
791
792
793
794
795
796
797 irlap_start_wd_timer(self, self->wd_timeout);
798 irlap_next_state(self, LAP_NRM_S);
799
800 break;
801 case RECV_DISCOVERY_XID_CMD:
802 IRDA_DEBUG(3, "%s(), event RECV_DISCOVER_XID_CMD!\n",
803 __func__);
804 irlap_next_state(self, LAP_NDM);
805
806 break;
807 case DISCONNECT_REQUEST:
808 IRDA_DEBUG(0, "%s(), Disconnect request!\n", __func__);
809 irlap_send_dm_frame(self);
810 irlap_next_state( self, LAP_NDM);
811 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
812 break;
813 default:
814 IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __func__,
815 event, irlap_event[event]);
816
817 ret = -1;
818 break;
819 }
820
821 return ret;
822}
823
824
825
826
827
828
829
830
831static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
832 struct sk_buff *skb, struct irlap_info *info)
833{
834 int ret = 0;
835
836 IRDA_DEBUG(4, "%s()\n", __func__);
837
838 IRDA_ASSERT(self != NULL, return -1;);
839 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
840
841 switch (event) {
842 case FINAL_TIMER_EXPIRED:
843 if (self->retry_count < self->N3) {
844
845
846
847
848
849
850 irlap_start_backoff_timer(self, msecs_to_jiffies(20 +
851 (jiffies % 30)));
852 } else {
853
854 irlap_next_state(self, LAP_NDM);
855
856 irlap_disconnect_indication(self, LAP_FOUND_NONE);
857 }
858 break;
859 case BACKOFF_TIMER_EXPIRED:
860 irlap_send_snrm_frame(self, &self->qos_rx);
861 irlap_start_final_timer(self, self->final_timeout);
862 self->retry_count++;
863 break;
864 case RECV_SNRM_CMD:
865 IRDA_DEBUG(4, "%s(), SNRM battle!\n", __func__);
866
867 IRDA_ASSERT(skb != NULL, return 0;);
868 IRDA_ASSERT(info != NULL, return 0;);
869
870
871
872
873
874 if (info &&(info->daddr > self->saddr)) {
875 del_timer(&self->final_timer);
876 irlap_initiate_connection_state(self);
877
878 IRDA_ASSERT(self->netdev != NULL, return -1;);
879
880 skb_pull(skb, sizeof(struct snrm_frame));
881
882 irlap_qos_negotiate(self, skb);
883
884
885 irlap_apply_connection_parameters(self, FALSE);
886 irlap_send_ua_response_frame(self, &self->qos_rx);
887
888 irlap_next_state(self, LAP_NRM_S);
889 irlap_connect_confirm(self, skb);
890
891
892
893
894
895
896 irlap_start_wd_timer(self, self->wd_timeout);
897 } else {
898
899 irlap_next_state(self, LAP_SETUP);
900 }
901 break;
902 case RECV_UA_RSP:
903
904 del_timer(&self->final_timer);
905
906
907 irlap_initiate_connection_state(self);
908
909
910 IRDA_ASSERT(skb->len > 10, return -1;);
911
912 skb_pull(skb, sizeof(struct ua_frame));
913
914 IRDA_ASSERT(self->netdev != NULL, return -1;);
915
916 irlap_qos_negotiate(self, skb);
917
918
919 irlap_apply_connection_parameters(self, TRUE);
920 self->retry_count = 0;
921
922
923
924
925
926
927
928 irlap_wait_min_turn_around(self, &self->qos_tx);
929
930
931 irlap_send_rr_frame(self, CMD_FRAME);
932
933
934
935
936
937
938
939 irlap_start_final_timer(self, self->final_timeout/2);
940 irlap_next_state(self, LAP_NRM_P);
941
942 irlap_connect_confirm(self, skb);
943 break;
944 case RECV_DM_RSP:
945 case RECV_DISC_CMD:
946 del_timer(&self->final_timer);
947 irlap_next_state(self, LAP_NDM);
948
949 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
950 break;
951 default:
952 IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __func__,
953 event, irlap_event[event]);
954
955 ret = -1;
956 break;
957 }
958 return ret;
959}
960
961
962
963
964
965
966
967static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event,
968 struct sk_buff *skb, struct irlap_info *info)
969{
970 IRDA_DEBUG( 0, "%s(), Unknown event\n", __func__);
971
972 return -1;
973}
974
975
976
977
978
979
980
981
982
983static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
984 struct sk_buff *skb, struct irlap_info *info)
985{
986 int ret = 0;
987
988 switch (event) {
989 case SEND_I_CMD:
990
991
992
993 if ((self->window > 0) && (!self->remote_busy)) {
994 int nextfit;
995#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
996 struct sk_buff *skb_next;
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 skb_next = skb_peek(&self->txq);
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021 nextfit = ((skb_next != NULL) &&
1022 ((skb_next->len + skb->len) <=
1023 self->bytes_left));
1024
1025
1026
1027
1028
1029
1030
1031
1032 if((!nextfit) && (skb->len > self->bytes_left)) {
1033 IRDA_DEBUG(0, "%s(), Not allowed to transmit"
1034 " more bytes!\n", __func__);
1035
1036 skb_queue_head(&self->txq, skb_get(skb));
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052 return -EPROTO;
1053 }
1054
1055
1056 self->bytes_left -= skb->len;
1057#else
1058
1059
1060 nextfit = !skb_queue_empty(&self->txq);
1061#endif
1062
1063
1064
1065
1066 if ((self->window > 1) && (nextfit)) {
1067
1068 irlap_send_data_primary(self, skb);
1069 irlap_next_state(self, LAP_XMIT_P);
1070 } else {
1071
1072 irlap_send_data_primary_poll(self, skb);
1073
1074
1075
1076
1077
1078 ret = -EPROTO;
1079 }
1080#ifdef CONFIG_IRDA_FAST_RR
1081
1082 self->fast_RR = FALSE;
1083#endif
1084 } else {
1085 IRDA_DEBUG(4, "%s(), Unable to send! remote busy?\n",
1086 __func__);
1087 skb_queue_head(&self->txq, skb_get(skb));
1088
1089
1090
1091
1092
1093 ret = -EPROTO;
1094 }
1095 break;
1096 case POLL_TIMER_EXPIRED:
1097 IRDA_DEBUG(3, "%s(), POLL_TIMER_EXPIRED <%ld>\n",
1098 __func__, jiffies);
1099 irlap_send_rr_frame(self, CMD_FRAME);
1100
1101 self->window = self->window_size;
1102#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1103
1104 self->bytes_left = self->line_capacity;
1105#endif
1106 irlap_start_final_timer(self, self->final_timeout);
1107 irlap_next_state(self, LAP_NRM_P);
1108 break;
1109 case DISCONNECT_REQUEST:
1110 del_timer(&self->poll_timer);
1111 irlap_wait_min_turn_around(self, &self->qos_tx);
1112 irlap_send_disc_frame(self);
1113 irlap_flush_all_queues(self);
1114 irlap_start_final_timer(self, self->final_timeout);
1115 self->retry_count = 0;
1116 irlap_next_state(self, LAP_PCLOSE);
1117 break;
1118 case DATA_REQUEST:
1119
1120
1121 break;
1122 default:
1123 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
1124 __func__, irlap_event[event]);
1125
1126 ret = -EINVAL;
1127 break;
1128 }
1129 return ret;
1130}
1131
1132
1133
1134
1135
1136
1137static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event,
1138 struct sk_buff *skb, struct irlap_info *info)
1139{
1140 int ret = 0;
1141
1142 IRDA_DEBUG(1, "%s()\n", __func__);
1143
1144 IRDA_ASSERT(self != NULL, return -1;);
1145 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1146
1147 switch (event) {
1148 case RECV_UA_RSP:
1149 case RECV_DM_RSP:
1150 del_timer(&self->final_timer);
1151
1152
1153 irlap_apply_default_connection_parameters(self);
1154
1155
1156 irlap_next_state(self, LAP_NDM);
1157
1158 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
1159 break;
1160 case FINAL_TIMER_EXPIRED:
1161 if (self->retry_count < self->N3) {
1162 irlap_wait_min_turn_around(self, &self->qos_tx);
1163 irlap_send_disc_frame(self);
1164 irlap_start_final_timer(self, self->final_timeout);
1165 self->retry_count++;
1166
1167 } else {
1168 irlap_apply_default_connection_parameters(self);
1169
1170
1171 irlap_next_state(self, LAP_NDM);
1172
1173 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1174 }
1175 break;
1176 default:
1177 IRDA_DEBUG(1, "%s(), Unknown event %d\n", __func__, event);
1178
1179 ret = -1;
1180 break;
1181 }
1182 return ret;
1183}
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
1195 struct sk_buff *skb, struct irlap_info *info)
1196{
1197 int ret = 0;
1198 int ns_status;
1199 int nr_status;
1200
1201 switch (event) {
1202 case RECV_I_RSP:
1203 if (unlikely(skb->len <= LAP_ADDR_HEADER + LAP_CTRL_HEADER)) {
1204
1205
1206
1207
1208
1209
1210
1211 irlap_wait_min_turn_around(self, &self->qos_tx);
1212 irlap_send_rr_frame(self, CMD_FRAME);
1213
1214 break;
1215 }
1216
1217#ifdef CONFIG_IRDA_FAST_RR
1218
1219
1220
1221
1222
1223 self->fast_RR = FALSE;
1224#endif
1225 IRDA_ASSERT( info != NULL, return -1;);
1226
1227 ns_status = irlap_validate_ns_received(self, info->ns);
1228 nr_status = irlap_validate_nr_received(self, info->nr);
1229
1230
1231
1232
1233 if ((ns_status == NS_EXPECTED) && (nr_status == NR_EXPECTED)) {
1234
1235
1236 self->vr = (self->vr + 1) % 8;
1237
1238
1239 irlap_update_nr_received(self, info->nr);
1240
1241
1242
1243
1244
1245
1246 self->retry_count = 0;
1247 self->ack_required = TRUE;
1248
1249
1250 if (!info->pf) {
1251
1252 irlap_next_state(self, LAP_NRM_P);
1253
1254 irlap_data_indication(self, skb, FALSE);
1255 } else {
1256
1257 del_timer(&self->final_timer);
1258
1259 irlap_wait_min_turn_around(self, &self->qos_tx);
1260
1261
1262
1263
1264
1265 irlap_data_indication(self, skb, FALSE);
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275 irlap_next_state(self, LAP_XMIT_P);
1276
1277
1278
1279
1280 irlap_start_poll_timer(self, self->poll_timeout);
1281 }
1282 break;
1283
1284 }
1285
1286 if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
1287 {
1288 if (!info->pf) {
1289 irlap_update_nr_received(self, info->nr);
1290
1291
1292
1293
1294
1295
1296
1297 irlap_next_state(self, LAP_NRM_P);
1298 } else {
1299 IRDA_DEBUG(4,
1300 "%s(), missing or duplicate frame!\n",
1301 __func__);
1302
1303
1304 irlap_update_nr_received(self, info->nr);
1305
1306 irlap_wait_min_turn_around(self, &self->qos_tx);
1307 irlap_send_rr_frame(self, CMD_FRAME);
1308
1309 self->ack_required = FALSE;
1310
1311 irlap_start_final_timer(self, self->final_timeout);
1312 irlap_next_state(self, LAP_NRM_P);
1313 }
1314 break;
1315 }
1316
1317
1318
1319 if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
1320 {
1321 if (info->pf) {
1322 self->vr = (self->vr + 1) % 8;
1323
1324
1325 irlap_update_nr_received(self, info->nr);
1326
1327
1328 irlap_resend_rejected_frames(self, CMD_FRAME);
1329
1330 self->ack_required = FALSE;
1331
1332
1333
1334
1335
1336 irlap_start_final_timer(self, 2 * self->final_timeout);
1337
1338
1339 irlap_next_state(self, LAP_NRM_P);
1340
1341 irlap_data_indication(self, skb, FALSE);
1342 } else {
1343
1344
1345
1346
1347
1348
1349 self->vr = (self->vr + 1) % 8;
1350
1351
1352 irlap_update_nr_received(self, info->nr);
1353
1354 self->ack_required = FALSE;
1355
1356
1357 irlap_next_state(self, LAP_NRM_P);
1358
1359 irlap_data_indication(self, skb, FALSE);
1360 }
1361 break;
1362 }
1363
1364
1365
1366
1367 if ((ns_status == NS_UNEXPECTED) &&
1368 (nr_status == NR_UNEXPECTED))
1369 {
1370 IRDA_DEBUG(4, "%s(), unexpected nr and ns!\n",
1371 __func__);
1372 if (info->pf) {
1373
1374 irlap_resend_rejected_frames(self, CMD_FRAME);
1375
1376
1377
1378 irlap_start_final_timer(self, 2 * self->final_timeout);
1379
1380
1381 irlap_next_state(self, LAP_NRM_P);
1382 } else {
1383
1384
1385
1386 self->ack_required = FALSE;
1387 }
1388 break;
1389 }
1390
1391
1392
1393
1394 if ((nr_status == NR_INVALID) || (ns_status == NS_INVALID)) {
1395 if (info->pf) {
1396 del_timer(&self->final_timer);
1397
1398 irlap_next_state(self, LAP_RESET_WAIT);
1399
1400 irlap_disconnect_indication(self, LAP_RESET_INDICATION);
1401 self->xmitflag = TRUE;
1402 } else {
1403 del_timer(&self->final_timer);
1404
1405 irlap_disconnect_indication(self, LAP_RESET_INDICATION);
1406
1407 self->xmitflag = FALSE;
1408 }
1409 break;
1410 }
1411 IRDA_DEBUG(1, "%s(), Not implemented!\n", __func__);
1412 IRDA_DEBUG(1, "%s(), event=%s, ns_status=%d, nr_status=%d\n",
1413 __func__, irlap_event[event], ns_status, nr_status);
1414 break;
1415 case RECV_UI_FRAME:
1416
1417 if (!info->pf) {
1418 irlap_data_indication(self, skb, TRUE);
1419 irlap_next_state(self, LAP_NRM_P);
1420 } else {
1421 del_timer(&self->final_timer);
1422 irlap_data_indication(self, skb, TRUE);
1423 irlap_next_state(self, LAP_XMIT_P);
1424 IRDA_DEBUG(1, "%s: RECV_UI_FRAME: next state %s\n", __func__, irlap_state[self->state]);
1425 irlap_start_poll_timer(self, self->poll_timeout);
1426 }
1427 break;
1428 case RECV_RR_RSP:
1429
1430
1431
1432
1433 self->remote_busy = FALSE;
1434
1435
1436 del_timer(&self->final_timer);
1437
1438
1439
1440
1441 ret = irlap_validate_nr_received(self, info->nr);
1442 if (ret == NR_EXPECTED) {
1443
1444 irlap_update_nr_received(self, info->nr);
1445
1446
1447
1448
1449
1450
1451 self->retry_count = 0;
1452 irlap_wait_min_turn_around(self, &self->qos_tx);
1453
1454 irlap_next_state(self, LAP_XMIT_P);
1455
1456
1457 irlap_start_poll_timer(self, self->poll_timeout);
1458 } else if (ret == NR_UNEXPECTED) {
1459 IRDA_ASSERT(info != NULL, return -1;);
1460
1461
1462
1463
1464
1465 irlap_update_nr_received(self, info->nr);
1466
1467 IRDA_DEBUG(4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, "
1468 "vs=%d, vr=%d\n",
1469 self->retry_count, info->nr, self->va,
1470 self->vs, self->vr);
1471
1472
1473 irlap_resend_rejected_frames(self, CMD_FRAME);
1474 irlap_start_final_timer(self, self->final_timeout * 2);
1475
1476 irlap_next_state(self, LAP_NRM_P);
1477 } else if (ret == NR_INVALID) {
1478 IRDA_DEBUG(1, "%s(), Received RR with "
1479 "invalid nr !\n", __func__);
1480
1481 irlap_next_state(self, LAP_RESET_WAIT);
1482
1483 irlap_disconnect_indication(self, LAP_RESET_INDICATION);
1484 self->xmitflag = TRUE;
1485 }
1486 break;
1487 case RECV_RNR_RSP:
1488 IRDA_ASSERT(info != NULL, return -1;);
1489
1490
1491 del_timer(&self->final_timer);
1492 self->remote_busy = TRUE;
1493
1494
1495 irlap_update_nr_received(self, info->nr);
1496 irlap_next_state(self, LAP_XMIT_P);
1497
1498
1499 irlap_start_poll_timer(self, self->poll_timeout);
1500 break;
1501 case RECV_FRMR_RSP:
1502 del_timer(&self->final_timer);
1503 self->xmitflag = TRUE;
1504 irlap_next_state(self, LAP_RESET_WAIT);
1505 irlap_reset_indication(self);
1506 break;
1507 case FINAL_TIMER_EXPIRED:
1508
1509
1510
1511
1512
1513
1514 if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
1515 IRDA_DEBUG(1, "FINAL_TIMER_EXPIRED when receiving a "
1516 "frame! Waiting a little bit more!\n");
1517 irlap_start_final_timer(self, msecs_to_jiffies(300));
1518
1519
1520
1521
1522
1523
1524 self->add_wait = TRUE;
1525 break;
1526 }
1527 self->add_wait = FALSE;
1528
1529
1530 if (self->retry_count < self->N2) {
1531 if (skb_peek(&self->wx_list) == NULL) {
1532
1533 IRDA_DEBUG(4, "nrm_p: resending rr");
1534 irlap_wait_min_turn_around(self, &self->qos_tx);
1535 irlap_send_rr_frame(self, CMD_FRAME);
1536 } else {
1537 IRDA_DEBUG(4, "nrm_p: resend frames");
1538 irlap_resend_rejected_frames(self, CMD_FRAME);
1539 }
1540
1541 irlap_start_final_timer(self, self->final_timeout);
1542 self->retry_count++;
1543 IRDA_DEBUG(4, "irlap_state_nrm_p: FINAL_TIMER_EXPIRED:"
1544 " retry_count=%d\n", self->retry_count);
1545
1546
1547
1548
1549
1550
1551
1552 if((self->retry_count % self->N1) == 0)
1553 irlap_status_indication(self,
1554 STATUS_NO_ACTIVITY);
1555
1556
1557 } else {
1558 irlap_apply_default_connection_parameters(self);
1559
1560
1561 irlap_next_state(self, LAP_NDM);
1562 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1563 }
1564 break;
1565 case RECV_REJ_RSP:
1566 irlap_update_nr_received(self, info->nr);
1567 if (self->remote_busy) {
1568 irlap_wait_min_turn_around(self, &self->qos_tx);
1569 irlap_send_rr_frame(self, CMD_FRAME);
1570 } else
1571 irlap_resend_rejected_frames(self, CMD_FRAME);
1572 irlap_start_final_timer(self, 2 * self->final_timeout);
1573 break;
1574 case RECV_SREJ_RSP:
1575 irlap_update_nr_received(self, info->nr);
1576 if (self->remote_busy) {
1577 irlap_wait_min_turn_around(self, &self->qos_tx);
1578 irlap_send_rr_frame(self, CMD_FRAME);
1579 } else
1580 irlap_resend_rejected_frame(self, CMD_FRAME);
1581 irlap_start_final_timer(self, 2 * self->final_timeout);
1582 break;
1583 case RECV_RD_RSP:
1584 IRDA_DEBUG(1, "%s(), RECV_RD_RSP\n", __func__);
1585
1586 irlap_flush_all_queues(self);
1587 irlap_next_state(self, LAP_XMIT_P);
1588
1589 irlap_disconnect_request(self);
1590 break;
1591 default:
1592 IRDA_DEBUG(1, "%s(), Unknown event %s\n",
1593 __func__, irlap_event[event]);
1594
1595 ret = -1;
1596 break;
1597 }
1598 return ret;
1599}
1600
1601
1602
1603
1604
1605
1606
1607
1608static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
1609 struct sk_buff *skb, struct irlap_info *info)
1610{
1611 int ret = 0;
1612
1613 IRDA_DEBUG(3, "%s(), event = %s\n", __func__, irlap_event[event]);
1614
1615 IRDA_ASSERT(self != NULL, return -1;);
1616 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1617
1618 switch (event) {
1619 case RESET_REQUEST:
1620 if (self->xmitflag) {
1621 irlap_wait_min_turn_around(self, &self->qos_tx);
1622 irlap_send_snrm_frame(self, NULL);
1623 irlap_start_final_timer(self, self->final_timeout);
1624 irlap_next_state(self, LAP_RESET);
1625 } else {
1626 irlap_start_final_timer(self, self->final_timeout);
1627 irlap_next_state(self, LAP_RESET);
1628 }
1629 break;
1630 case DISCONNECT_REQUEST:
1631 irlap_wait_min_turn_around( self, &self->qos_tx);
1632 irlap_send_disc_frame( self);
1633 irlap_flush_all_queues( self);
1634 irlap_start_final_timer( self, self->final_timeout);
1635 self->retry_count = 0;
1636 irlap_next_state( self, LAP_PCLOSE);
1637 break;
1638 default:
1639 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __func__,
1640 irlap_event[event]);
1641
1642 ret = -1;
1643 break;
1644 }
1645 return ret;
1646}
1647
1648
1649
1650
1651
1652
1653
1654
1655static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event,
1656 struct sk_buff *skb, struct irlap_info *info)
1657{
1658 int ret = 0;
1659
1660 IRDA_DEBUG(3, "%s(), event = %s\n", __func__, irlap_event[event]);
1661
1662 IRDA_ASSERT(self != NULL, return -1;);
1663 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1664
1665 switch (event) {
1666 case RECV_DISC_CMD:
1667 del_timer(&self->final_timer);
1668
1669 irlap_apply_default_connection_parameters(self);
1670
1671
1672 irlap_next_state(self, LAP_NDM);
1673
1674 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1675
1676 break;
1677 case RECV_UA_RSP:
1678 del_timer(&self->final_timer);
1679
1680
1681 irlap_initiate_connection_state(self);
1682
1683 irlap_reset_confirm();
1684
1685 self->remote_busy = FALSE;
1686
1687 irlap_next_state(self, LAP_XMIT_P);
1688
1689 irlap_start_poll_timer(self, self->poll_timeout);
1690
1691 break;
1692 case FINAL_TIMER_EXPIRED:
1693 if (self->retry_count < 3) {
1694 irlap_wait_min_turn_around(self, &self->qos_tx);
1695
1696 IRDA_ASSERT(self->netdev != NULL, return -1;);
1697 irlap_send_snrm_frame(self, self->qos_dev);
1698
1699 self->retry_count++;
1700
1701 irlap_start_final_timer(self, self->final_timeout);
1702 irlap_next_state(self, LAP_RESET);
1703 } else if (self->retry_count >= self->N3) {
1704 irlap_apply_default_connection_parameters(self);
1705
1706
1707 irlap_next_state(self, LAP_NDM);
1708
1709 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1710 }
1711 break;
1712 case RECV_SNRM_CMD:
1713
1714
1715
1716
1717 if (!info) {
1718 IRDA_DEBUG(3, "%s(), RECV_SNRM_CMD\n", __func__);
1719 irlap_initiate_connection_state(self);
1720 irlap_wait_min_turn_around(self, &self->qos_tx);
1721 irlap_send_ua_response_frame(self, &self->qos_rx);
1722 irlap_reset_confirm();
1723 irlap_start_wd_timer(self, self->wd_timeout);
1724 irlap_next_state(self, LAP_NDM);
1725 } else {
1726 IRDA_DEBUG(0,
1727 "%s(), SNRM frame contained an I field!\n",
1728 __func__);
1729 }
1730 break;
1731 default:
1732 IRDA_DEBUG(1, "%s(), Unknown event %s\n",
1733 __func__, irlap_event[event]);
1734
1735 ret = -1;
1736 break;
1737 }
1738 return ret;
1739}
1740
1741
1742
1743
1744
1745
1746
1747
1748static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
1749 struct sk_buff *skb, struct irlap_info *info)
1750{
1751 int ret = 0;
1752
1753 IRDA_DEBUG(4, "%s(), event=%s\n", __func__, irlap_event[event]);
1754
1755 IRDA_ASSERT(self != NULL, return -ENODEV;);
1756 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
1757
1758 switch (event) {
1759 case SEND_I_CMD:
1760
1761
1762
1763 if ((self->window > 0) && (!self->remote_busy)) {
1764 int nextfit;
1765#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1766 struct sk_buff *skb_next;
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778 skb_next = skb_peek(&self->txq);
1779 nextfit = ((skb_next != NULL) &&
1780 ((skb_next->len + skb->len) <=
1781 self->bytes_left));
1782
1783
1784
1785
1786
1787
1788 if((!nextfit) && (skb->len > self->bytes_left)) {
1789 IRDA_DEBUG(0, "%s(), Not allowed to transmit"
1790 " more bytes!\n", __func__);
1791
1792 skb_queue_head(&self->txq, skb_get(skb));
1793
1794
1795
1796
1797
1798
1799
1800 self->window = self->window_size;
1801 self->bytes_left = self->line_capacity;
1802 irlap_start_wd_timer(self, self->wd_timeout);
1803
1804 irlap_next_state(self, LAP_NRM_S);
1805
1806
1807
1808
1809 return -EPROTO;
1810 }
1811
1812 self->bytes_left -= skb->len;
1813#else
1814
1815
1816 nextfit = !skb_queue_empty(&self->txq);
1817#endif
1818
1819
1820
1821
1822 if ((self->window > 1) && (nextfit)) {
1823 irlap_send_data_secondary(self, skb);
1824 irlap_next_state(self, LAP_XMIT_S);
1825 } else {
1826 irlap_send_data_secondary_final(self, skb);
1827 irlap_next_state(self, LAP_NRM_S);
1828
1829
1830
1831
1832
1833 ret = -EPROTO;
1834 }
1835 } else {
1836 IRDA_DEBUG(2, "%s(), Unable to send!\n", __func__);
1837 skb_queue_head(&self->txq, skb_get(skb));
1838 ret = -EPROTO;
1839 }
1840 break;
1841 case DISCONNECT_REQUEST:
1842 irlap_send_rd_frame(self);
1843 irlap_flush_all_queues(self);
1844 irlap_start_wd_timer(self, self->wd_timeout);
1845 irlap_next_state(self, LAP_SCLOSE);
1846 break;
1847 case DATA_REQUEST:
1848
1849
1850 break;
1851 default:
1852 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __func__,
1853 irlap_event[event]);
1854
1855 ret = -EINVAL;
1856 break;
1857 }
1858 return ret;
1859}
1860
1861
1862
1863
1864
1865
1866
1867
1868static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
1869 struct sk_buff *skb, struct irlap_info *info)
1870{
1871 int ns_status;
1872 int nr_status;
1873 int ret = 0;
1874
1875 IRDA_DEBUG(4, "%s(), event=%s\n", __func__, irlap_event[ event]);
1876
1877 IRDA_ASSERT(self != NULL, return -1;);
1878 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1879
1880 switch (event) {
1881 case RECV_I_CMD:
1882
1883 IRDA_DEBUG(4, "%s(), event=%s nr=%d, vs=%d, ns=%d, "
1884 "vr=%d, pf=%d\n", __func__,
1885 irlap_event[event], info->nr,
1886 self->vs, info->ns, self->vr, info->pf);
1887
1888 self->retry_count = 0;
1889
1890 ns_status = irlap_validate_ns_received(self, info->ns);
1891 nr_status = irlap_validate_nr_received(self, info->nr);
1892
1893
1894
1895 if ((ns_status == NS_EXPECTED) && (nr_status == NR_EXPECTED)) {
1896
1897
1898 self->vr = (self->vr + 1) % 8;
1899
1900
1901 irlap_update_nr_received(self, info->nr);
1902
1903
1904
1905
1906 if (!info->pf) {
1907
1908 self->ack_required = TRUE;
1909
1910
1911
1912
1913
1914#if 0
1915 irda_start_timer(WD_TIMER, self->wd_timeout);
1916#endif
1917
1918 irlap_next_state(self, LAP_NRM_S);
1919
1920 irlap_data_indication(self, skb, FALSE);
1921 break;
1922 } else {
1923
1924
1925
1926
1927
1928 irlap_wait_min_turn_around(self, &self->qos_tx);
1929
1930
1931
1932
1933
1934
1935
1936 irlap_data_indication(self, skb, FALSE);
1937
1938
1939 if (!skb_queue_empty(&self->txq) &&
1940 (self->window > 0))
1941 {
1942 self->ack_required = TRUE;
1943
1944 del_timer(&self->wd_timer);
1945
1946 irlap_next_state(self, LAP_XMIT_S);
1947 } else {
1948 irlap_send_rr_frame(self, RSP_FRAME);
1949 irlap_start_wd_timer(self,
1950 self->wd_timeout);
1951
1952
1953 irlap_next_state(self, LAP_NRM_S);
1954 }
1955 break;
1956 }
1957 }
1958
1959
1960
1961 if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
1962 {
1963
1964 if (!info->pf) {
1965 irlap_update_nr_received(self, info->nr);
1966
1967 irlap_start_wd_timer(self, self->wd_timeout);
1968 } else {
1969
1970 irlap_update_nr_received(self, info->nr);
1971
1972 irlap_wait_min_turn_around(self, &self->qos_tx);
1973 irlap_send_rr_frame(self, RSP_FRAME);
1974
1975 irlap_start_wd_timer(self, self->wd_timeout);
1976 }
1977 break;
1978 }
1979
1980
1981
1982
1983 if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
1984 {
1985 if (info->pf) {
1986 IRDA_DEBUG(4, "RECV_I_RSP: frame(s) lost\n");
1987
1988 self->vr = (self->vr + 1) % 8;
1989
1990
1991 irlap_update_nr_received(self, info->nr);
1992
1993
1994 irlap_resend_rejected_frames(self, RSP_FRAME);
1995
1996
1997 irlap_next_state(self, LAP_NRM_S);
1998
1999 irlap_data_indication(self, skb, FALSE);
2000 irlap_start_wd_timer(self, self->wd_timeout);
2001 break;
2002 }
2003
2004
2005
2006
2007 if (!info->pf) {
2008 self->vr = (self->vr + 1) % 8;
2009
2010
2011 irlap_update_nr_received(self, info->nr);
2012
2013
2014 irlap_next_state(self, LAP_NRM_S);
2015
2016 irlap_data_indication(self, skb, FALSE);
2017 irlap_start_wd_timer(self, self->wd_timeout);
2018 }
2019 break;
2020 }
2021
2022 if (ret == NR_INVALID) {
2023 IRDA_DEBUG(0, "NRM_S, NR_INVALID not implemented!\n");
2024 }
2025 if (ret == NS_INVALID) {
2026 IRDA_DEBUG(0, "NRM_S, NS_INVALID not implemented!\n");
2027 }
2028 break;
2029 case RECV_UI_FRAME:
2030
2031
2032
2033 if (!info->pf) {
2034 irlap_data_indication(self, skb, TRUE);
2035 irlap_next_state(self, LAP_NRM_S);
2036 } else {
2037
2038
2039
2040 if (!skb_queue_empty(&self->txq) &&
2041 (self->window > 0) && !self->remote_busy)
2042 {
2043 irlap_data_indication(self, skb, TRUE);
2044
2045 del_timer(&self->wd_timer);
2046
2047 irlap_next_state(self, LAP_XMIT_S);
2048 } else {
2049 irlap_data_indication(self, skb, TRUE);
2050
2051 irlap_wait_min_turn_around(self, &self->qos_tx);
2052
2053 irlap_send_rr_frame(self, RSP_FRAME);
2054 self->ack_required = FALSE;
2055
2056 irlap_start_wd_timer(self, self->wd_timeout);
2057
2058
2059 irlap_next_state(self, LAP_NRM_S);
2060 }
2061 }
2062 break;
2063 case RECV_RR_CMD:
2064 self->retry_count = 0;
2065
2066
2067
2068
2069 nr_status = irlap_validate_nr_received(self, info->nr);
2070 if (nr_status == NR_EXPECTED) {
2071 if (!skb_queue_empty(&self->txq) &&
2072 (self->window > 0)) {
2073 self->remote_busy = FALSE;
2074
2075
2076 irlap_update_nr_received(self, info->nr);
2077 del_timer(&self->wd_timer);
2078
2079 irlap_wait_min_turn_around(self, &self->qos_tx);
2080 irlap_next_state(self, LAP_XMIT_S);
2081 } else {
2082 self->remote_busy = FALSE;
2083
2084 irlap_update_nr_received(self, info->nr);
2085 irlap_wait_min_turn_around(self, &self->qos_tx);
2086 irlap_start_wd_timer(self, self->wd_timeout);
2087
2088
2089
2090
2091
2092 if (self->disconnect_pending) {
2093
2094 irlap_send_rd_frame(self);
2095 irlap_flush_all_queues(self);
2096
2097 irlap_next_state(self, LAP_SCLOSE);
2098 } else {
2099
2100 irlap_send_rr_frame(self, RSP_FRAME);
2101
2102 irlap_next_state(self, LAP_NRM_S);
2103 }
2104 }
2105 } else if (nr_status == NR_UNEXPECTED) {
2106 self->remote_busy = FALSE;
2107 irlap_update_nr_received(self, info->nr);
2108 irlap_resend_rejected_frames(self, RSP_FRAME);
2109
2110 irlap_start_wd_timer(self, self->wd_timeout);
2111
2112
2113 irlap_next_state(self, LAP_NRM_S);
2114 } else {
2115 IRDA_DEBUG(1, "%s(), invalid nr not implemented!\n",
2116 __func__);
2117 }
2118 break;
2119 case RECV_SNRM_CMD:
2120
2121 if (!info) {
2122 del_timer(&self->wd_timer);
2123 IRDA_DEBUG(1, "%s(), received SNRM cmd\n", __func__);
2124 irlap_next_state(self, LAP_RESET_CHECK);
2125
2126 irlap_reset_indication(self);
2127 } else {
2128 IRDA_DEBUG(0,
2129 "%s(), SNRM frame contained an I-field!\n",
2130 __func__);
2131
2132 }
2133 break;
2134 case RECV_REJ_CMD:
2135 irlap_update_nr_received(self, info->nr);
2136 if (self->remote_busy) {
2137 irlap_wait_min_turn_around(self, &self->qos_tx);
2138 irlap_send_rr_frame(self, RSP_FRAME);
2139 } else
2140 irlap_resend_rejected_frames(self, RSP_FRAME);
2141 irlap_start_wd_timer(self, self->wd_timeout);
2142 break;
2143 case RECV_SREJ_CMD:
2144 irlap_update_nr_received(self, info->nr);
2145 if (self->remote_busy) {
2146 irlap_wait_min_turn_around(self, &self->qos_tx);
2147 irlap_send_rr_frame(self, RSP_FRAME);
2148 } else
2149 irlap_resend_rejected_frame(self, RSP_FRAME);
2150 irlap_start_wd_timer(self, self->wd_timeout);
2151 break;
2152 case WD_TIMER_EXPIRED:
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162 IRDA_DEBUG(1, "%s(), retry_count = %d\n", __func__,
2163 self->retry_count);
2164
2165 if (self->retry_count < (self->N2 / 2)) {
2166
2167 irlap_start_wd_timer(self, self->wd_timeout);
2168 self->retry_count++;
2169
2170 if((self->retry_count % (self->N1 / 2)) == 0)
2171 irlap_status_indication(self,
2172 STATUS_NO_ACTIVITY);
2173 } else {
2174 irlap_apply_default_connection_parameters(self);
2175
2176
2177 irlap_next_state(self, LAP_NDM);
2178 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
2179 }
2180 break;
2181 case RECV_DISC_CMD:
2182
2183 irlap_next_state(self, LAP_NDM);
2184
2185
2186 irlap_wait_min_turn_around(self, &self->qos_tx);
2187 irlap_send_ua_response_frame(self, NULL);
2188
2189 del_timer(&self->wd_timer);
2190 irlap_flush_all_queues(self);
2191
2192 irlap_apply_default_connection_parameters(self);
2193
2194 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2195 break;
2196 case RECV_DISCOVERY_XID_CMD:
2197 irlap_wait_min_turn_around(self, &self->qos_tx);
2198 irlap_send_rr_frame(self, RSP_FRAME);
2199 self->ack_required = TRUE;
2200 irlap_start_wd_timer(self, self->wd_timeout);
2201 irlap_next_state(self, LAP_NRM_S);
2202
2203 break;
2204 case RECV_TEST_CMD:
2205
2206 skb_pull(skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER);
2207
2208 irlap_wait_min_turn_around(self, &self->qos_tx);
2209 irlap_start_wd_timer(self, self->wd_timeout);
2210
2211
2212 irlap_send_test_frame(self, self->caddr, info->daddr, skb);
2213 break;
2214 default:
2215 IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __func__,
2216 event, irlap_event[event]);
2217
2218 ret = -EINVAL;
2219 break;
2220 }
2221 return ret;
2222}
2223
2224
2225
2226
2227static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event,
2228 struct sk_buff *skb, struct irlap_info *info)
2229{
2230 IRDA_DEBUG(1, "%s()\n", __func__);
2231
2232 IRDA_ASSERT(self != NULL, return -ENODEV;);
2233 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
2234
2235 switch (event) {
2236 case RECV_DISC_CMD:
2237
2238 irlap_next_state(self, LAP_NDM);
2239
2240
2241 irlap_wait_min_turn_around(self, &self->qos_tx);
2242 irlap_send_ua_response_frame(self, NULL);
2243
2244 del_timer(&self->wd_timer);
2245
2246 irlap_apply_default_connection_parameters(self);
2247
2248 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2249 break;
2250 case RECV_DM_RSP:
2251
2252
2253
2254 case RECV_RR_RSP:
2255 case RECV_RNR_RSP:
2256 case RECV_REJ_RSP:
2257 case RECV_SREJ_RSP:
2258 case RECV_I_RSP:
2259
2260 irlap_next_state(self, LAP_NDM);
2261
2262 del_timer(&self->wd_timer);
2263 irlap_apply_default_connection_parameters(self);
2264
2265 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2266 break;
2267 case WD_TIMER_EXPIRED:
2268
2269 irlap_next_state(self, LAP_NDM);
2270
2271 irlap_apply_default_connection_parameters(self);
2272
2273 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2274 break;
2275 default:
2276
2277
2278
2279 if (info != NULL && info->pf) {
2280 del_timer(&self->wd_timer);
2281 irlap_wait_min_turn_around(self, &self->qos_tx);
2282 irlap_send_rd_frame(self);
2283 irlap_start_wd_timer(self, self->wd_timeout);
2284 break;
2285 }
2286
2287 IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __func__,
2288 event, irlap_event[event]);
2289
2290 break;
2291 }
2292
2293 return -1;
2294}
2295
2296static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event,
2297 struct sk_buff *skb,
2298 struct irlap_info *info)
2299{
2300 int ret = 0;
2301
2302 IRDA_DEBUG(1, "%s(), event=%s\n", __func__, irlap_event[event]);
2303
2304 IRDA_ASSERT(self != NULL, return -ENODEV;);
2305 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
2306
2307 switch (event) {
2308 case RESET_RESPONSE:
2309 irlap_send_ua_response_frame(self, &self->qos_rx);
2310 irlap_initiate_connection_state(self);
2311 irlap_start_wd_timer(self, WD_TIMEOUT);
2312 irlap_flush_all_queues(self);
2313
2314 irlap_next_state(self, LAP_NRM_S);
2315 break;
2316 case DISCONNECT_REQUEST:
2317 irlap_wait_min_turn_around(self, &self->qos_tx);
2318 irlap_send_rd_frame(self);
2319 irlap_start_wd_timer(self, WD_TIMEOUT);
2320 irlap_next_state(self, LAP_SCLOSE);
2321 break;
2322 default:
2323 IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __func__,
2324 event, irlap_event[event]);
2325
2326 ret = -EINVAL;
2327 break;
2328 }
2329 return ret;
2330}
2331