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