1
2
3
4
5
6
7
8
9
10
11#include "irnet_irda.h"
12#include <linux/sched.h>
13#include <linux/seq_file.h>
14#include <asm/unaligned.h>
15
16
17
18
19
20static void irnet_ppp_disconnect(struct work_struct *work)
21{
22 irnet_socket * self =
23 container_of(work, irnet_socket, disconnect_work);
24
25 if (self == NULL)
26 return;
27
28
29
30
31 if (self->ppp_open && !self->ttp_open && !self->ttp_connect) {
32 ppp_unregister_channel(&self->chan);
33 self->ppp_open = 0;
34 }
35}
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50static void
51irnet_post_event(irnet_socket * ap,
52 irnet_event event,
53 __u32 saddr,
54 __u32 daddr,
55 char * name,
56 __u16 hints)
57{
58 int index;
59
60 DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
61 ap, event, daddr, name);
62
63
64
65
66
67 spin_lock_bh(&irnet_events.spinlock);
68
69
70 index = irnet_events.index;
71 irnet_events.log[index].event = event;
72 irnet_events.log[index].daddr = daddr;
73 irnet_events.log[index].saddr = saddr;
74
75 if(name)
76 strcpy(irnet_events.log[index].name, name);
77 else
78 irnet_events.log[index].name[0] = '\0';
79
80 irnet_events.log[index].hints.word = hints;
81
82 if((ap != (irnet_socket *) NULL) && (ap->ppp_open))
83 irnet_events.log[index].unit = ppp_unit_number(&ap->chan);
84 else
85 irnet_events.log[index].unit = -1;
86
87
88
89
90 irnet_events.index = (index + 1) % IRNET_MAX_EVENTS;
91
92 DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index);
93
94
95 spin_unlock_bh(&irnet_events.spinlock);
96
97
98 wake_up_interruptible_all(&irnet_events.rwait);
99
100 DEXIT(CTRL_TRACE, "\n");
101}
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122static inline int
123irnet_open_tsap(irnet_socket * self)
124{
125 notify_t notify;
126
127 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
128
129 DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");
130
131
132 irda_notify_init(¬ify);
133 notify.connect_confirm = irnet_connect_confirm;
134 notify.connect_indication = irnet_connect_indication;
135 notify.disconnect_indication = irnet_disconnect_indication;
136 notify.data_indication = irnet_data_indication;
137
138 notify.flow_indication = irnet_flow_indication;
139 notify.status_indication = irnet_status_indication;
140 notify.instance = self;
141 strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name));
142
143
144 self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
145 ¬ify);
146 DABORT(self->tsap == NULL, -ENOMEM,
147 IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
148
149
150 self->stsap_sel = self->tsap->stsap_sel;
151
152 DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
153 self->tsap, self->stsap_sel);
154 return 0;
155}
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171static inline __u8
172irnet_ias_to_tsap(irnet_socket * self,
173 int result,
174 struct ias_value * value)
175{
176 __u8 dtsap_sel = 0;
177
178 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
179
180
181 self->errno = 0;
182
183
184 switch(result)
185 {
186
187 case IAS_CLASS_UNKNOWN:
188 case IAS_ATTRIB_UNKNOWN:
189 DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
190 self->errno = -EADDRNOTAVAIL;
191 break;
192
193
194 default :
195 DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
196 self->errno = -EHOSTUNREACH;
197 break;
198
199
200 case IAS_SUCCESS:
201 break;
202 }
203
204
205 if(value != NULL)
206 {
207
208 switch(value->type)
209 {
210 case IAS_INTEGER:
211 DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
212 if(value->t.integer != -1)
213
214 dtsap_sel = value->t.integer;
215 else
216 self->errno = -EADDRNOTAVAIL;
217 break;
218 default:
219 self->errno = -EADDRNOTAVAIL;
220 DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
221 break;
222 }
223
224
225 irias_delete_value(value);
226 }
227 else
228 {
229
230 if(!(self->errno))
231 {
232 DERROR(IRDA_SR_ERROR,
233 "IrDA bug : result == SUCCESS && value == NULL\n");
234 self->errno = -EHOSTUNREACH;
235 }
236 }
237 DEXIT(IRDA_SR_TRACE, "\n");
238
239
240 return(dtsap_sel);
241}
242
243
244
245
246
247
248
249
250
251
252
253
254
255static inline int
256irnet_find_lsap_sel(irnet_socket * self)
257{
258 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
259
260
261 DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");
262
263
264 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
265 irnet_getvalue_confirm);
266
267
268 self->errno = -EHOSTUNREACH;
269
270
271 iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
272 IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
273
274
275
276
277
278
279 DEXIT(IRDA_SR_TRACE, "\n");
280 return 0;
281}
282
283
284
285
286
287
288
289
290static inline int
291irnet_connect_tsap(irnet_socket * self)
292{
293 int err;
294
295 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
296
297
298 err = irnet_open_tsap(self);
299 if(err != 0)
300 {
301 clear_bit(0, &self->ttp_connect);
302 DERROR(IRDA_SR_ERROR, "connect aborted!\n");
303 return(err);
304 }
305
306
307 err = irttp_connect_request(self->tsap, self->dtsap_sel,
308 self->rsaddr, self->daddr, NULL,
309 self->max_sdu_size_rx, NULL);
310 if(err != 0)
311 {
312 clear_bit(0, &self->ttp_connect);
313 DERROR(IRDA_SR_ERROR, "connect aborted!\n");
314 return(err);
315 }
316
317
318
319
320
321
322 DEXIT(IRDA_SR_TRACE, "\n");
323 return(err);
324}
325
326
327
328
329
330
331
332
333
334static inline int
335irnet_discover_next_daddr(irnet_socket * self)
336{
337
338
339 if(self->iriap)
340 {
341 iriap_close(self->iriap);
342 self->iriap = NULL;
343 }
344
345 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
346 irnet_discovervalue_confirm);
347 if(self->iriap == NULL)
348 return -ENOMEM;
349
350
351 self->disco_index++;
352
353
354 if(self->disco_index < self->disco_number)
355 {
356
357 iriap_getvaluebyclass_request(self->iriap,
358 self->discoveries[self->disco_index].saddr,
359 self->discoveries[self->disco_index].daddr,
360 IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
361
362
363
364 return(0);
365 }
366 else
367 return(1);
368}
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393static inline int
394irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
395{
396 int ret;
397
398 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
399
400
401 self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
402 DISCOVERY_DEFAULT_SLOTS);
403
404
405 if(self->discoveries == NULL)
406 {
407 self->disco_number = -1;
408 clear_bit(0, &self->ttp_connect);
409 DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
410 }
411 DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
412 self->discoveries, self->disco_number);
413
414
415 self->disco_index = -1;
416 self->daddr = DEV_ADDR_ANY;
417
418
419 ret = irnet_discover_next_daddr(self);
420 if(ret)
421 {
422
423 if(self->iriap)
424 iriap_close(self->iriap);
425 self->iriap = NULL;
426
427
428 kfree(self->discoveries);
429 self->discoveries = NULL;
430
431 clear_bit(0, &self->ttp_connect);
432 DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
433 }
434
435
436
437 DEXIT(IRDA_SR_TRACE, "\n");
438 return(0);
439}
440
441
442
443
444
445
446
447
448
449static inline int
450irnet_dname_to_daddr(irnet_socket * self)
451{
452 struct irda_device_info *discoveries;
453 int number;
454 int i;
455
456 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
457
458
459 discoveries = irlmp_get_discoveries(&number, 0xffff,
460 DISCOVERY_DEFAULT_SLOTS);
461
462 if(discoveries == NULL)
463 DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
464
465
466
467
468
469
470 for(i = 0; i < number; i++)
471 {
472
473 if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN))
474 {
475
476 self->daddr = discoveries[i].daddr;
477 DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n",
478 self->rname, self->daddr);
479 kfree(discoveries);
480 DEXIT(IRDA_SR_TRACE, "\n");
481 return 0;
482 }
483 }
484
485 DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
486 kfree(discoveries);
487 return(-EADDRNOTAVAIL);
488}
489
490
491
492
493
494
495
496
497
498
499
500
501int
502irda_irnet_create(irnet_socket * self)
503{
504 DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
505
506 self->magic = IRNET_MAGIC;
507
508 self->ttp_open = 0;
509 self->ttp_connect = 0;
510 self->rname[0] = '\0';
511 self->rdaddr = DEV_ADDR_ANY;
512 self->rsaddr = DEV_ADDR_ANY;
513 self->daddr = DEV_ADDR_ANY;
514 self->saddr = DEV_ADDR_ANY;
515 self->max_sdu_size_rx = TTP_SAR_UNBOUND;
516
517
518 self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
519#ifdef DISCOVERY_NOMASK
520 self->mask = 0xffff;
521#else
522 self->mask = irlmp_service_to_hint(S_LAN);
523#endif
524 self->tx_flow = FLOW_START;
525
526 INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);
527
528 DEXIT(IRDA_SOCK_TRACE, "\n");
529 return(0);
530}
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545int
546irda_irnet_connect(irnet_socket * self)
547{
548 int err;
549
550 DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
551
552
553
554
555
556 if(test_and_set_bit(0, &self->ttp_connect))
557 DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
558 if((self->iriap != NULL) || (self->tsap != NULL))
559 DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");
560
561
562
563
564
565 if((irnet_server.running) && (self->q.q_next == NULL))
566 {
567 spin_lock_bh(&irnet_server.spinlock);
568 hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname);
569 spin_unlock_bh(&irnet_server.spinlock);
570 DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname);
571 }
572
573
574 if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
575 {
576
577 if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
578 DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
579
580 }
581 else
582 {
583
584 if(self->rdaddr == DEV_ADDR_ANY)
585 {
586 if((err = irnet_dname_to_daddr(self)) != 0)
587 DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
588 }
589 else
590
591 self->daddr = self->rdaddr;
592
593
594 irnet_find_lsap_sel(self);
595
596 }
597
598
599
600
601
602 DEXIT(IRDA_SOCK_TRACE, "\n");
603 return(0);
604}
605
606
607
608
609
610
611
612
613
614void
615irda_irnet_destroy(irnet_socket * self)
616{
617 DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
618 if(self == NULL)
619 return;
620
621
622
623 if((irnet_server.running) && (self->q.q_next != NULL))
624 {
625 struct irnet_socket * entry;
626 DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n");
627 spin_lock_bh(&irnet_server.spinlock);
628 entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self);
629 self->q.q_next = NULL;
630 spin_unlock_bh(&irnet_server.spinlock);
631 DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n");
632 }
633
634
635 if(test_bit(0, &self->ttp_open))
636 {
637
638
639
640 irnet_post_event(NULL, IRNET_DISCONNECT_TO,
641 self->saddr, self->daddr, self->rname, 0);
642 }
643
644
645
646 clear_bit(0, &self->ttp_connect);
647
648
649 clear_bit(0, &self->ttp_open);
650
651
652 irlmp_unregister_client(self->ckey);
653
654
655 if(self->iriap)
656 {
657 iriap_close(self->iriap);
658 self->iriap = NULL;
659 }
660
661
662 if(self->discoveries != NULL)
663 {
664
665 kfree(self->discoveries);
666 self->discoveries = NULL;
667 }
668
669
670 if(self->tsap)
671 {
672 DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n");
673 irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
674 irttp_close_tsap(self->tsap);
675 self->tsap = NULL;
676 }
677 self->stsap_sel = 0;
678
679 DEXIT(IRDA_SOCK_TRACE, "\n");
680 return;
681}
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701static inline int
702irnet_daddr_to_dname(irnet_socket * self)
703{
704 struct irda_device_info *discoveries;
705 int number;
706 int i;
707
708 DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
709
710
711 discoveries = irlmp_get_discoveries(&number, 0xffff,
712 DISCOVERY_DEFAULT_SLOTS);
713
714 if (discoveries == NULL)
715 DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");
716
717
718 for(i = 0; i < number; i++)
719 {
720
721 if(discoveries[i].daddr == self->daddr)
722 {
723
724 strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
725 self->rname[sizeof(self->rname) - 1] = '\0';
726 DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
727 self->daddr, self->rname);
728 kfree(discoveries);
729 DEXIT(IRDA_SERV_TRACE, "\n");
730 return 0;
731 }
732 }
733
734 DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
735 kfree(discoveries);
736 return(-EADDRNOTAVAIL);
737}
738
739
740
741
742
743
744
745
746
747
748static inline irnet_socket *
749irnet_find_socket(irnet_socket * self)
750{
751 irnet_socket * new = (irnet_socket *) NULL;
752 int err;
753
754 DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
755
756
757 self->daddr = irttp_get_daddr(self->tsap);
758 self->saddr = irttp_get_saddr(self->tsap);
759
760
761 err = irnet_daddr_to_dname(self);
762
763
764 spin_lock_bh(&irnet_server.spinlock);
765
766
767
768 if(err == 0)
769 {
770 new = (irnet_socket *) hashbin_find(irnet_server.list,
771 0, self->rname);
772 if(new)
773 DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches rname ``%s''.\n",
774 new, new->rname);
775 }
776
777
778
779
780
781 if(new == (irnet_socket *) NULL)
782 {
783 new = (irnet_socket *) hashbin_get_first(irnet_server.list);
784 while(new !=(irnet_socket *) NULL)
785 {
786
787 if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
788 {
789
790 DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches daddr %#08x.\n",
791 new, self->daddr);
792 break;
793 }
794 new = (irnet_socket *) hashbin_get_next(irnet_server.list);
795 }
796 }
797
798
799 if(new == (irnet_socket *) NULL)
800 {
801 new = (irnet_socket *) hashbin_get_first(irnet_server.list);
802 while(new !=(irnet_socket *) NULL)
803 {
804
805 if(!(test_bit(0, &new->ttp_open)) && (new->rdaddr == DEV_ADDR_ANY) &&
806 (new->rname[0] == '\0') && (new->ppp_open))
807 {
808
809 DEBUG(IRDA_SERV_INFO, "Socket 0x%p is free.\n",
810 new);
811 break;
812 }
813 new = (irnet_socket *) hashbin_get_next(irnet_server.list);
814 }
815 }
816
817
818 spin_unlock_bh(&irnet_server.spinlock);
819
820 DEXIT(IRDA_SERV_TRACE, " - new = 0x%p\n", new);
821 return new;
822}
823
824
825
826
827
828
829
830
831static inline int
832irnet_connect_socket(irnet_socket * server,
833 irnet_socket * new,
834 struct qos_info * qos,
835 __u32 max_sdu_size,
836 __u8 max_header_size)
837{
838 DENTER(IRDA_SERV_TRACE, "(server=0x%p, new=0x%p)\n",
839 server, new);
840
841
842 new->tsap = irttp_dup(server->tsap, new);
843 DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n");
844
845
846 new->stsap_sel = new->tsap->stsap_sel;
847 new->dtsap_sel = new->tsap->dtsap_sel;
848 new->saddr = irttp_get_saddr(new->tsap);
849 new->daddr = irttp_get_daddr(new->tsap);
850
851 new->max_header_size = max_header_size;
852 new->max_sdu_size_tx = max_sdu_size;
853 new->max_data_size = max_sdu_size;
854#ifdef STREAM_COMPAT
855
856 if(max_sdu_size == 0)
857 new->max_data_size = irttp_get_max_seg_size(new->tsap);
858#endif
859
860
861 irttp_listen(server->tsap);
862
863
864 irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);
865
866
867 set_bit(0, &new->ttp_open);
868
869
870
871 clear_bit(0, &new->ttp_connect);
872 if(new->iriap)
873 {
874 iriap_close(new->iriap);
875 new->iriap = NULL;
876 }
877 if(new->discoveries != NULL)
878 {
879 kfree(new->discoveries);
880 new->discoveries = NULL;
881 }
882
883#ifdef CONNECT_INDIC_KICK
884
885
886
887
888 ppp_output_wakeup(&new->chan);
889#endif
890
891
892 irnet_post_event(new, IRNET_CONNECT_FROM,
893 new->saddr, new->daddr, server->rname, 0);
894
895 DEXIT(IRDA_SERV_TRACE, "\n");
896 return 0;
897}
898
899
900
901
902
903
904
905
906static inline void
907irnet_disconnect_server(irnet_socket * self,
908 struct sk_buff *skb)
909{
910 DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
911
912
913 kfree_skb(skb);
914
915#ifdef FAIL_SEND_DISCONNECT
916
917
918
919 irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
920#endif
921
922
923 irnet_post_event(NULL, IRNET_REQUEST_FROM,
924 self->saddr, self->daddr, self->rname, 0);
925
926
927 irttp_listen(self->tsap);
928
929 DEXIT(IRDA_SERV_TRACE, "\n");
930 return;
931}
932
933
934
935
936
937
938
939
940
941
942static inline int
943irnet_setup_server(void)
944{
945 __u16 hints;
946
947 DENTER(IRDA_SERV_TRACE, "()\n");
948
949
950 irda_irnet_create(&irnet_server.s);
951
952
953 irnet_open_tsap(&irnet_server.s);
954
955
956 irnet_server.s.ppp_open = 0;
957 irnet_server.s.chan.private = NULL;
958 irnet_server.s.file = NULL;
959
960
961
962
963
964
965 hints = irlmp_service_to_hint(S_LAN);
966
967#ifdef ADVERTISE_HINT
968
969 irnet_server.skey = irlmp_register_service(hints);
970#endif
971
972
973 irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
974 irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
975 irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
976 irias_insert_object(irnet_server.ias_obj);
977
978#ifdef DISCOVERY_EVENTS
979
980 irlmp_update_client(irnet_server.s.ckey, hints,
981 irnet_discovery_indication, irnet_expiry_indication,
982 (void *) &irnet_server.s);
983#endif
984
985 DEXIT(IRDA_SERV_TRACE, " - self=0x%p\n", &irnet_server.s);
986 return 0;
987}
988
989
990
991
992
993
994
995
996
997static inline void
998irnet_destroy_server(void)
999{
1000 DENTER(IRDA_SERV_TRACE, "()\n");
1001
1002#ifdef ADVERTISE_HINT
1003
1004 irlmp_unregister_service(irnet_server.skey);
1005#endif
1006
1007
1008 if(irnet_server.ias_obj)
1009 irias_delete_object(irnet_server.ias_obj);
1010
1011
1012 irda_irnet_destroy(&irnet_server.s);
1013
1014 DEXIT(IRDA_SERV_TRACE, "\n");
1015 return;
1016}
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033static int
1034irnet_data_indication(void * instance,
1035 void * sap,
1036 struct sk_buff *skb)
1037{
1038 irnet_socket * ap = (irnet_socket *) instance;
1039 unsigned char * p;
1040 int code = 0;
1041
1042 DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
1043 ap, skb);
1044 DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");
1045
1046
1047 if(!ap->ppp_open)
1048 {
1049 DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n");
1050
1051
1052
1053 return -ENOMEM;
1054 }
1055
1056
1057 p = skb->data;
1058 if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI))
1059 {
1060
1061 if(skb->len < 3)
1062 goto err_exit;
1063 p = skb_pull(skb, 2);
1064 }
1065
1066
1067 if(p[0] & 1)
1068 {
1069
1070 skb_push(skb, 1)[0] = 0;
1071 }
1072 else
1073 if(skb->len < 2)
1074 goto err_exit;
1075
1076
1077
1078
1079 ppp_input(&ap->chan, skb);
1080
1081 DEXIT(IRDA_TCB_TRACE, "\n");
1082 return 0;
1083
1084 err_exit:
1085 DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n");
1086 kfree_skb(skb);
1087 ppp_input_error(&ap->chan, code);
1088 return 0;
1089}
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103static void
1104irnet_disconnect_indication(void * instance,
1105 void * sap,
1106 LM_REASON reason,
1107 struct sk_buff *skb)
1108{
1109 irnet_socket * self = (irnet_socket *) instance;
1110 int test_open;
1111 int test_connect;
1112
1113 DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1114 DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1115
1116
1117 if(skb)
1118 dev_kfree_skb(skb);
1119
1120
1121 test_open = test_and_clear_bit(0, &self->ttp_open);
1122
1123
1124 test_connect = test_and_clear_bit(0, &self->ttp_connect);
1125
1126
1127
1128
1129
1130 if(!(test_open || test_connect))
1131 {
1132 DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
1133 return;
1134 }
1135
1136
1137 if(test_open)
1138 irnet_post_event(self, IRNET_DISCONNECT_FROM,
1139 self->saddr, self->daddr, self->rname, 0);
1140 else
1141
1142 if((self->tsap) && (self != &irnet_server.s))
1143 irnet_post_event(self, IRNET_NOANSWER_FROM,
1144 self->saddr, self->daddr, self->rname, 0);
1145
1146
1147 if((self->tsap) && (self != &irnet_server.s))
1148 {
1149 DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n");
1150 irttp_close_tsap(self->tsap);
1151 self->tsap = NULL;
1152 }
1153
1154 self->stsap_sel = 0;
1155 self->daddr = DEV_ADDR_ANY;
1156 self->tx_flow = FLOW_START;
1157
1158
1159 if(self->ppp_open)
1160 {
1161 if(test_open)
1162 {
1163
1164 schedule_work(&self->disconnect_work);
1165 }
1166 else
1167 {
1168
1169
1170
1171
1172 ppp_output_wakeup(&self->chan);
1173 }
1174 }
1175
1176 DEXIT(IRDA_TCB_TRACE, "\n");
1177}
1178
1179
1180
1181
1182
1183
1184
1185
1186static void
1187irnet_connect_confirm(void * instance,
1188 void * sap,
1189 struct qos_info *qos,
1190 __u32 max_sdu_size,
1191 __u8 max_header_size,
1192 struct sk_buff *skb)
1193{
1194 irnet_socket * self = (irnet_socket *) instance;
1195
1196 DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1197
1198
1199 if(! test_bit(0, &self->ttp_connect))
1200 {
1201 DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !\n");
1202 return;
1203 }
1204
1205
1206 self->max_header_size = max_header_size;
1207
1208
1209 self->max_sdu_size_tx = max_sdu_size;
1210 self->max_data_size = max_sdu_size;
1211#ifdef STREAM_COMPAT
1212 if(max_sdu_size == 0)
1213 self->max_data_size = irttp_get_max_seg_size(self->tsap);
1214#endif
1215
1216
1217 self->saddr = irttp_get_saddr(self->tsap);
1218
1219
1220 set_bit(0, &self->ttp_open);
1221 clear_bit(0, &self->ttp_connect);
1222
1223 ppp_output_wakeup(&self->chan);
1224
1225
1226 if(skb->len > 0)
1227 {
1228#ifdef PASS_CONNECT_PACKETS
1229 DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1230
1231 irnet_data_indication(instance, sap, skb);
1232#else
1233 DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1234 kfree_skb(skb);
1235#endif
1236 }
1237 else
1238 kfree_skb(skb);
1239
1240
1241 irnet_post_event(self, IRNET_CONNECT_TO,
1242 self->saddr, self->daddr, self->rname, 0);
1243
1244 DEXIT(IRDA_TCB_TRACE, "\n");
1245}
1246
1247
1248
1249
1250
1251
1252
1253
1254static void
1255irnet_flow_indication(void * instance,
1256 void * sap,
1257 LOCAL_FLOW flow)
1258{
1259 irnet_socket * self = (irnet_socket *) instance;
1260 LOCAL_FLOW oldflow = self->tx_flow;
1261
1262 DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);
1263
1264
1265 self->tx_flow = flow;
1266
1267
1268 switch(flow)
1269 {
1270 case FLOW_START:
1271 DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n");
1272
1273 if(oldflow == FLOW_STOP)
1274 ppp_output_wakeup(&self->chan);
1275 else
1276 DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!\n");
1277 break;
1278 case FLOW_STOP:
1279 DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n");
1280 break;
1281 default:
1282 DEBUG(IRDA_CB_INFO, "Unknown flow command!\n");
1283 break;
1284 }
1285
1286 DEXIT(IRDA_TCB_TRACE, "\n");
1287}
1288
1289
1290
1291
1292
1293
1294
1295
1296static void
1297irnet_status_indication(void * instance,
1298 LINK_STATUS link,
1299 LOCK_STATUS lock)
1300{
1301 irnet_socket * self = (irnet_socket *) instance;
1302
1303 DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1304 DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1305
1306
1307 switch(link)
1308 {
1309 case STATUS_NO_ACTIVITY:
1310 irnet_post_event(self, IRNET_BLOCKED_LINK,
1311 self->saddr, self->daddr, self->rname, 0);
1312 break;
1313 default:
1314 DEBUG(IRDA_CB_INFO, "Unknown status...\n");
1315 }
1316
1317 DEXIT(IRDA_TCB_TRACE, "\n");
1318}
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334static void
1335irnet_connect_indication(void * instance,
1336 void * sap,
1337 struct qos_info *qos,
1338 __u32 max_sdu_size,
1339 __u8 max_header_size,
1340 struct sk_buff *skb)
1341{
1342 irnet_socket * server = &irnet_server.s;
1343 irnet_socket * new = (irnet_socket *) NULL;
1344
1345 DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
1346 DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
1347 "Invalid instance (0x%p) !!!\n", instance);
1348 DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");
1349
1350
1351 new = irnet_find_socket(server);
1352
1353
1354 if(new == (irnet_socket *) NULL)
1355 {
1356 DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n");
1357 irnet_disconnect_server(server, skb);
1358 return;
1359 }
1360
1361
1362 if(test_bit(0, &new->ttp_open))
1363 {
1364 DEXIT(IRDA_CB_INFO, ": Socket already connected.\n");
1365 irnet_disconnect_server(server, skb);
1366 return;
1367 }
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404 if(0
1405#ifdef ALLOW_SIMULT_CONNECT
1406 || ((irttp_is_primary(server->tsap) == 1)
1407 && (test_and_clear_bit(0, &new->ttp_connect)))
1408#endif
1409 )
1410 {
1411 DERROR(IRDA_CB_ERROR, "Socket already connecting, but going to reuse it !\n");
1412
1413
1414 if(new->tsap != NULL)
1415 {
1416
1417
1418
1419 irttp_close_tsap(new->tsap);
1420 new->tsap = NULL;
1421 }
1422 }
1423 else
1424 {
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 if((test_bit(0, &new->ttp_connect)) || (new->tsap != NULL))
1436 {
1437
1438 DERROR(IRDA_CB_ERROR, "Race condition detected, socket in use, abort connect...\n");
1439 irnet_disconnect_server(server, skb);
1440 return;
1441 }
1442 }
1443
1444
1445 irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);
1446
1447
1448 if(skb->len > 0)
1449 {
1450#ifdef PASS_CONNECT_PACKETS
1451 DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1452
1453 irnet_data_indication(new, new->tsap, skb);
1454#else
1455 DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1456 kfree_skb(skb);
1457#endif
1458 }
1459 else
1460 kfree_skb(skb);
1461
1462 DEXIT(IRDA_TCB_TRACE, "\n");
1463}
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483static void
1484irnet_getvalue_confirm(int result,
1485 __u16 obj_id,
1486 struct ias_value *value,
1487 void * priv)
1488{
1489 irnet_socket * self = (irnet_socket *) priv;
1490
1491 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1492 DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1493
1494
1495
1496 if(! test_bit(0, &self->ttp_connect))
1497 {
1498 DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1499 return;
1500 }
1501
1502
1503 iriap_close(self->iriap);
1504 self->iriap = NULL;
1505
1506
1507 self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
1508
1509
1510 if(self->errno)
1511 {
1512 clear_bit(0, &self->ttp_connect);
1513 DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
1514 return;
1515 }
1516
1517 DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1518 self->daddr, self->dtsap_sel);
1519
1520
1521 irnet_connect_tsap(self);
1522
1523 DEXIT(IRDA_OCB_TRACE, "\n");
1524}
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546static void
1547irnet_discovervalue_confirm(int result,
1548 __u16 obj_id,
1549 struct ias_value *value,
1550 void * priv)
1551{
1552 irnet_socket * self = (irnet_socket *) priv;
1553 __u8 dtsap_sel;
1554
1555 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1556 DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1557
1558
1559
1560 if(! test_bit(0, &self->ttp_connect))
1561 {
1562 DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1563 return;
1564 }
1565
1566
1567 dtsap_sel = irnet_ias_to_tsap(self, result, value);
1568
1569
1570 if(self->errno == 0)
1571 {
1572
1573 if(self->daddr != DEV_ADDR_ANY)
1574 {
1575 DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
1576 }
1577 else
1578 {
1579
1580 self->daddr = self->discoveries[self->disco_index].daddr;
1581 self->dtsap_sel = dtsap_sel;
1582 }
1583 }
1584
1585
1586 if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
1587 {
1588 int ret;
1589
1590
1591 ret = irnet_discover_next_daddr(self);
1592 if(!ret)
1593 {
1594
1595
1596 return;
1597 }
1598
1599 }
1600
1601
1602
1603
1604 iriap_close(self->iriap);
1605 self->iriap = NULL;
1606
1607
1608 DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
1609 self->discoveries);
1610 if(self->discoveries != NULL)
1611 {
1612
1613 kfree(self->discoveries);
1614 self->discoveries = NULL;
1615 }
1616 self->disco_number = -1;
1617
1618
1619 if(self->daddr == DEV_ADDR_ANY)
1620 {
1621 self->daddr = DEV_ADDR_ANY;
1622 clear_bit(0, &self->ttp_connect);
1623 DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
1624 return;
1625 }
1626
1627
1628
1629 DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1630 self->daddr, self->dtsap_sel);
1631
1632
1633 irnet_connect_tsap(self);
1634
1635 DEXIT(IRDA_OCB_TRACE, "\n");
1636}
1637
1638#ifdef DISCOVERY_EVENTS
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661static void
1662irnet_discovery_indication(discinfo_t * discovery,
1663 DISCOVERY_MODE mode,
1664 void * priv)
1665{
1666 irnet_socket * self = &irnet_server.s;
1667
1668 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1669 DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1670 "Invalid instance (0x%p) !!!\n", priv);
1671
1672 DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
1673 discovery->info);
1674
1675
1676 irnet_post_event(NULL, IRNET_DISCOVER,
1677 discovery->saddr, discovery->daddr, discovery->info,
1678 get_unaligned((__u16 *)discovery->hints));
1679
1680 DEXIT(IRDA_OCB_TRACE, "\n");
1681}
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692static void
1693irnet_expiry_indication(discinfo_t * expiry,
1694 DISCOVERY_MODE mode,
1695 void * priv)
1696{
1697 irnet_socket * self = &irnet_server.s;
1698
1699 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1700 DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1701 "Invalid instance (0x%p) !!!\n", priv);
1702
1703 DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
1704 expiry->info);
1705
1706
1707 irnet_post_event(NULL, IRNET_EXPIRE,
1708 expiry->saddr, expiry->daddr, expiry->info,
1709 get_unaligned((__u16 *)expiry->hints));
1710
1711 DEXIT(IRDA_OCB_TRACE, "\n");
1712}
1713#endif
1714
1715
1716
1717
1718
1719
1720
1721
1722#ifdef CONFIG_PROC_FS
1723static int
1724irnet_proc_show(struct seq_file *m, void *v)
1725{
1726 irnet_socket * self;
1727 char * state;
1728 int i = 0;
1729
1730
1731 seq_printf(m, "IrNET server - ");
1732 seq_printf(m, "IrDA state: %s, ",
1733 (irnet_server.running ? "running" : "dead"));
1734 seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
1735 seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
1736
1737
1738 if(!irnet_server.running)
1739 return 0;
1740
1741
1742 spin_lock_bh(&irnet_server.spinlock);
1743
1744
1745 self = (irnet_socket *) hashbin_get_first(irnet_server.list);
1746 while(self != NULL)
1747 {
1748
1749 seq_printf(m, "\nIrNET socket %d - ", i++);
1750
1751
1752 seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname);
1753 seq_printf(m, "daddr: %08x, ", self->rdaddr);
1754 seq_printf(m, "saddr: %08x\n", self->rsaddr);
1755
1756
1757 seq_printf(m, " PPP state: %s",
1758 (self->ppp_open ? "registered" : "unregistered"));
1759 if(self->ppp_open)
1760 {
1761 seq_printf(m, ", unit: ppp%d",
1762 ppp_unit_number(&self->chan));
1763 seq_printf(m, ", channel: %d",
1764 ppp_channel_index(&self->chan));
1765 seq_printf(m, ", mru: %d",
1766 self->mru);
1767
1768 }
1769
1770
1771 if(self->ttp_open)
1772 state = "connected";
1773 else
1774 if(self->tsap != NULL)
1775 state = "connecting";
1776 else
1777 if(self->iriap != NULL)
1778 state = "searching";
1779 else
1780 if(self->ttp_connect)
1781 state = "weird";
1782 else
1783 state = "idle";
1784 seq_printf(m, "\n IrDA state: %s, ", state);
1785 seq_printf(m, "daddr: %08x, ", self->daddr);
1786 seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel);
1787 seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel);
1788
1789
1790 self = (irnet_socket *) hashbin_get_next(irnet_server.list);
1791 }
1792
1793
1794 spin_unlock_bh(&irnet_server.spinlock);
1795
1796 return 0;
1797}
1798
1799static int irnet_proc_open(struct inode *inode, struct file *file)
1800{
1801 return single_open(file, irnet_proc_show, NULL);
1802}
1803
1804static const struct file_operations irnet_proc_fops = {
1805 .owner = THIS_MODULE,
1806 .open = irnet_proc_open,
1807 .read = seq_read,
1808 .llseek = seq_lseek,
1809 .release = single_release,
1810};
1811#endif
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824int __init
1825irda_irnet_init(void)
1826{
1827 int err = 0;
1828
1829 DENTER(MODULE_TRACE, "()\n");
1830
1831
1832 memset(&irnet_server, 0, sizeof(struct irnet_root));
1833
1834
1835 irnet_server.list = hashbin_new(HB_NOLOCK);
1836 DABORT(irnet_server.list == NULL, -ENOMEM,
1837 MODULE_ERROR, "Can't allocate hashbin!\n");
1838
1839 spin_lock_init(&irnet_server.spinlock);
1840
1841
1842 init_waitqueue_head(&irnet_events.rwait);
1843 irnet_events.index = 0;
1844
1845 spin_lock_init(&irnet_events.spinlock);
1846
1847#ifdef CONFIG_PROC_FS
1848
1849 proc_create("irnet", 0, proc_irda, &irnet_proc_fops);
1850#endif
1851
1852
1853 err = irnet_setup_server();
1854
1855 if(!err)
1856
1857 irnet_server.running = 1;
1858
1859 DEXIT(MODULE_TRACE, "\n");
1860 return err;
1861}
1862
1863
1864
1865
1866
1867void __exit
1868irda_irnet_cleanup(void)
1869{
1870 DENTER(MODULE_TRACE, "()\n");
1871
1872
1873 irnet_server.running = 0;
1874
1875#ifdef CONFIG_PROC_FS
1876
1877 remove_proc_entry("irnet", proc_irda);
1878#endif
1879
1880
1881 irnet_destroy_server();
1882
1883
1884 hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);
1885
1886 DEXIT(MODULE_TRACE, "\n");
1887}
1888