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#include <linux/kernel.h>
28
29#include <net/irda/irda.h>
30#include <net/irda/timer.h>
31#include <net/irda/irlap.h>
32#include <net/irda/irlmp.h>
33#include <net/irda/irlmp_frame.h>
34#include <net/irda/irlmp_event.h>
35
36const char *const irlmp_state[] = {
37 "LAP_STANDBY",
38 "LAP_U_CONNECT",
39 "LAP_ACTIVE",
40};
41
42const char *const irlsap_state[] = {
43 "LSAP_DISCONNECTED",
44 "LSAP_CONNECT",
45 "LSAP_CONNECT_PEND",
46 "LSAP_DATA_TRANSFER_READY",
47 "LSAP_SETUP",
48 "LSAP_SETUP_PEND",
49};
50
51#ifdef CONFIG_IRDA_DEBUG
52static const char *const irlmp_event[] = {
53 "LM_CONNECT_REQUEST",
54 "LM_CONNECT_CONFIRM",
55 "LM_CONNECT_RESPONSE",
56 "LM_CONNECT_INDICATION",
57
58 "LM_DISCONNECT_INDICATION",
59 "LM_DISCONNECT_REQUEST",
60
61 "LM_DATA_REQUEST",
62 "LM_UDATA_REQUEST",
63 "LM_DATA_INDICATION",
64 "LM_UDATA_INDICATION",
65
66 "LM_WATCHDOG_TIMEOUT",
67
68
69 "LM_LAP_CONNECT_REQUEST",
70 "LM_LAP_CONNECT_INDICATION",
71 "LM_LAP_CONNECT_CONFIRM",
72 "LM_LAP_DISCONNECT_INDICATION",
73 "LM_LAP_DISCONNECT_REQUEST",
74 "LM_LAP_DISCOVERY_REQUEST",
75 "LM_LAP_DISCOVERY_CONFIRM",
76 "LM_LAP_IDLE_TIMEOUT",
77};
78#endif
79
80
81static void irlmp_state_standby (struct lap_cb *, IRLMP_EVENT,
82 struct sk_buff *);
83static void irlmp_state_u_connect(struct lap_cb *, IRLMP_EVENT,
84 struct sk_buff *);
85static void irlmp_state_active (struct lap_cb *, IRLMP_EVENT,
86 struct sk_buff *);
87
88
89static int irlmp_state_disconnected(struct lsap_cb *, IRLMP_EVENT,
90 struct sk_buff *);
91static int irlmp_state_connect (struct lsap_cb *, IRLMP_EVENT,
92 struct sk_buff *);
93static int irlmp_state_connect_pend(struct lsap_cb *, IRLMP_EVENT,
94 struct sk_buff *);
95static int irlmp_state_dtr (struct lsap_cb *, IRLMP_EVENT,
96 struct sk_buff *);
97static int irlmp_state_setup (struct lsap_cb *, IRLMP_EVENT,
98 struct sk_buff *);
99static int irlmp_state_setup_pend (struct lsap_cb *, IRLMP_EVENT,
100 struct sk_buff *);
101
102static void (*lap_state[]) (struct lap_cb *, IRLMP_EVENT, struct sk_buff *) =
103{
104 irlmp_state_standby,
105 irlmp_state_u_connect,
106 irlmp_state_active,
107};
108
109static int (*lsap_state[])( struct lsap_cb *, IRLMP_EVENT, struct sk_buff *) =
110{
111 irlmp_state_disconnected,
112 irlmp_state_connect,
113 irlmp_state_connect_pend,
114 irlmp_state_dtr,
115 irlmp_state_setup,
116 irlmp_state_setup_pend
117};
118
119static inline void irlmp_next_lap_state(struct lap_cb *self,
120 IRLMP_STATE state)
121{
122
123
124
125 self->lap_state = state;
126}
127
128static inline void irlmp_next_lsap_state(struct lsap_cb *self,
129 LSAP_STATE state)
130{
131
132
133
134
135 self->lsap_state = state;
136}
137
138
139int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event,
140 struct sk_buff *skb)
141{
142 IRDA_ASSERT(self != NULL, return -1;);
143 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
144
145 IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n",
146 __func__, irlmp_event[event], irlsap_state[ self->lsap_state]);
147
148 return (*lsap_state[self->lsap_state]) (self, event, skb);
149}
150
151
152
153
154
155
156
157void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event,
158 struct sk_buff *skb)
159{
160 IRDA_ASSERT(self != NULL, return;);
161 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
162
163 IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n", __func__,
164 irlmp_event[event],
165 irlmp_state[self->lap_state]);
166
167 (*lap_state[self->lap_state]) (self, event, skb);
168}
169
170void irlmp_discovery_timer_expired(void *data)
171{
172 IRDA_DEBUG(4, "%s()\n", __func__);
173
174
175 irlmp_do_expiry();
176
177 irlmp_do_discovery(sysctl_discovery_slots);
178
179
180 irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout * HZ);
181}
182
183void irlmp_watchdog_timer_expired(void *data)
184{
185 struct lsap_cb *self = (struct lsap_cb *) data;
186
187 IRDA_DEBUG(2, "%s()\n", __func__);
188
189 IRDA_ASSERT(self != NULL, return;);
190 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
191
192 irlmp_do_lsap_event(self, LM_WATCHDOG_TIMEOUT, NULL);
193}
194
195void irlmp_idle_timer_expired(void *data)
196{
197 struct lap_cb *self = (struct lap_cb *) data;
198
199 IRDA_DEBUG(2, "%s()\n", __func__);
200
201 IRDA_ASSERT(self != NULL, return;);
202 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
203
204 irlmp_do_lap_event(self, LM_LAP_IDLE_TIMEOUT, NULL);
205}
206
207
208
209
210static inline void
211irlmp_do_all_lsap_event(hashbin_t * lsap_hashbin,
212 IRLMP_EVENT event)
213{
214 struct lsap_cb *lsap;
215 struct lsap_cb *lsap_next;
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233 lsap = (struct lsap_cb *) hashbin_get_first(lsap_hashbin);
234
235 while (NULL != hashbin_find_next(lsap_hashbin,
236 (long) lsap,
237 NULL,
238 (void *) &lsap_next) ) {
239 irlmp_do_lsap_event(lsap, event, NULL);
240 lsap = lsap_next;
241 }
242}
243
244
245
246
247
248
249
250
251
252
253
254
255
256static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
257 struct sk_buff *skb)
258{
259 IRDA_DEBUG(4, "%s()\n", __func__);
260 IRDA_ASSERT(self->irlap != NULL, return;);
261
262 switch (event) {
263 case LM_LAP_DISCOVERY_REQUEST:
264
265
266 irlap_discovery_request(self->irlap, &irlmp->discovery_cmd);
267 break;
268 case LM_LAP_CONNECT_INDICATION:
269
270
271
272
273 irlmp_next_lap_state(self, LAP_ACTIVE);
274
275
276 irlap_connect_response(self->irlap, skb);
277 break;
278 case LM_LAP_CONNECT_REQUEST:
279 IRDA_DEBUG(4, "%s() LS_CONNECT_REQUEST\n", __func__);
280
281 irlmp_next_lap_state(self, LAP_U_CONNECT);
282
283
284 irlap_connect_request(self->irlap, self->daddr, NULL, 0);
285 break;
286 case LM_LAP_DISCONNECT_INDICATION:
287 IRDA_DEBUG(4, "%s(), Error LM_LAP_DISCONNECT_INDICATION\n",
288 __func__);
289
290 irlmp_next_lap_state(self, LAP_STANDBY);
291 break;
292 default:
293 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
294 __func__, irlmp_event[event]);
295 break;
296 }
297}
298
299
300
301
302
303
304
305
306static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
307 struct sk_buff *skb)
308{
309 IRDA_DEBUG(2, "%s(), event=%s\n", __func__, irlmp_event[event]);
310
311 switch (event) {
312 case LM_LAP_CONNECT_INDICATION:
313
314
315
316
317 irlmp_next_lap_state(self, LAP_ACTIVE);
318
319
320 irlap_connect_response(self->irlap, skb);
321
322
323 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
324
325
326
327
328 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
329 IRDA_DEBUG(0, "%s() NO LSAPs !\n", __func__);
330 irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
331 }
332 break;
333 case LM_LAP_CONNECT_REQUEST:
334
335 break;
336 case LM_LAP_CONNECT_CONFIRM:
337
338 irlmp_next_lap_state(self, LAP_ACTIVE);
339
340
341 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
342
343
344
345
346 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
347 IRDA_DEBUG(0, "%s() NO LSAPs !\n", __func__);
348 irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
349 }
350 break;
351 case LM_LAP_DISCONNECT_INDICATION:
352 IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_INDICATION\n", __func__);
353 irlmp_next_lap_state(self, LAP_STANDBY);
354
355
356 irlmp_do_all_lsap_event(self->lsaps,
357 LM_LAP_DISCONNECT_INDICATION);
358 break;
359 case LM_LAP_DISCONNECT_REQUEST:
360 IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_REQUEST\n", __func__);
361
362
363
364 if (HASHBIN_GET_SIZE(self->lsaps) <= 1) {
365 irlap_disconnect_request(self->irlap);
366 }
367 break;
368 default:
369 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
370 __func__, irlmp_event[event]);
371 break;
372 }
373}
374
375
376
377
378
379
380
381static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
382 struct sk_buff *skb)
383{
384 IRDA_DEBUG(4, "%s()\n", __func__);
385
386 switch (event) {
387 case LM_LAP_CONNECT_REQUEST:
388 IRDA_DEBUG(4, "%s(), LS_CONNECT_REQUEST\n", __func__);
389
390
391
392
393
394
395
396 irlap_clear_disconnect(self->irlap);
397
398
399
400
401
402
403
404 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
405
406
407 irlmp_do_all_lsap_event(irlmp->unconnected_lsaps,
408 LM_LAP_CONNECT_CONFIRM);
409
410 break;
411 case LM_LAP_DISCONNECT_REQUEST:
412
413
414
415
416
417
418 if (HASHBIN_GET_SIZE(self->lsaps) > 0) {
419
420 irlmp_start_idle_timer(self, sysctl_lap_keepalive_time * HZ / 1000);
421 } else {
422
423
424
425
426
427
428
429
430
431
432
433
434 irlap_disconnect_request(self->irlap);
435 }
436 break;
437 case LM_LAP_IDLE_TIMEOUT:
438 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
439
440 irlap_disconnect_request(self->irlap);
441 }
442 break;
443 case LM_LAP_DISCONNECT_INDICATION:
444 irlmp_next_lap_state(self, LAP_STANDBY);
445
446
447
448
449
450
451
452 irlmp_stop_idle_timer(self);
453
454
455
456
457 irlmp_do_all_lsap_event(self->lsaps,
458 LM_LAP_DISCONNECT_INDICATION);
459
460
461
462
463
464
465
466
467 irlmp_do_expiry();
468 break;
469 default:
470 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
471 __func__, irlmp_event[event]);
472 break;
473 }
474}
475
476
477
478
479
480
481
482
483
484
485
486
487
488static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event,
489 struct sk_buff *skb)
490{
491 int ret = 0;
492
493 IRDA_DEBUG(4, "%s()\n", __func__);
494
495 IRDA_ASSERT(self != NULL, return -1;);
496 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
497
498 switch (event) {
499#ifdef CONFIG_IRDA_ULTRA
500 case LM_UDATA_INDICATION:
501
502
503
504 irlmp_connless_data_indication(self, skb);
505 break;
506#endif
507 case LM_CONNECT_REQUEST:
508 IRDA_DEBUG(4, "%s(), LM_CONNECT_REQUEST\n", __func__);
509
510 if (self->conn_skb) {
511 IRDA_WARNING("%s: busy with another request!\n",
512 __func__);
513 return -EBUSY;
514 }
515
516 skb_get(skb);
517 self->conn_skb = skb;
518
519 irlmp_next_lsap_state(self, LSAP_SETUP_PEND);
520
521
522 irlmp_start_watchdog_timer(self, 5*HZ);
523
524 irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
525 break;
526 case LM_CONNECT_INDICATION:
527 if (self->conn_skb) {
528 IRDA_WARNING("%s: busy with another request!\n",
529 __func__);
530 return -EBUSY;
531 }
532
533 skb_get(skb);
534 self->conn_skb = skb;
535
536 irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);
537
538
539
540
541
542
543
544
545
546
547
548
549 irlmp_start_watchdog_timer(self, 1*HZ);
550
551 irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
552 break;
553 default:
554 IRDA_DEBUG(1, "%s(), Unknown event %s on LSAP %#02x\n",
555 __func__, irlmp_event[event], self->slsap_sel);
556 break;
557 }
558 return ret;
559}
560
561
562
563
564
565
566
567static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
568 struct sk_buff *skb)
569{
570 struct lsap_cb *lsap;
571 int ret = 0;
572
573 IRDA_DEBUG(4, "%s()\n", __func__);
574
575 IRDA_ASSERT(self != NULL, return -1;);
576 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
577
578 switch (event) {
579 case LM_CONNECT_RESPONSE:
580
581
582
583
584 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
585 NULL);
586
587 IRDA_ASSERT(lsap == self, return -1;);
588 IRDA_ASSERT(self->lap != NULL, return -1;);
589 IRDA_ASSERT(self->lap->lsaps != NULL, return -1;);
590
591 hashbin_insert(self->lap->lsaps, (irda_queue_t *) self,
592 (long) self, NULL);
593
594 set_bit(0, &self->connected);
595
596 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
597 self->slsap_sel, CONNECT_CNF, skb);
598
599 del_timer(&self->watchdog_timer);
600
601 irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
602 break;
603 case LM_WATCHDOG_TIMEOUT:
604
605
606 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __func__);
607
608
609 self->lap = NULL;
610 self->dlsap_sel = LSAP_ANY;
611 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
612 break;
613 default:
614
615
616 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
617 __func__, irlmp_event[event], self->slsap_sel);
618 break;
619 }
620 return ret;
621}
622
623
624
625
626
627
628
629static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event,
630 struct sk_buff *skb)
631{
632 struct sk_buff *tx_skb;
633 int ret = 0;
634
635 IRDA_DEBUG(4, "%s()\n", __func__);
636
637 IRDA_ASSERT(self != NULL, return -1;);
638 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
639
640 switch (event) {
641 case LM_CONNECT_REQUEST:
642
643 break;
644 case LM_CONNECT_RESPONSE:
645 IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
646 "no indication issued yet\n", __func__);
647
648 break;
649 case LM_DISCONNECT_REQUEST:
650 IRDA_DEBUG(0, "%s(), LM_DISCONNECT_REQUEST, "
651 "not yet bound to IrLAP connection\n", __func__);
652
653 break;
654 case LM_LAP_CONNECT_CONFIRM:
655 IRDA_DEBUG(4, "%s(), LS_CONNECT_CONFIRM\n", __func__);
656 irlmp_next_lsap_state(self, LSAP_CONNECT);
657
658 tx_skb = self->conn_skb;
659 self->conn_skb = NULL;
660
661 irlmp_connect_indication(self, tx_skb);
662
663 dev_kfree_skb(tx_skb);
664 break;
665 case LM_WATCHDOG_TIMEOUT:
666
667
668
669 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __func__);
670
671
672 self->lap = NULL;
673 self->dlsap_sel = LSAP_ANY;
674 if(self->conn_skb)
675 dev_kfree_skb(self->conn_skb);
676 self->conn_skb = NULL;
677 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
678 break;
679 default:
680
681
682 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
683 __func__, irlmp_event[event], self->slsap_sel);
684 break;
685 }
686 return ret;
687}
688
689
690
691
692
693
694
695static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event,
696 struct sk_buff *skb)
697{
698 LM_REASON reason;
699 int ret = 0;
700
701 IRDA_DEBUG(4, "%s()\n", __func__);
702
703 IRDA_ASSERT(self != NULL, return -1;);
704 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
705 IRDA_ASSERT(self->lap != NULL, return -1;);
706
707 switch (event) {
708 case LM_DATA_REQUEST:
709 irlmp_send_data_pdu(self->lap, self->dlsap_sel,
710 self->slsap_sel, FALSE, skb);
711 break;
712 case LM_DATA_INDICATION:
713 irlmp_data_indication(self, skb);
714 break;
715 case LM_UDATA_REQUEST:
716 IRDA_ASSERT(skb != NULL, return -1;);
717 irlmp_send_data_pdu(self->lap, self->dlsap_sel,
718 self->slsap_sel, TRUE, skb);
719 break;
720 case LM_UDATA_INDICATION:
721 irlmp_udata_indication(self, skb);
722 break;
723 case LM_CONNECT_REQUEST:
724 IRDA_DEBUG(0, "%s(), LM_CONNECT_REQUEST, "
725 "error, LSAP already connected\n", __func__);
726
727 break;
728 case LM_CONNECT_RESPONSE:
729 IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
730 "error, LSAP already connected\n", __func__);
731
732 break;
733 case LM_DISCONNECT_REQUEST:
734 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, self->slsap_sel,
735 DISCONNECT, skb);
736 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
737
738
739
740
741 if (self->lap) {
742 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",
743 __func__);
744 irlmp_do_lap_event(self->lap,
745 LM_LAP_DISCONNECT_REQUEST,
746 NULL);
747 }
748 break;
749 case LM_LAP_DISCONNECT_INDICATION:
750 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
751
752 reason = irlmp_convert_lap_reason(self->lap->reason);
753
754 irlmp_disconnect_indication(self, reason, NULL);
755 break;
756 case LM_DISCONNECT_INDICATION:
757 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
758
759 IRDA_ASSERT(self->lap != NULL, return -1;);
760 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
761
762 IRDA_ASSERT(skb != NULL, return -1;);
763 IRDA_ASSERT(skb->len > 3, return -1;);
764 reason = skb->data[3];
765
766
767 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __func__);
768 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
769
770 irlmp_disconnect_indication(self, reason, skb);
771 break;
772 default:
773 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
774 __func__, irlmp_event[event], self->slsap_sel);
775 break;
776 }
777 return ret;
778}
779
780
781
782
783
784
785
786
787static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,
788 struct sk_buff *skb)
789{
790 LM_REASON reason;
791 int ret = 0;
792
793 IRDA_ASSERT(self != NULL, return -1;);
794 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
795
796 IRDA_DEBUG(4, "%s()\n", __func__);
797
798 switch (event) {
799 case LM_CONNECT_CONFIRM:
800 irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
801
802 del_timer(&self->watchdog_timer);
803
804 irlmp_connect_confirm(self, skb);
805 break;
806 case LM_DISCONNECT_INDICATION:
807 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
808
809 IRDA_ASSERT(self->lap != NULL, return -1;);
810 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
811
812 IRDA_ASSERT(skb != NULL, return -1;);
813 IRDA_ASSERT(skb->len > 3, return -1;);
814 reason = skb->data[3];
815
816
817 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __func__);
818 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
819
820 irlmp_disconnect_indication(self, reason, skb);
821 break;
822 case LM_LAP_DISCONNECT_INDICATION:
823 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
824
825 del_timer(&self->watchdog_timer);
826
827 IRDA_ASSERT(self->lap != NULL, return -1;);
828 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
829
830 reason = irlmp_convert_lap_reason(self->lap->reason);
831
832 irlmp_disconnect_indication(self, reason, skb);
833 break;
834 case LM_WATCHDOG_TIMEOUT:
835 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __func__);
836
837 IRDA_ASSERT(self->lap != NULL, return -1;);
838 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
839 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
840
841 irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
842 break;
843 default:
844 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
845 __func__, irlmp_event[event], self->slsap_sel);
846 break;
847 }
848 return ret;
849}
850
851
852
853
854
855
856
857
858
859static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event,
860 struct sk_buff *skb)
861{
862 struct sk_buff *tx_skb;
863 LM_REASON reason;
864 int ret = 0;
865
866 IRDA_DEBUG(4, "%s()\n", __func__);
867
868 IRDA_ASSERT(self != NULL, return -1;);
869 IRDA_ASSERT(irlmp != NULL, return -1;);
870
871 switch (event) {
872 case LM_LAP_CONNECT_CONFIRM:
873 IRDA_ASSERT(self->conn_skb != NULL, return -1;);
874
875 tx_skb = self->conn_skb;
876 self->conn_skb = NULL;
877
878 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
879 self->slsap_sel, CONNECT_CMD, tx_skb);
880
881 dev_kfree_skb(tx_skb);
882
883 irlmp_next_lsap_state(self, LSAP_SETUP);
884 break;
885 case LM_WATCHDOG_TIMEOUT:
886 IRDA_DEBUG(0, "%s() : WATCHDOG_TIMEOUT !\n", __func__);
887
888 IRDA_ASSERT(self->lap != NULL, return -1;);
889 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
890 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
891
892 irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
893 break;
894 case LM_LAP_DISCONNECT_INDICATION:
895 del_timer( &self->watchdog_timer);
896
897 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
898
899 reason = irlmp_convert_lap_reason(self->lap->reason);
900
901 irlmp_disconnect_indication(self, reason, NULL);
902 break;
903 default:
904 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
905 __func__, irlmp_event[event], self->slsap_sel);
906 break;
907 }
908 return ret;
909}
910