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