Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/irda/irnet/irnet_irda.c
15115 views
1
/*
2
* IrNET protocol module : Synchronous PPP over an IrDA socket.
3
*
4
* Jean II - HPL `00 - <[email protected]>
5
*
6
* This file implement the IRDA interface of IrNET.
7
* Basically, we sit on top of IrTTP. We set up IrTTP, IrIAS properly,
8
* and exchange frames with IrTTP.
9
*/
10
11
#include "irnet_irda.h" /* Private header */
12
#include <linux/sched.h>
13
#include <linux/seq_file.h>
14
#include <linux/slab.h>
15
#include <asm/unaligned.h>
16
17
/*
18
* PPP disconnect work: we need to make sure we're in
19
* process context when calling ppp_unregister_channel().
20
*/
21
static void irnet_ppp_disconnect(struct work_struct *work)
22
{
23
irnet_socket * self =
24
container_of(work, irnet_socket, disconnect_work);
25
26
if (self == NULL)
27
return;
28
/*
29
* If we were connected, cleanup & close the PPP
30
* channel, which will kill pppd (hangup) and the rest.
31
*/
32
if (self->ppp_open && !self->ttp_open && !self->ttp_connect) {
33
ppp_unregister_channel(&self->chan);
34
self->ppp_open = 0;
35
}
36
}
37
38
/************************* CONTROL CHANNEL *************************/
39
/*
40
* When ppp is not active, /dev/irnet act as a control channel.
41
* Writing allow to set up the IrDA destination of the IrNET channel,
42
* and any application may be read events happening on IrNET...
43
*/
44
45
/*------------------------------------------------------------------*/
46
/*
47
* Post an event to the control channel...
48
* Put the event in the log, and then wait all process blocked on read
49
* so they can read the log...
50
*/
51
static void
52
irnet_post_event(irnet_socket * ap,
53
irnet_event event,
54
__u32 saddr,
55
__u32 daddr,
56
char * name,
57
__u16 hints)
58
{
59
int index; /* In the log */
60
61
DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
62
ap, event, daddr, name);
63
64
/* Protect this section via spinlock.
65
* Note : as we are the only event producer, we only need to exclude
66
* ourself when touching the log, which is nice and easy.
67
*/
68
spin_lock_bh(&irnet_events.spinlock);
69
70
/* Copy the event in the log */
71
index = irnet_events.index;
72
irnet_events.log[index].event = event;
73
irnet_events.log[index].daddr = daddr;
74
irnet_events.log[index].saddr = saddr;
75
/* Try to copy IrDA nickname */
76
if(name)
77
strcpy(irnet_events.log[index].name, name);
78
else
79
irnet_events.log[index].name[0] = '\0';
80
/* Copy hints */
81
irnet_events.log[index].hints.word = hints;
82
/* Try to get ppp unit number */
83
if((ap != (irnet_socket *) NULL) && (ap->ppp_open))
84
irnet_events.log[index].unit = ppp_unit_number(&ap->chan);
85
else
86
irnet_events.log[index].unit = -1;
87
88
/* Increment the index
89
* Note that we increment the index only after the event is written,
90
* to make sure that the readers don't get garbage... */
91
irnet_events.index = (index + 1) % IRNET_MAX_EVENTS;
92
93
DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index);
94
95
/* Spin lock end */
96
spin_unlock_bh(&irnet_events.spinlock);
97
98
/* Now : wake up everybody waiting for events... */
99
wake_up_interruptible_all(&irnet_events.rwait);
100
101
DEXIT(CTRL_TRACE, "\n");
102
}
103
104
/************************* IRDA SUBROUTINES *************************/
105
/*
106
* These are a bunch of subroutines called from other functions
107
* down there, mostly common code or to improve readability...
108
*
109
* Note : we duplicate quite heavily some routines of af_irda.c,
110
* because our input structure (self) is quite different
111
* (struct irnet instead of struct irda_sock), which make sharing
112
* the same code impossible (at least, without templates).
113
*/
114
115
/*------------------------------------------------------------------*/
116
/*
117
* Function irda_open_tsap (self)
118
*
119
* Open local Transport Service Access Point (TSAP)
120
*
121
* Create a IrTTP instance for us and set all the IrTTP callbacks.
122
*/
123
static inline int
124
irnet_open_tsap(irnet_socket * self)
125
{
126
notify_t notify; /* Callback structure */
127
128
DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
129
130
DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");
131
132
/* Initialize IrTTP callbacks to be used by the IrDA stack */
133
irda_notify_init(&notify);
134
notify.connect_confirm = irnet_connect_confirm;
135
notify.connect_indication = irnet_connect_indication;
136
notify.disconnect_indication = irnet_disconnect_indication;
137
notify.data_indication = irnet_data_indication;
138
/*notify.udata_indication = NULL;*/
139
notify.flow_indication = irnet_flow_indication;
140
notify.status_indication = irnet_status_indication;
141
notify.instance = self;
142
strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name));
143
144
/* Open an IrTTP instance */
145
self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
146
&notify);
147
DABORT(self->tsap == NULL, -ENOMEM,
148
IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
149
150
/* Remember which TSAP selector we actually got */
151
self->stsap_sel = self->tsap->stsap_sel;
152
153
DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
154
self->tsap, self->stsap_sel);
155
return 0;
156
}
157
158
/*------------------------------------------------------------------*/
159
/*
160
* Function irnet_ias_to_tsap (self, result, value)
161
*
162
* Examine an IAS object and extract TSAP
163
*
164
* We do an IAP query to find the TSAP associated with the IrNET service.
165
* When IrIAP pass us the result of the query, this function look at
166
* the return values to check for failures and extract the TSAP if
167
* possible.
168
* Also deallocate value
169
* The failure is in self->errno
170
* Return TSAP or -1
171
*/
172
static inline __u8
173
irnet_ias_to_tsap(irnet_socket * self,
174
int result,
175
struct ias_value * value)
176
{
177
__u8 dtsap_sel = 0; /* TSAP we are looking for */
178
179
DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
180
181
/* By default, no error */
182
self->errno = 0;
183
184
/* Check if request succeeded */
185
switch(result)
186
{
187
/* Standard errors : service not available */
188
case IAS_CLASS_UNKNOWN:
189
case IAS_ATTRIB_UNKNOWN:
190
DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
191
self->errno = -EADDRNOTAVAIL;
192
break;
193
194
/* Other errors, most likely IrDA stack failure */
195
default :
196
DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
197
self->errno = -EHOSTUNREACH;
198
break;
199
200
/* Success : we got what we wanted */
201
case IAS_SUCCESS:
202
break;
203
}
204
205
/* Check what was returned to us */
206
if(value != NULL)
207
{
208
/* What type of argument have we got ? */
209
switch(value->type)
210
{
211
case IAS_INTEGER:
212
DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
213
if(value->t.integer != -1)
214
/* Get the remote TSAP selector */
215
dtsap_sel = value->t.integer;
216
else
217
self->errno = -EADDRNOTAVAIL;
218
break;
219
default:
220
self->errno = -EADDRNOTAVAIL;
221
DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
222
break;
223
}
224
225
/* Cleanup */
226
irias_delete_value(value);
227
}
228
else /* value == NULL */
229
{
230
/* Nothing returned to us - usually result != SUCCESS */
231
if(!(self->errno))
232
{
233
DERROR(IRDA_SR_ERROR,
234
"IrDA bug : result == SUCCESS && value == NULL\n");
235
self->errno = -EHOSTUNREACH;
236
}
237
}
238
DEXIT(IRDA_SR_TRACE, "\n");
239
240
/* Return the TSAP */
241
return dtsap_sel;
242
}
243
244
/*------------------------------------------------------------------*/
245
/*
246
* Function irnet_find_lsap_sel (self)
247
*
248
* Try to lookup LSAP selector in remote LM-IAS
249
*
250
* Basically, we start a IAP query, and then go to sleep. When the query
251
* return, irnet_getvalue_confirm will wake us up, and we can examine the
252
* result of the query...
253
* Note that in some case, the query fail even before we go to sleep,
254
* creating some races...
255
*/
256
static inline int
257
irnet_find_lsap_sel(irnet_socket * self)
258
{
259
DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
260
261
/* This should not happen */
262
DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");
263
264
/* Create an IAP instance, will be closed in irnet_getvalue_confirm() */
265
self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
266
irnet_getvalue_confirm);
267
268
/* Treat unexpected signals as disconnect */
269
self->errno = -EHOSTUNREACH;
270
271
/* Query remote LM-IAS */
272
iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
273
IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
274
275
/* The above request is non-blocking.
276
* After a while, IrDA will call us back in irnet_getvalue_confirm()
277
* We will then call irnet_ias_to_tsap() and finish the
278
* connection procedure */
279
280
DEXIT(IRDA_SR_TRACE, "\n");
281
return 0;
282
}
283
284
/*------------------------------------------------------------------*/
285
/*
286
* Function irnet_connect_tsap (self)
287
*
288
* Initialise the TTP socket and initiate TTP connection
289
*
290
*/
291
static inline int
292
irnet_connect_tsap(irnet_socket * self)
293
{
294
int err;
295
296
DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
297
298
/* Open a local TSAP (an IrTTP instance) */
299
err = irnet_open_tsap(self);
300
if(err != 0)
301
{
302
clear_bit(0, &self->ttp_connect);
303
DERROR(IRDA_SR_ERROR, "connect aborted!\n");
304
return err;
305
}
306
307
/* Connect to remote device */
308
err = irttp_connect_request(self->tsap, self->dtsap_sel,
309
self->rsaddr, self->daddr, NULL,
310
self->max_sdu_size_rx, NULL);
311
if(err != 0)
312
{
313
clear_bit(0, &self->ttp_connect);
314
DERROR(IRDA_SR_ERROR, "connect aborted!\n");
315
return err;
316
}
317
318
/* The above call is non-blocking.
319
* After a while, the IrDA stack will either call us back in
320
* irnet_connect_confirm() or irnet_disconnect_indication()
321
* See you there ;-) */
322
323
DEXIT(IRDA_SR_TRACE, "\n");
324
return err;
325
}
326
327
/*------------------------------------------------------------------*/
328
/*
329
* Function irnet_discover_next_daddr (self)
330
*
331
* Query the IrNET TSAP of the next device in the log.
332
*
333
* Used in the TSAP discovery procedure.
334
*/
335
static inline int
336
irnet_discover_next_daddr(irnet_socket * self)
337
{
338
/* Close the last instance of IrIAP, and open a new one.
339
* We can't reuse the IrIAP instance in the IrIAP callback */
340
if(self->iriap)
341
{
342
iriap_close(self->iriap);
343
self->iriap = NULL;
344
}
345
/* Create a new IAP instance */
346
self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
347
irnet_discovervalue_confirm);
348
if(self->iriap == NULL)
349
return -ENOMEM;
350
351
/* Next discovery - before the call to avoid races */
352
self->disco_index++;
353
354
/* Check if we have one more address to try */
355
if(self->disco_index < self->disco_number)
356
{
357
/* Query remote LM-IAS */
358
iriap_getvaluebyclass_request(self->iriap,
359
self->discoveries[self->disco_index].saddr,
360
self->discoveries[self->disco_index].daddr,
361
IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
362
/* The above request is non-blocking.
363
* After a while, IrDA will call us back in irnet_discovervalue_confirm()
364
* We will then call irnet_ias_to_tsap() and come back here again... */
365
return 0;
366
}
367
else
368
return 1;
369
}
370
371
/*------------------------------------------------------------------*/
372
/*
373
* Function irnet_discover_daddr_and_lsap_sel (self)
374
*
375
* This try to find a device with the requested service.
376
*
377
* Initiate a TSAP discovery procedure.
378
* It basically look into the discovery log. For each address in the list,
379
* it queries the LM-IAS of the device to find if this device offer
380
* the requested service.
381
* If there is more than one node supporting the service, we complain
382
* to the user (it should move devices around).
383
* If we find one node which have the requested TSAP, we connect to it.
384
*
385
* This function just start the whole procedure. It request the discovery
386
* log and submit the first IAS query.
387
* The bulk of the job is handled in irnet_discovervalue_confirm()
388
*
389
* Note : this procedure fails if there is more than one device in range
390
* on the same dongle, because IrLMP doesn't disconnect the LAP when the
391
* last LSAP is closed. Moreover, we would need to wait the LAP
392
* disconnection...
393
*/
394
static inline int
395
irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
396
{
397
int ret;
398
399
DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
400
401
/* Ask lmp for the current discovery log */
402
self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
403
DISCOVERY_DEFAULT_SLOTS);
404
405
/* Check if the we got some results */
406
if(self->discoveries == NULL)
407
{
408
self->disco_number = -1;
409
clear_bit(0, &self->ttp_connect);
410
DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
411
}
412
DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
413
self->discoveries, self->disco_number);
414
415
/* Start with the first discovery */
416
self->disco_index = -1;
417
self->daddr = DEV_ADDR_ANY;
418
419
/* This will fail if the log is empty - this is non-blocking */
420
ret = irnet_discover_next_daddr(self);
421
if(ret)
422
{
423
/* Close IAP */
424
if(self->iriap)
425
iriap_close(self->iriap);
426
self->iriap = NULL;
427
428
/* Cleanup our copy of the discovery log */
429
kfree(self->discoveries);
430
self->discoveries = NULL;
431
432
clear_bit(0, &self->ttp_connect);
433
DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
434
}
435
436
/* Follow me in irnet_discovervalue_confirm() */
437
438
DEXIT(IRDA_SR_TRACE, "\n");
439
return 0;
440
}
441
442
/*------------------------------------------------------------------*/
443
/*
444
* Function irnet_dname_to_daddr (self)
445
*
446
* Convert an IrDA nickname to a valid IrDA address
447
*
448
* It basically look into the discovery log until there is a match.
449
*/
450
static inline int
451
irnet_dname_to_daddr(irnet_socket * self)
452
{
453
struct irda_device_info *discoveries; /* Copy of the discovery log */
454
int number; /* Number of nodes in the log */
455
int i;
456
457
DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
458
459
/* Ask lmp for the current discovery log */
460
discoveries = irlmp_get_discoveries(&number, 0xffff,
461
DISCOVERY_DEFAULT_SLOTS);
462
/* Check if the we got some results */
463
if(discoveries == NULL)
464
DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
465
466
/*
467
* Now, check all discovered devices (if any), and connect
468
* client only about the services that the client is
469
* interested in...
470
*/
471
for(i = 0; i < number; i++)
472
{
473
/* Does the name match ? */
474
if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN))
475
{
476
/* Yes !!! Get it.. */
477
self->daddr = discoveries[i].daddr;
478
DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n",
479
self->rname, self->daddr);
480
kfree(discoveries);
481
DEXIT(IRDA_SR_TRACE, "\n");
482
return 0;
483
}
484
}
485
/* No luck ! */
486
DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
487
kfree(discoveries);
488
return -EADDRNOTAVAIL;
489
}
490
491
492
/************************* SOCKET ROUTINES *************************/
493
/*
494
* This are the main operations on IrNET sockets, basically to create
495
* and destroy IrNET sockets. These are called from the PPP part...
496
*/
497
498
/*------------------------------------------------------------------*/
499
/*
500
* Create a IrNET instance : just initialise some parameters...
501
*/
502
int
503
irda_irnet_create(irnet_socket * self)
504
{
505
DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
506
507
self->magic = IRNET_MAGIC; /* Paranoia */
508
509
self->ttp_open = 0; /* Prevent higher layer from accessing IrTTP */
510
self->ttp_connect = 0; /* Not connecting yet */
511
self->rname[0] = '\0'; /* May be set via control channel */
512
self->rdaddr = DEV_ADDR_ANY; /* May be set via control channel */
513
self->rsaddr = DEV_ADDR_ANY; /* May be set via control channel */
514
self->daddr = DEV_ADDR_ANY; /* Until we get connected */
515
self->saddr = DEV_ADDR_ANY; /* Until we get connected */
516
self->max_sdu_size_rx = TTP_SAR_UNBOUND;
517
518
/* Register as a client with IrLMP */
519
self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
520
#ifdef DISCOVERY_NOMASK
521
self->mask = 0xffff; /* For W2k compatibility */
522
#else /* DISCOVERY_NOMASK */
523
self->mask = irlmp_service_to_hint(S_LAN);
524
#endif /* DISCOVERY_NOMASK */
525
self->tx_flow = FLOW_START; /* Flow control from IrTTP */
526
527
INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);
528
529
DEXIT(IRDA_SOCK_TRACE, "\n");
530
return 0;
531
}
532
533
/*------------------------------------------------------------------*/
534
/*
535
* Connect to the other side :
536
* o convert device name to an address
537
* o find the socket number (dlsap)
538
* o Establish the connection
539
*
540
* Note : We no longer mimic af_irda. The IAS query for finding the TSAP
541
* is done asynchronously, like the TTP connection. This allow us to
542
* call this function from any context (not only process).
543
* The downside is that following what's happening in there is tricky
544
* because it involve various functions all over the place...
545
*/
546
int
547
irda_irnet_connect(irnet_socket * self)
548
{
549
int err;
550
551
DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
552
553
/* Check if we are already trying to connect.
554
* Because irda_irnet_connect() can be called directly by pppd plus
555
* packet retries in ppp_generic and connect may take time, plus we may
556
* race with irnet_connect_indication(), we need to be careful there... */
557
if(test_and_set_bit(0, &self->ttp_connect))
558
DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
559
if((self->iriap != NULL) || (self->tsap != NULL))
560
DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");
561
562
/* Insert ourselves in the hashbin so that the IrNET server can find us.
563
* Notes : 4th arg is string of 32 char max and must be null terminated
564
* When 4th arg is used (string), 3rd arg isn't (int)
565
* Can't re-insert (MUST remove first) so check for that... */
566
if((irnet_server.running) && (self->q.q_next == NULL))
567
{
568
spin_lock_bh(&irnet_server.spinlock);
569
hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname);
570
spin_unlock_bh(&irnet_server.spinlock);
571
DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname);
572
}
573
574
/* If we don't have anything (no address, no name) */
575
if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
576
{
577
/* Try to find a suitable address */
578
if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
579
DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
580
/* In most cases, the call above is non-blocking */
581
}
582
else
583
{
584
/* If we have only the name (no address), try to get an address */
585
if(self->rdaddr == DEV_ADDR_ANY)
586
{
587
if((err = irnet_dname_to_daddr(self)) != 0)
588
DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
589
}
590
else
591
/* Use the requested destination address */
592
self->daddr = self->rdaddr;
593
594
/* Query remote LM-IAS to find LSAP selector */
595
irnet_find_lsap_sel(self);
596
/* The above call is non blocking */
597
}
598
599
/* At this point, we are waiting for the IrDA stack to call us back,
600
* or we have already failed.
601
* We will finish the connection procedure in irnet_connect_tsap().
602
*/
603
DEXIT(IRDA_SOCK_TRACE, "\n");
604
return 0;
605
}
606
607
/*------------------------------------------------------------------*/
608
/*
609
* Function irda_irnet_destroy(self)
610
*
611
* Destroy irnet instance
612
*
613
* Note : this need to be called from a process context.
614
*/
615
void
616
irda_irnet_destroy(irnet_socket * self)
617
{
618
DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
619
if(self == NULL)
620
return;
621
622
/* Remove ourselves from hashbin (if we are queued in hashbin)
623
* Note : `irnet_server.running' protect us from calls in hashbin_delete() */
624
if((irnet_server.running) && (self->q.q_next != NULL))
625
{
626
struct irnet_socket * entry;
627
DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n");
628
spin_lock_bh(&irnet_server.spinlock);
629
entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self);
630
self->q.q_next = NULL;
631
spin_unlock_bh(&irnet_server.spinlock);
632
DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n");
633
}
634
635
/* If we were connected, post a message */
636
if(test_bit(0, &self->ttp_open))
637
{
638
/* Note : as the disconnect comes from ppp_generic, the unit number
639
* doesn't exist anymore when we post the event, so we need to pass
640
* NULL as the first arg... */
641
irnet_post_event(NULL, IRNET_DISCONNECT_TO,
642
self->saddr, self->daddr, self->rname, 0);
643
}
644
645
/* Prevent various IrDA callbacks from messing up things
646
* Need to be first */
647
clear_bit(0, &self->ttp_connect);
648
649
/* Prevent higher layer from accessing IrTTP */
650
clear_bit(0, &self->ttp_open);
651
652
/* Unregister with IrLMP */
653
irlmp_unregister_client(self->ckey);
654
655
/* Unregister with LM-IAS */
656
if(self->iriap)
657
{
658
iriap_close(self->iriap);
659
self->iriap = NULL;
660
}
661
662
/* Cleanup eventual discoveries from connection attempt or control channel */
663
if(self->discoveries != NULL)
664
{
665
/* Cleanup our copy of the discovery log */
666
kfree(self->discoveries);
667
self->discoveries = NULL;
668
}
669
670
/* Close our IrTTP connection */
671
if(self->tsap)
672
{
673
DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n");
674
irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
675
irttp_close_tsap(self->tsap);
676
self->tsap = NULL;
677
}
678
self->stsap_sel = 0;
679
680
DEXIT(IRDA_SOCK_TRACE, "\n");
681
}
682
683
684
/************************** SERVER SOCKET **************************/
685
/*
686
* The IrNET service is composed of one server socket and a variable
687
* number of regular IrNET sockets. The server socket is supposed to
688
* handle incoming connections and redirect them to one IrNET sockets.
689
* It's a superset of the regular IrNET socket, but has a very distinct
690
* behaviour...
691
*/
692
693
/*------------------------------------------------------------------*/
694
/*
695
* Function irnet_daddr_to_dname (self)
696
*
697
* Convert an IrDA address to a IrDA nickname
698
*
699
* It basically look into the discovery log until there is a match.
700
*/
701
static inline int
702
irnet_daddr_to_dname(irnet_socket * self)
703
{
704
struct irda_device_info *discoveries; /* Copy of the discovery log */
705
int number; /* Number of nodes in the log */
706
int i;
707
708
DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
709
710
/* Ask lmp for the current discovery log */
711
discoveries = irlmp_get_discoveries(&number, 0xffff,
712
DISCOVERY_DEFAULT_SLOTS);
713
/* Check if the we got some results */
714
if (discoveries == NULL)
715
DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");
716
717
/* Now, check all discovered devices (if any) */
718
for(i = 0; i < number; i++)
719
{
720
/* Does the name match ? */
721
if(discoveries[i].daddr == self->daddr)
722
{
723
/* Yes !!! Get it.. */
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
/* No luck ! */
734
DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
735
kfree(discoveries);
736
return -EADDRNOTAVAIL;
737
}
738
739
/*------------------------------------------------------------------*/
740
/*
741
* Function irda_find_socket (self)
742
*
743
* Find the correct IrNET socket
744
*
745
* Look into the list of IrNET sockets and finds one with the right
746
* properties...
747
*/
748
static inline irnet_socket *
749
irnet_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
/* Get the addresses of the requester */
757
self->daddr = irttp_get_daddr(self->tsap);
758
self->saddr = irttp_get_saddr(self->tsap);
759
760
/* Try to get the IrDA nickname of the requester */
761
err = irnet_daddr_to_dname(self);
762
763
/* Protect access to the instance list */
764
spin_lock_bh(&irnet_server.spinlock);
765
766
/* So now, try to get an socket having specifically
767
* requested that nickname */
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
/* If no name matches, try to find an socket by the destination address */
778
/* It can be either the requested destination address (set via the
779
* control channel), or the current destination address if the
780
* socket is in the middle of a connection request */
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
/* Does it have the same address ? */
787
if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
788
{
789
/* Yes !!! Get it.. */
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
/* If we don't have any socket, get the first unconnected socket */
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
/* Is it available ? */
805
if(!(test_bit(0, &new->ttp_open)) && (new->rdaddr == DEV_ADDR_ANY) &&
806
(new->rname[0] == '\0') && (new->ppp_open))
807
{
808
/* Yes !!! Get it.. */
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
/* Spin lock end */
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
* Function irda_connect_socket (self)
827
*
828
* Connect an incoming connection to the socket
829
*
830
*/
831
static inline int
832
irnet_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
/* Now attach up the new socket */
842
new->tsap = irttp_dup(server->tsap, new);
843
DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n");
844
845
/* Set up all the relevant parameters on the new socket */
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
/* If we want to receive "stream sockets" */
856
if(max_sdu_size == 0)
857
new->max_data_size = irttp_get_max_seg_size(new->tsap);
858
#endif /* STREAM_COMPAT */
859
860
/* Clean up the original one to keep it in listen state */
861
irttp_listen(server->tsap);
862
863
/* Send a connection response on the new socket */
864
irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);
865
866
/* Allow PPP to send its junk over the new socket... */
867
set_bit(0, &new->ttp_open);
868
869
/* Not connecting anymore, and clean up last possible remains
870
* of connection attempts on the socket */
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
/* As currently we don't block packets in ppp_irnet_send() while passive,
885
* this is not really needed...
886
* Also, not doing it give IrDA a chance to finish the setup properly
887
* before being swamped with packets... */
888
ppp_output_wakeup(&new->chan);
889
#endif /* CONNECT_INDIC_KICK */
890
891
/* Notify the control channel */
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
* Function irda_disconnect_server (self)
902
*
903
* Cleanup the server socket when the incoming connection abort
904
*
905
*/
906
static inline void
907
irnet_disconnect_server(irnet_socket * self,
908
struct sk_buff *skb)
909
{
910
DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
911
912
/* Put the received packet in the black hole */
913
kfree_skb(skb);
914
915
#ifdef FAIL_SEND_DISCONNECT
916
/* Tell the other party we don't want to be connected */
917
/* Hum... Is it the right thing to do ? And do we need to send
918
* a connect response before ? It looks ok without this... */
919
irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
920
#endif /* FAIL_SEND_DISCONNECT */
921
922
/* Notify the control channel (see irnet_find_socket()) */
923
irnet_post_event(NULL, IRNET_REQUEST_FROM,
924
self->saddr, self->daddr, self->rname, 0);
925
926
/* Clean up the server to keep it in listen state */
927
irttp_listen(self->tsap);
928
929
DEXIT(IRDA_SERV_TRACE, "\n");
930
}
931
932
/*------------------------------------------------------------------*/
933
/*
934
* Function irda_setup_server (self)
935
*
936
* Create a IrTTP server and set it up...
937
*
938
* Register the IrLAN hint bit, create a IrTTP instance for us,
939
* set all the IrTTP callbacks and create an IrIAS entry...
940
*/
941
static inline int
942
irnet_setup_server(void)
943
{
944
__u16 hints;
945
946
DENTER(IRDA_SERV_TRACE, "()\n");
947
948
/* Initialise the regular socket part of the server */
949
irda_irnet_create(&irnet_server.s);
950
951
/* Open a local TSAP (an IrTTP instance) for the server */
952
irnet_open_tsap(&irnet_server.s);
953
954
/* PPP part setup */
955
irnet_server.s.ppp_open = 0;
956
irnet_server.s.chan.private = NULL;
957
irnet_server.s.file = NULL;
958
959
/* Get the hint bit corresponding to IrLAN */
960
/* Note : we overload the IrLAN hint bit. As it is only a "hint", and as
961
* we provide roughly the same functionality as IrLAN, this is ok.
962
* In fact, the situation is similar as JetSend overloading the Obex hint
963
*/
964
hints = irlmp_service_to_hint(S_LAN);
965
966
#ifdef ADVERTISE_HINT
967
/* Register with IrLMP as a service (advertise our hint bit) */
968
irnet_server.skey = irlmp_register_service(hints);
969
#endif /* ADVERTISE_HINT */
970
971
/* Register with LM-IAS (so that people can connect to us) */
972
irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
973
irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
974
irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
975
irias_insert_object(irnet_server.ias_obj);
976
977
#ifdef DISCOVERY_EVENTS
978
/* Tell IrLMP we want to be notified of newly discovered nodes */
979
irlmp_update_client(irnet_server.s.ckey, hints,
980
irnet_discovery_indication, irnet_expiry_indication,
981
(void *) &irnet_server.s);
982
#endif
983
984
DEXIT(IRDA_SERV_TRACE, " - self=0x%p\n", &irnet_server.s);
985
return 0;
986
}
987
988
/*------------------------------------------------------------------*/
989
/*
990
* Function irda_destroy_server (self)
991
*
992
* Destroy the IrTTP server...
993
*
994
* Reverse of the previous function...
995
*/
996
static inline void
997
irnet_destroy_server(void)
998
{
999
DENTER(IRDA_SERV_TRACE, "()\n");
1000
1001
#ifdef ADVERTISE_HINT
1002
/* Unregister with IrLMP */
1003
irlmp_unregister_service(irnet_server.skey);
1004
#endif /* ADVERTISE_HINT */
1005
1006
/* Unregister with LM-IAS */
1007
if(irnet_server.ias_obj)
1008
irias_delete_object(irnet_server.ias_obj);
1009
1010
/* Cleanup the socket part */
1011
irda_irnet_destroy(&irnet_server.s);
1012
1013
DEXIT(IRDA_SERV_TRACE, "\n");
1014
}
1015
1016
1017
/************************ IRDA-TTP CALLBACKS ************************/
1018
/*
1019
* When we create a IrTTP instance, we pass to it a set of callbacks
1020
* that IrTTP will call in case of various events.
1021
* We take care of those events here.
1022
*/
1023
1024
/*------------------------------------------------------------------*/
1025
/*
1026
* Function irnet_data_indication (instance, sap, skb)
1027
*
1028
* Received some data from TinyTP. Just queue it on the receive queue
1029
*
1030
*/
1031
static int
1032
irnet_data_indication(void * instance,
1033
void * sap,
1034
struct sk_buff *skb)
1035
{
1036
irnet_socket * ap = (irnet_socket *) instance;
1037
unsigned char * p;
1038
int code = 0;
1039
1040
DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
1041
ap, skb);
1042
DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");
1043
1044
/* Check is ppp is ready to receive our packet */
1045
if(!ap->ppp_open)
1046
{
1047
DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n");
1048
/* When we return error, TTP will need to requeue the skb and
1049
* will stop the sender. IrTTP will stall until we send it a
1050
* flow control request... */
1051
return -ENOMEM;
1052
}
1053
1054
/* strip address/control field if present */
1055
p = skb->data;
1056
if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI))
1057
{
1058
/* chop off address/control */
1059
if(skb->len < 3)
1060
goto err_exit;
1061
p = skb_pull(skb, 2);
1062
}
1063
1064
/* decompress protocol field if compressed */
1065
if(p[0] & 1)
1066
{
1067
/* protocol is compressed */
1068
skb_push(skb, 1)[0] = 0;
1069
}
1070
else
1071
if(skb->len < 2)
1072
goto err_exit;
1073
1074
/* pass to generic ppp layer */
1075
/* Note : how do I know if ppp can accept or not the packet ? This is
1076
* essential if I want to manage flow control smoothly... */
1077
ppp_input(&ap->chan, skb);
1078
1079
DEXIT(IRDA_TCB_TRACE, "\n");
1080
return 0;
1081
1082
err_exit:
1083
DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n");
1084
kfree_skb(skb);
1085
ppp_input_error(&ap->chan, code);
1086
return 0; /* Don't return an error code, only for flow control... */
1087
}
1088
1089
/*------------------------------------------------------------------*/
1090
/*
1091
* Function irnet_disconnect_indication (instance, sap, reason, skb)
1092
*
1093
* Connection has been closed. Chech reason to find out why
1094
*
1095
* Note : there are many cases where we come here :
1096
* o attempted to connect, timeout
1097
* o connected, link is broken, LAP has timeout
1098
* o connected, other side close the link
1099
* o connection request on the server not handled
1100
*/
1101
static void
1102
irnet_disconnect_indication(void * instance,
1103
void * sap,
1104
LM_REASON reason,
1105
struct sk_buff *skb)
1106
{
1107
irnet_socket * self = (irnet_socket *) instance;
1108
int test_open;
1109
int test_connect;
1110
1111
DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1112
DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1113
1114
/* Don't care about it, but let's not leak it */
1115
if(skb)
1116
dev_kfree_skb(skb);
1117
1118
/* Prevent higher layer from accessing IrTTP */
1119
test_open = test_and_clear_bit(0, &self->ttp_open);
1120
/* Not connecting anymore...
1121
* (note : TSAP is open, so IAP callbacks are no longer pending...) */
1122
test_connect = test_and_clear_bit(0, &self->ttp_connect);
1123
1124
/* If both self->ttp_open and self->ttp_connect are NULL, it mean that we
1125
* have a race condition with irda_irnet_destroy() or
1126
* irnet_connect_indication(), so don't mess up tsap...
1127
*/
1128
if(!(test_open || test_connect))
1129
{
1130
DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
1131
return;
1132
}
1133
1134
/* If we were active, notify the control channel */
1135
if(test_open)
1136
irnet_post_event(self, IRNET_DISCONNECT_FROM,
1137
self->saddr, self->daddr, self->rname, 0);
1138
else
1139
/* If we were trying to connect, notify the control channel */
1140
if((self->tsap) && (self != &irnet_server.s))
1141
irnet_post_event(self, IRNET_NOANSWER_FROM,
1142
self->saddr, self->daddr, self->rname, 0);
1143
1144
/* Close our IrTTP connection, cleanup tsap */
1145
if((self->tsap) && (self != &irnet_server.s))
1146
{
1147
DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n");
1148
irttp_close_tsap(self->tsap);
1149
self->tsap = NULL;
1150
}
1151
/* Cleanup the socket in case we want to reconnect in ppp_output_wakeup() */
1152
self->stsap_sel = 0;
1153
self->daddr = DEV_ADDR_ANY;
1154
self->tx_flow = FLOW_START;
1155
1156
/* Deal with the ppp instance if it's still alive */
1157
if(self->ppp_open)
1158
{
1159
if(test_open)
1160
{
1161
/* ppp_unregister_channel() wants a user context. */
1162
schedule_work(&self->disconnect_work);
1163
}
1164
else
1165
{
1166
/* If we were trying to connect, flush (drain) ppp_generic
1167
* Tx queue (most often we have blocked it), which will
1168
* trigger an other attempt to connect. If we are passive,
1169
* this will empty the Tx queue after last try. */
1170
ppp_output_wakeup(&self->chan);
1171
}
1172
}
1173
1174
DEXIT(IRDA_TCB_TRACE, "\n");
1175
}
1176
1177
/*------------------------------------------------------------------*/
1178
/*
1179
* Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb)
1180
*
1181
* Connections has been confirmed by the remote device
1182
*
1183
*/
1184
static void
1185
irnet_connect_confirm(void * instance,
1186
void * sap,
1187
struct qos_info *qos,
1188
__u32 max_sdu_size,
1189
__u8 max_header_size,
1190
struct sk_buff *skb)
1191
{
1192
irnet_socket * self = (irnet_socket *) instance;
1193
1194
DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1195
1196
/* Check if socket is closing down (via irda_irnet_destroy()) */
1197
if(! test_bit(0, &self->ttp_connect))
1198
{
1199
DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !\n");
1200
return;
1201
}
1202
1203
/* How much header space do we need to reserve */
1204
self->max_header_size = max_header_size;
1205
1206
/* IrTTP max SDU size in transmit direction */
1207
self->max_sdu_size_tx = max_sdu_size;
1208
self->max_data_size = max_sdu_size;
1209
#ifdef STREAM_COMPAT
1210
if(max_sdu_size == 0)
1211
self->max_data_size = irttp_get_max_seg_size(self->tsap);
1212
#endif /* STREAM_COMPAT */
1213
1214
/* At this point, IrLMP has assigned our source address */
1215
self->saddr = irttp_get_saddr(self->tsap);
1216
1217
/* Allow higher layer to access IrTTP */
1218
set_bit(0, &self->ttp_open);
1219
clear_bit(0, &self->ttp_connect); /* Not racy, IrDA traffic is serial */
1220
/* Give a kick in the ass of ppp_generic so that he sends us some data */
1221
ppp_output_wakeup(&self->chan);
1222
1223
/* Check size of received packet */
1224
if(skb->len > 0)
1225
{
1226
#ifdef PASS_CONNECT_PACKETS
1227
DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1228
/* Try to pass it to PPP */
1229
irnet_data_indication(instance, sap, skb);
1230
#else /* PASS_CONNECT_PACKETS */
1231
DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1232
kfree_skb(skb); /* Note : will be optimised with other kfree... */
1233
#endif /* PASS_CONNECT_PACKETS */
1234
}
1235
else
1236
kfree_skb(skb);
1237
1238
/* Notify the control channel */
1239
irnet_post_event(self, IRNET_CONNECT_TO,
1240
self->saddr, self->daddr, self->rname, 0);
1241
1242
DEXIT(IRDA_TCB_TRACE, "\n");
1243
}
1244
1245
/*------------------------------------------------------------------*/
1246
/*
1247
* Function irnet_flow_indication (instance, sap, flow)
1248
*
1249
* Used by TinyTP to tell us if it can accept more data or not
1250
*
1251
*/
1252
static void
1253
irnet_flow_indication(void * instance,
1254
void * sap,
1255
LOCAL_FLOW flow)
1256
{
1257
irnet_socket * self = (irnet_socket *) instance;
1258
LOCAL_FLOW oldflow = self->tx_flow;
1259
1260
DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);
1261
1262
/* Update our state */
1263
self->tx_flow = flow;
1264
1265
/* Check what IrTTP want us to do... */
1266
switch(flow)
1267
{
1268
case FLOW_START:
1269
DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n");
1270
/* Check if we really need to wake up PPP */
1271
if(oldflow == FLOW_STOP)
1272
ppp_output_wakeup(&self->chan);
1273
else
1274
DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!\n");
1275
break;
1276
case FLOW_STOP:
1277
DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n");
1278
break;
1279
default:
1280
DEBUG(IRDA_CB_INFO, "Unknown flow command!\n");
1281
break;
1282
}
1283
1284
DEXIT(IRDA_TCB_TRACE, "\n");
1285
}
1286
1287
/*------------------------------------------------------------------*/
1288
/*
1289
* Function irnet_status_indication (instance, sap, reason, skb)
1290
*
1291
* Link (IrLAP) status report.
1292
*
1293
*/
1294
static void
1295
irnet_status_indication(void * instance,
1296
LINK_STATUS link,
1297
LOCK_STATUS lock)
1298
{
1299
irnet_socket * self = (irnet_socket *) instance;
1300
1301
DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1302
DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1303
1304
/* We can only get this event if we are connected */
1305
switch(link)
1306
{
1307
case STATUS_NO_ACTIVITY:
1308
irnet_post_event(self, IRNET_BLOCKED_LINK,
1309
self->saddr, self->daddr, self->rname, 0);
1310
break;
1311
default:
1312
DEBUG(IRDA_CB_INFO, "Unknown status...\n");
1313
}
1314
1315
DEXIT(IRDA_TCB_TRACE, "\n");
1316
}
1317
1318
/*------------------------------------------------------------------*/
1319
/*
1320
* Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata)
1321
*
1322
* Incoming connection
1323
*
1324
* In theory, this function is called only on the server socket.
1325
* Some other node is attempting to connect to the IrNET service, and has
1326
* sent a connection request on our server socket.
1327
* We just redirect the connection to the relevant IrNET socket.
1328
*
1329
* Note : we also make sure that between 2 irnet nodes, there can
1330
* exist only one irnet connection.
1331
*/
1332
static void
1333
irnet_connect_indication(void * instance,
1334
void * sap,
1335
struct qos_info *qos,
1336
__u32 max_sdu_size,
1337
__u8 max_header_size,
1338
struct sk_buff *skb)
1339
{
1340
irnet_socket * server = &irnet_server.s;
1341
irnet_socket * new = (irnet_socket *) NULL;
1342
1343
DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
1344
DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
1345
"Invalid instance (0x%p) !!!\n", instance);
1346
DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");
1347
1348
/* Try to find the most appropriate IrNET socket */
1349
new = irnet_find_socket(server);
1350
1351
/* After all this hard work, do we have an socket ? */
1352
if(new == (irnet_socket *) NULL)
1353
{
1354
DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n");
1355
irnet_disconnect_server(server, skb);
1356
return;
1357
}
1358
1359
/* Is the socket already busy ? */
1360
if(test_bit(0, &new->ttp_open))
1361
{
1362
DEXIT(IRDA_CB_INFO, ": Socket already connected.\n");
1363
irnet_disconnect_server(server, skb);
1364
return;
1365
}
1366
1367
/* The following code is a bit tricky, so need comments ;-)
1368
*/
1369
/* If ttp_connect is set, the socket is trying to connect to the other
1370
* end and may have sent a IrTTP connection request and is waiting for
1371
* a connection response (that may never come).
1372
* Now, the pain is that the socket may have opened a tsap and is
1373
* waiting on it, while the other end is trying to connect to it on
1374
* another tsap.
1375
* Because IrNET can be peer to peer, we need to workaround this.
1376
* Furthermore, the way the irnetd script is implemented, the
1377
* target will create a second IrNET connection back to the
1378
* originator and expect the originator to bind this new connection
1379
* to the original PPPD instance.
1380
* And of course, if we don't use irnetd, we can have a race when
1381
* both side try to connect simultaneously, which could leave both
1382
* connections half closed (yuck).
1383
* Conclusions :
1384
* 1) The "originator" must accept the new connection and get rid
1385
* of the old one so that irnetd works
1386
* 2) One side must deny the new connection to avoid races,
1387
* but both side must agree on which side it is...
1388
* Most often, the originator is primary at the LAP layer.
1389
* Jean II
1390
*/
1391
/* Now, let's look at the way I wrote the test...
1392
* We need to clear up the ttp_connect flag atomically to prevent
1393
* irnet_disconnect_indication() to mess up the tsap we are going to close.
1394
* We want to clear the ttp_connect flag only if we close the tsap,
1395
* otherwise we will never close it, so we need to check for primary
1396
* *before* doing the test on the flag.
1397
* And of course, ALLOW_SIMULT_CONNECT can disable this entirely...
1398
* Jean II
1399
*/
1400
1401
/* Socket already connecting ? On primary ? */
1402
if(0
1403
#ifdef ALLOW_SIMULT_CONNECT
1404
|| ((irttp_is_primary(server->tsap) == 1) && /* primary */
1405
(test_and_clear_bit(0, &new->ttp_connect)))
1406
#endif /* ALLOW_SIMULT_CONNECT */
1407
)
1408
{
1409
DERROR(IRDA_CB_ERROR, "Socket already connecting, but going to reuse it !\n");
1410
1411
/* Cleanup the old TSAP if necessary - IrIAP will be cleaned up later */
1412
if(new->tsap != NULL)
1413
{
1414
/* Close the old connection the new socket was attempting,
1415
* so that we can hook it up to the new connection.
1416
* It's now safe to do it... */
1417
irttp_close_tsap(new->tsap);
1418
new->tsap = NULL;
1419
}
1420
}
1421
else
1422
{
1423
/* Three options :
1424
* 1) socket was not connecting or connected : ttp_connect should be 0.
1425
* 2) we don't want to connect the socket because we are secondary or
1426
* ALLOW_SIMULT_CONNECT is undefined. ttp_connect should be 1.
1427
* 3) we are half way in irnet_disconnect_indication(), and it's a
1428
* nice race condition... Fortunately, we can detect that by checking
1429
* if tsap is still alive. On the other hand, we can't be in
1430
* irda_irnet_destroy() otherwise we would not have found this
1431
* socket in the hashbin.
1432
* Jean II */
1433
if((test_bit(0, &new->ttp_connect)) || (new->tsap != NULL))
1434
{
1435
/* Don't mess this socket, somebody else in in charge... */
1436
DERROR(IRDA_CB_ERROR, "Race condition detected, socket in use, abort connect...\n");
1437
irnet_disconnect_server(server, skb);
1438
return;
1439
}
1440
}
1441
1442
/* So : at this point, we have a socket, and it is idle. Good ! */
1443
irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);
1444
1445
/* Check size of received packet */
1446
if(skb->len > 0)
1447
{
1448
#ifdef PASS_CONNECT_PACKETS
1449
DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1450
/* Try to pass it to PPP */
1451
irnet_data_indication(new, new->tsap, skb);
1452
#else /* PASS_CONNECT_PACKETS */
1453
DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1454
kfree_skb(skb); /* Note : will be optimised with other kfree... */
1455
#endif /* PASS_CONNECT_PACKETS */
1456
}
1457
else
1458
kfree_skb(skb);
1459
1460
DEXIT(IRDA_TCB_TRACE, "\n");
1461
}
1462
1463
1464
/********************** IRDA-IAS/LMP CALLBACKS **********************/
1465
/*
1466
* These are the callbacks called by other layers of the IrDA stack,
1467
* mainly LMP for discovery and IAS for name queries.
1468
*/
1469
1470
/*------------------------------------------------------------------*/
1471
/*
1472
* Function irnet_getvalue_confirm (result, obj_id, value, priv)
1473
*
1474
* Got answer from remote LM-IAS, just connect
1475
*
1476
* This is the reply to a IAS query we were doing to find the TSAP of
1477
* the device we want to connect to.
1478
* If we have found a valid TSAP, just initiate the TTP connection
1479
* on this TSAP.
1480
*/
1481
static void
1482
irnet_getvalue_confirm(int result,
1483
__u16 obj_id,
1484
struct ias_value *value,
1485
void * priv)
1486
{
1487
irnet_socket * self = (irnet_socket *) priv;
1488
1489
DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1490
DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1491
1492
/* Check if already connected (via irnet_connect_socket())
1493
* or socket is closing down (via irda_irnet_destroy()) */
1494
if(! test_bit(0, &self->ttp_connect))
1495
{
1496
DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1497
return;
1498
}
1499
1500
/* We probably don't need to make any more queries */
1501
iriap_close(self->iriap);
1502
self->iriap = NULL;
1503
1504
/* Post process the IAS reply */
1505
self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
1506
1507
/* If error, just go out */
1508
if(self->errno)
1509
{
1510
clear_bit(0, &self->ttp_connect);
1511
DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
1512
return;
1513
}
1514
1515
DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1516
self->daddr, self->dtsap_sel);
1517
1518
/* Start up TTP - non blocking */
1519
irnet_connect_tsap(self);
1520
1521
DEXIT(IRDA_OCB_TRACE, "\n");
1522
}
1523
1524
/*------------------------------------------------------------------*/
1525
/*
1526
* Function irnet_discovervalue_confirm (result, obj_id, value, priv)
1527
*
1528
* Handle the TSAP discovery procedure state machine.
1529
* Got answer from remote LM-IAS, try next device
1530
*
1531
* We are doing a TSAP discovery procedure, and we got an answer to
1532
* a IAS query we were doing to find the TSAP on one of the address
1533
* in the discovery log.
1534
*
1535
* If we have found a valid TSAP for the first time, save it. If it's
1536
* not the first time we found one, complain.
1537
*
1538
* If we have more addresses in the log, just initiate a new query.
1539
* Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
1540
*
1541
* Otherwise, wrap up the procedure (cleanup), check if we have found
1542
* any device and connect to it.
1543
*/
1544
static void
1545
irnet_discovervalue_confirm(int result,
1546
__u16 obj_id,
1547
struct ias_value *value,
1548
void * priv)
1549
{
1550
irnet_socket * self = (irnet_socket *) priv;
1551
__u8 dtsap_sel; /* TSAP we are looking for */
1552
1553
DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1554
DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1555
1556
/* Check if already connected (via irnet_connect_socket())
1557
* or socket is closing down (via irda_irnet_destroy()) */
1558
if(! test_bit(0, &self->ttp_connect))
1559
{
1560
DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1561
return;
1562
}
1563
1564
/* Post process the IAS reply */
1565
dtsap_sel = irnet_ias_to_tsap(self, result, value);
1566
1567
/* Have we got something ? */
1568
if(self->errno == 0)
1569
{
1570
/* We found the requested service */
1571
if(self->daddr != DEV_ADDR_ANY)
1572
{
1573
DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
1574
}
1575
else
1576
{
1577
/* First time we found that one, save it ! */
1578
self->daddr = self->discoveries[self->disco_index].daddr;
1579
self->dtsap_sel = dtsap_sel;
1580
}
1581
}
1582
1583
/* If no failure */
1584
if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
1585
{
1586
int ret;
1587
1588
/* Search the next node */
1589
ret = irnet_discover_next_daddr(self);
1590
if(!ret)
1591
{
1592
/* In this case, the above request was non-blocking.
1593
* We will return here after a while... */
1594
return;
1595
}
1596
/* In this case, we have processed the last discovery item */
1597
}
1598
1599
/* No more queries to be done (failure or last one) */
1600
1601
/* We probably don't need to make any more queries */
1602
iriap_close(self->iriap);
1603
self->iriap = NULL;
1604
1605
/* No more items : remove the log and signal termination */
1606
DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
1607
self->discoveries);
1608
if(self->discoveries != NULL)
1609
{
1610
/* Cleanup our copy of the discovery log */
1611
kfree(self->discoveries);
1612
self->discoveries = NULL;
1613
}
1614
self->disco_number = -1;
1615
1616
/* Check out what we found */
1617
if(self->daddr == DEV_ADDR_ANY)
1618
{
1619
self->daddr = DEV_ADDR_ANY;
1620
clear_bit(0, &self->ttp_connect);
1621
DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
1622
return;
1623
}
1624
1625
/* We have a valid address - just connect */
1626
1627
DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1628
self->daddr, self->dtsap_sel);
1629
1630
/* Start up TTP - non blocking */
1631
irnet_connect_tsap(self);
1632
1633
DEXIT(IRDA_OCB_TRACE, "\n");
1634
}
1635
1636
#ifdef DISCOVERY_EVENTS
1637
/*------------------------------------------------------------------*/
1638
/*
1639
* Function irnet_discovery_indication (discovery)
1640
*
1641
* Got a discovery indication from IrLMP, post an event
1642
*
1643
* Note : IrLMP take care of matching the hint mask for us, and also
1644
* check if it is a "new" node for us...
1645
*
1646
* As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
1647
* nodes, so it's only at connection time that we will know if the
1648
* node support IrNET, IrLAN or both. The other solution is to check
1649
* in IAS the PNP ids and service name.
1650
* Note : even if a node support IrNET (or IrLAN), it's no guarantee
1651
* that we will be able to connect to it, the node might already be
1652
* busy...
1653
*
1654
* One last thing : in some case, this function will trigger duplicate
1655
* discovery events. On the other hand, we should catch all
1656
* discoveries properly (i.e. not miss one). Filtering duplicate here
1657
* is to messy, so we leave that to user space...
1658
*/
1659
static void
1660
irnet_discovery_indication(discinfo_t * discovery,
1661
DISCOVERY_MODE mode,
1662
void * priv)
1663
{
1664
irnet_socket * self = &irnet_server.s;
1665
1666
DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1667
DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1668
"Invalid instance (0x%p) !!!\n", priv);
1669
1670
DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
1671
discovery->info);
1672
1673
/* Notify the control channel */
1674
irnet_post_event(NULL, IRNET_DISCOVER,
1675
discovery->saddr, discovery->daddr, discovery->info,
1676
get_unaligned((__u16 *)discovery->hints));
1677
1678
DEXIT(IRDA_OCB_TRACE, "\n");
1679
}
1680
1681
/*------------------------------------------------------------------*/
1682
/*
1683
* Function irnet_expiry_indication (expiry)
1684
*
1685
* Got a expiry indication from IrLMP, post an event
1686
*
1687
* Note : IrLMP take care of matching the hint mask for us, we only
1688
* check if it is a "new" node...
1689
*/
1690
static void
1691
irnet_expiry_indication(discinfo_t * expiry,
1692
DISCOVERY_MODE mode,
1693
void * priv)
1694
{
1695
irnet_socket * self = &irnet_server.s;
1696
1697
DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1698
DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1699
"Invalid instance (0x%p) !!!\n", priv);
1700
1701
DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
1702
expiry->info);
1703
1704
/* Notify the control channel */
1705
irnet_post_event(NULL, IRNET_EXPIRE,
1706
expiry->saddr, expiry->daddr, expiry->info,
1707
get_unaligned((__u16 *)expiry->hints));
1708
1709
DEXIT(IRDA_OCB_TRACE, "\n");
1710
}
1711
#endif /* DISCOVERY_EVENTS */
1712
1713
1714
/*********************** PROC ENTRY CALLBACKS ***********************/
1715
/*
1716
* We create a instance in the /proc filesystem, and here we take care
1717
* of that...
1718
*/
1719
1720
#ifdef CONFIG_PROC_FS
1721
static int
1722
irnet_proc_show(struct seq_file *m, void *v)
1723
{
1724
irnet_socket * self;
1725
char * state;
1726
int i = 0;
1727
1728
/* Get the IrNET server information... */
1729
seq_printf(m, "IrNET server - ");
1730
seq_printf(m, "IrDA state: %s, ",
1731
(irnet_server.running ? "running" : "dead"));
1732
seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
1733
seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
1734
1735
/* Do we need to continue ? */
1736
if(!irnet_server.running)
1737
return 0;
1738
1739
/* Protect access to the instance list */
1740
spin_lock_bh(&irnet_server.spinlock);
1741
1742
/* Get the sockets one by one... */
1743
self = (irnet_socket *) hashbin_get_first(irnet_server.list);
1744
while(self != NULL)
1745
{
1746
/* Start printing info about the socket. */
1747
seq_printf(m, "\nIrNET socket %d - ", i++);
1748
1749
/* First, get the requested configuration */
1750
seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname);
1751
seq_printf(m, "daddr: %08x, ", self->rdaddr);
1752
seq_printf(m, "saddr: %08x\n", self->rsaddr);
1753
1754
/* Second, get all the PPP info */
1755
seq_printf(m, " PPP state: %s",
1756
(self->ppp_open ? "registered" : "unregistered"));
1757
if(self->ppp_open)
1758
{
1759
seq_printf(m, ", unit: ppp%d",
1760
ppp_unit_number(&self->chan));
1761
seq_printf(m, ", channel: %d",
1762
ppp_channel_index(&self->chan));
1763
seq_printf(m, ", mru: %d",
1764
self->mru);
1765
/* Maybe add self->flags ? Later... */
1766
}
1767
1768
/* Then, get all the IrDA specific info... */
1769
if(self->ttp_open)
1770
state = "connected";
1771
else
1772
if(self->tsap != NULL)
1773
state = "connecting";
1774
else
1775
if(self->iriap != NULL)
1776
state = "searching";
1777
else
1778
if(self->ttp_connect)
1779
state = "weird";
1780
else
1781
state = "idle";
1782
seq_printf(m, "\n IrDA state: %s, ", state);
1783
seq_printf(m, "daddr: %08x, ", self->daddr);
1784
seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel);
1785
seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel);
1786
1787
/* Next socket, please... */
1788
self = (irnet_socket *) hashbin_get_next(irnet_server.list);
1789
}
1790
1791
/* Spin lock end */
1792
spin_unlock_bh(&irnet_server.spinlock);
1793
1794
return 0;
1795
}
1796
1797
static int irnet_proc_open(struct inode *inode, struct file *file)
1798
{
1799
return single_open(file, irnet_proc_show, NULL);
1800
}
1801
1802
static const struct file_operations irnet_proc_fops = {
1803
.owner = THIS_MODULE,
1804
.open = irnet_proc_open,
1805
.read = seq_read,
1806
.llseek = seq_lseek,
1807
.release = single_release,
1808
};
1809
#endif /* PROC_FS */
1810
1811
1812
/********************** CONFIGURATION/CLEANUP **********************/
1813
/*
1814
* Initialisation and teardown of the IrDA part, called at module
1815
* insertion and removal...
1816
*/
1817
1818
/*------------------------------------------------------------------*/
1819
/*
1820
* Prepare the IrNET layer for operation...
1821
*/
1822
int __init
1823
irda_irnet_init(void)
1824
{
1825
int err = 0;
1826
1827
DENTER(MODULE_TRACE, "()\n");
1828
1829
/* Pure paranoia - should be redundant */
1830
memset(&irnet_server, 0, sizeof(struct irnet_root));
1831
1832
/* Setup start of irnet instance list */
1833
irnet_server.list = hashbin_new(HB_NOLOCK);
1834
DABORT(irnet_server.list == NULL, -ENOMEM,
1835
MODULE_ERROR, "Can't allocate hashbin!\n");
1836
/* Init spinlock for instance list */
1837
spin_lock_init(&irnet_server.spinlock);
1838
1839
/* Initialise control channel */
1840
init_waitqueue_head(&irnet_events.rwait);
1841
irnet_events.index = 0;
1842
/* Init spinlock for event logging */
1843
spin_lock_init(&irnet_events.spinlock);
1844
1845
#ifdef CONFIG_PROC_FS
1846
/* Add a /proc file for irnet infos */
1847
proc_create("irnet", 0, proc_irda, &irnet_proc_fops);
1848
#endif /* CONFIG_PROC_FS */
1849
1850
/* Setup the IrNET server */
1851
err = irnet_setup_server();
1852
1853
if(!err)
1854
/* We are no longer functional... */
1855
irnet_server.running = 1;
1856
1857
DEXIT(MODULE_TRACE, "\n");
1858
return err;
1859
}
1860
1861
/*------------------------------------------------------------------*/
1862
/*
1863
* Cleanup at exit...
1864
*/
1865
void __exit
1866
irda_irnet_cleanup(void)
1867
{
1868
DENTER(MODULE_TRACE, "()\n");
1869
1870
/* We are no longer there... */
1871
irnet_server.running = 0;
1872
1873
#ifdef CONFIG_PROC_FS
1874
/* Remove our /proc file */
1875
remove_proc_entry("irnet", proc_irda);
1876
#endif /* CONFIG_PROC_FS */
1877
1878
/* Remove our IrNET server from existence */
1879
irnet_destroy_server();
1880
1881
/* Remove all instances of IrNET socket still present */
1882
hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);
1883
1884
DEXIT(MODULE_TRACE, "\n");
1885
}
1886
1887