1 /*********************************************************************
5 * Description: IrDA Link Management Protocol (LMP) layer
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 17 20:54:32 1997
9 * Modified at: Wed Jan 5 11:26:03 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
25 ********************************************************************/
27 #include <linux/config.h>
28 #include <linux/slab.h>
29 #include <linux/string.h>
30 #include <linux/skbuff.h>
31 #include <linux/types.h>
32 #include <linux/proc_fs.h>
33 #include <linux/init.h>
34 #include <linux/kmod.h>
35 #include <linux/random.h>
37 #include <net/irda/irda.h>
38 #include <net/irda/timer.h>
39 #include <net/irda/qos.h>
40 #include <net/irda/irlap.h>
41 #include <net/irda/iriap.h>
42 #include <net/irda/irlmp.h>
43 #include <net/irda/irlmp_frame.h>
45 /* Master structure */
46 struct irlmp_cb
*irlmp
= NULL
;
48 /* These can be altered by the sysctl interface */
49 int sysctl_discovery
= 0;
50 int sysctl_discovery_timeout
= 3; /* 3 seconds by default */
51 int sysctl_discovery_slots
= 6; /* 6 slots by default */
52 int sysctl_lap_keepalive_time
= LM_IDLE_TIMEOUT
* 1000 / HZ
;
53 char sysctl_devname
[65];
55 char *lmp_reasons
[] = {
65 __u8
*irlmp_hint_to_service(__u8
*hint
);
67 int irlmp_proc_read(char *buf
, char **start
, off_t offst
, int len
);
71 * Function irlmp_init (void)
73 * Create (allocate) the main IrLMP structure
76 int __init
irlmp_init(void)
78 IRDA_DEBUG(1, "%s()\n", __FUNCTION__
);
79 /* Initialize the irlmp structure. */
80 irlmp
= kmalloc( sizeof(struct irlmp_cb
), GFP_KERNEL
);
83 memset(irlmp
, 0, sizeof(struct irlmp_cb
));
85 irlmp
->magic
= LMP_MAGIC
;
87 irlmp
->clients
= hashbin_new(HB_LOCK
);
88 irlmp
->services
= hashbin_new(HB_LOCK
);
89 irlmp
->links
= hashbin_new(HB_LOCK
);
90 irlmp
->unconnected_lsaps
= hashbin_new(HB_LOCK
);
91 irlmp
->cachelog
= hashbin_new(HB_NOLOCK
);
92 spin_lock_init(&irlmp
->cachelog
->hb_spinlock
);
94 irlmp
->free_lsap_sel
= 0x10; /* Reserved 0x00-0x0f */
95 strcpy(sysctl_devname
, "Linux");
97 /* Do discovery every 3 seconds */
98 init_timer(&irlmp
->discovery_timer
);
99 irlmp_start_discovery_timer(irlmp
, sysctl_discovery_timeout
*HZ
);
105 * Function irlmp_cleanup (void)
110 void __exit
irlmp_cleanup(void)
112 /* Check for main structure */
113 ASSERT(irlmp
!= NULL
, return;);
114 ASSERT(irlmp
->magic
== LMP_MAGIC
, return;);
116 del_timer(&irlmp
->discovery_timer
);
118 hashbin_delete(irlmp
->links
, (FREE_FUNC
) kfree
);
119 hashbin_delete(irlmp
->unconnected_lsaps
, (FREE_FUNC
) kfree
);
120 hashbin_delete(irlmp
->clients
, (FREE_FUNC
) kfree
);
121 hashbin_delete(irlmp
->services
, (FREE_FUNC
) kfree
);
122 hashbin_delete(irlmp
->cachelog
, (FREE_FUNC
) kfree
);
124 /* De-allocate main structure */
130 * Function irlmp_open_lsap (slsap, notify)
132 * Register with IrLMP and create a local LSAP,
133 * returns handle to LSAP.
135 struct lsap_cb
*irlmp_open_lsap(__u8 slsap_sel
, notify_t
*notify
, __u8 pid
)
137 struct lsap_cb
*self
;
139 ASSERT(notify
!= NULL
, return NULL
;);
140 ASSERT(irlmp
!= NULL
, return NULL
;);
141 ASSERT(irlmp
->magic
== LMP_MAGIC
, return NULL
;);
143 /* Does the client care which Source LSAP selector it gets? */
144 if (slsap_sel
== LSAP_ANY
) {
145 slsap_sel
= irlmp_find_free_slsap();
148 } else if (irlmp_slsap_inuse(slsap_sel
))
151 /* Allocate new instance of a LSAP connection */
152 self
= kmalloc(sizeof(struct lsap_cb
), GFP_ATOMIC
);
154 ERROR("%s: can't allocate memory", __FUNCTION__
);
157 memset(self
, 0, sizeof(struct lsap_cb
));
159 self
->magic
= LMP_LSAP_MAGIC
;
160 self
->slsap_sel
= slsap_sel
;
162 /* Fix connectionless LSAP's */
163 if (slsap_sel
== LSAP_CONNLESS
) {
164 #ifdef CONFIG_IRDA_ULTRA
165 self
->dlsap_sel
= LSAP_CONNLESS
;
167 #endif /* CONFIG_IRDA_ULTRA */
169 self
->dlsap_sel
= LSAP_ANY
;
170 /* self->connected = FALSE; -> already NULL via memset() */
172 init_timer(&self
->watchdog_timer
);
174 ASSERT(notify
->instance
!= NULL
, return NULL
;);
175 self
->notify
= *notify
;
177 self
->lsap_state
= LSAP_DISCONNECTED
;
179 /* Insert into queue of unconnected LSAPs */
180 hashbin_insert(irlmp
->unconnected_lsaps
, (irda_queue_t
*) self
,
187 * Function __irlmp_close_lsap (self)
189 * Remove an instance of LSAP
191 static void __irlmp_close_lsap(struct lsap_cb
*self
)
193 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
195 ASSERT(self
!= NULL
, return;);
196 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
199 * Set some of the variables to preset values
202 del_timer(&self
->watchdog_timer
); /* Important! */
205 dev_kfree_skb(self
->conn_skb
);
211 * Function irlmp_close_lsap (self)
213 * Close and remove LSAP
216 void irlmp_close_lsap(struct lsap_cb
*self
)
219 struct lsap_cb
*lsap
= NULL
;
221 ASSERT(self
!= NULL
, return;);
222 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
225 * Find out if we should remove this LSAP from a link or from the
226 * list of unconnected lsaps (not associated with a link)
230 ASSERT(lap
->magic
== LMP_LAP_MAGIC
, return;);
231 /* We might close a LSAP before it has completed the
232 * connection setup. In those case, higher layers won't
233 * send a proper disconnect request. Harmless, except
234 * that we will forget to close LAP... - Jean II */
235 if(self
->lsap_state
!= LSAP_DISCONNECTED
) {
236 self
->lsap_state
= LSAP_DISCONNECTED
;
237 irlmp_do_lap_event(self
->lap
,
238 LM_LAP_DISCONNECT_REQUEST
, NULL
);
240 /* Now, remove from the link */
241 lsap
= hashbin_remove(lap
->lsaps
, (long) self
, NULL
);
242 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
243 lap
->cache
.valid
= FALSE
;
247 /* Check if we found the LSAP! If not then try the unconnected lsaps */
249 lsap
= hashbin_remove(irlmp
->unconnected_lsaps
, (long) self
,
254 "%s(), Looks like somebody has removed me already!\n",
258 __irlmp_close_lsap(self
);
262 * Function irlmp_register_irlap (saddr, notify)
264 * Register IrLAP layer with IrLMP. There is possible to have multiple
265 * instances of the IrLAP layer, each connected to different IrDA ports
268 void irlmp_register_link(struct irlap_cb
*irlap
, __u32 saddr
, notify_t
*notify
)
272 ASSERT(irlmp
!= NULL
, return;);
273 ASSERT(irlmp
->magic
== LMP_MAGIC
, return;);
274 ASSERT(notify
!= NULL
, return;);
277 * Allocate new instance of a LSAP connection
279 lap
= kmalloc(sizeof(struct lap_cb
), GFP_KERNEL
);
281 ERROR("%s: unable to kmalloc\n", __FUNCTION__
);
284 memset(lap
, 0, sizeof(struct lap_cb
));
287 lap
->magic
= LMP_LAP_MAGIC
;
289 lap
->daddr
= DEV_ADDR_ANY
;
290 lap
->lsaps
= hashbin_new(HB_LOCK
);
291 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
292 lap
->cache
.valid
= FALSE
;
295 lap
->lap_state
= LAP_STANDBY
;
297 init_timer(&lap
->idle_timer
);
300 * Insert into queue of LMP links
302 hashbin_insert(irlmp
->links
, (irda_queue_t
*) lap
, lap
->saddr
, NULL
);
305 * We set only this variable so IrLAP can tell us on which link the
306 * different events happened on
308 irda_notify_init(notify
);
309 notify
->instance
= lap
;
313 * Function irlmp_unregister_irlap (saddr)
315 * IrLAP layer has been removed!
318 void irlmp_unregister_link(__u32 saddr
)
322 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
324 link
= hashbin_remove(irlmp
->links
, saddr
, NULL
);
326 ASSERT(link
->magic
== LMP_LAP_MAGIC
, return;);
328 /* Remove all discoveries discovered at this link */
329 irlmp_expire_discoveries(irlmp
->cachelog
, link
->saddr
, TRUE
);
331 del_timer(&link
->idle_timer
);
339 * Function irlmp_connect_request (handle, dlsap, userdata)
341 * Connect with a peer LSAP
344 int irlmp_connect_request(struct lsap_cb
*self
, __u8 dlsap_sel
,
345 __u32 saddr
, __u32 daddr
,
346 struct qos_info
*qos
, struct sk_buff
*userdata
)
348 struct sk_buff
*tx_skb
= userdata
;
350 struct lsap_cb
*lsap
;
353 ASSERT(self
!= NULL
, return -EBADR
;);
354 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return -EBADR
;);
357 "%s(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n",
358 __FUNCTION__
, self
->slsap_sel
, dlsap_sel
, saddr
, daddr
);
360 if (test_bit(0, &self
->connected
)) {
365 /* Client must supply destination device address */
372 if (tx_skb
== NULL
) {
373 tx_skb
= dev_alloc_skb(64);
377 skb_reserve(tx_skb
, LMP_MAX_HEADER
);
380 /* Make room for MUX control header (3 bytes) */
381 ASSERT(skb_headroom(tx_skb
) >= LMP_CONTROL_HEADER
, return -1;);
382 skb_push(tx_skb
, LMP_CONTROL_HEADER
);
384 self
->dlsap_sel
= dlsap_sel
;
387 * Find the link to where we should try to connect since there may
388 * be more than one IrDA port on this machine. If the client has
389 * passed us the saddr (and already knows which link to use), then
390 * we use that to find the link, if not then we have to look in the
391 * discovery log and check if any of the links has discovered a
392 * device with the given daddr
394 if ((!saddr
) || (saddr
== DEV_ADDR_ANY
)) {
395 discovery_t
*discovery
;
398 spin_lock_irqsave(&irlmp
->cachelog
->hb_spinlock
, flags
);
399 if (daddr
!= DEV_ADDR_ANY
)
400 discovery
= hashbin_find(irlmp
->cachelog
, daddr
, NULL
);
402 IRDA_DEBUG(2, "%s(), no daddr\n", __FUNCTION__
);
403 discovery
= (discovery_t
*)
404 hashbin_get_first(irlmp
->cachelog
);
408 saddr
= discovery
->data
.saddr
;
409 daddr
= discovery
->data
.daddr
;
411 spin_unlock_irqrestore(&irlmp
->cachelog
->hb_spinlock
, flags
);
413 lap
= hashbin_lock_find(irlmp
->links
, saddr
, NULL
);
415 IRDA_DEBUG(1, "%s(), Unable to find a usable link!\n", __FUNCTION__
);
420 /* Check if LAP is disconnected or already connected */
421 if (lap
->daddr
== DEV_ADDR_ANY
)
423 else if (lap
->daddr
!= daddr
) {
424 /* Check if some LSAPs are active on this LAP */
425 if (HASHBIN_GET_SIZE(lap
->lsaps
) == 0) {
426 /* No active connection, but LAP hasn't been
427 * disconnected yet (waiting for timeout in LAP).
428 * Maybe we could give LAP a bit of help in this case.
430 IRDA_DEBUG(0, "%s(), sorry, but I'm waiting for LAP to timeout!\n", __FUNCTION__
);
435 /* LAP is already connected to a different node, and LAP
436 * can only talk to one node at a time */
437 IRDA_DEBUG(0, "%s(), sorry, but link is busy!\n", __FUNCTION__
);
445 * Remove LSAP from list of unconnected LSAPs and insert it into the
446 * list of connected LSAPs for the particular link
448 lsap
= hashbin_remove(irlmp
->unconnected_lsaps
, (long) self
, NULL
);
450 ASSERT(lsap
!= NULL
, return -1;);
451 ASSERT(lsap
->magic
== LMP_LSAP_MAGIC
, return -1;);
452 ASSERT(lsap
->lap
!= NULL
, return -1;);
453 ASSERT(lsap
->lap
->magic
== LMP_LAP_MAGIC
, return -1;);
455 hashbin_insert(self
->lap
->lsaps
, (irda_queue_t
*) self
, (long) self
,
458 set_bit(0, &self
->connected
); /* TRUE */
461 * User supplied qos specifications?
466 irlmp_do_lsap_event(self
, LM_CONNECT_REQUEST
, tx_skb
);
468 /* Drop reference count - see irlap_data_request(). */
469 dev_kfree_skb(tx_skb
);
476 dev_kfree_skb(tx_skb
);
481 * Function irlmp_connect_indication (self)
483 * Incoming connection
486 void irlmp_connect_indication(struct lsap_cb
*self
, struct sk_buff
*skb
)
492 ASSERT(self
!= NULL
, return;);
493 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
494 ASSERT(skb
!= NULL
, return;);
495 ASSERT(self
->lap
!= NULL
, return;);
497 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
498 __FUNCTION__
, self
->slsap_sel
, self
->dlsap_sel
);
500 /* Note : self->lap is set in irlmp_link_data_indication(),
501 * (case CONNECT_CMD:) because we have no way to set it here.
502 * Similarly, self->dlsap_sel is usually set in irlmp_find_lsap().
505 self
->qos
= *self
->lap
->qos
;
507 max_seg_size
= self
->lap
->qos
->data_size
.value
-LMP_HEADER
;
508 lap_header_size
= IRLAP_GET_HEADER_SIZE(self
->lap
->irlap
);
509 max_header_size
= LMP_HEADER
+ lap_header_size
;
511 /* Hide LMP_CONTROL_HEADER header from layer above */
512 skb_pull(skb
, LMP_CONTROL_HEADER
);
514 if (self
->notify
.connect_indication
) {
515 /* Don't forget to refcount it - see irlap_driver_rcv(). */
517 self
->notify
.connect_indication(self
->notify
.instance
, self
,
518 &self
->qos
, max_seg_size
,
519 max_header_size
, skb
);
524 * Function irlmp_connect_response (handle, userdata)
526 * Service user is accepting connection
529 int irlmp_connect_response(struct lsap_cb
*self
, struct sk_buff
*userdata
)
531 ASSERT(self
!= NULL
, return -1;);
532 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return -1;);
533 ASSERT(userdata
!= NULL
, return -1;);
535 set_bit(0, &self
->connected
); /* TRUE */
537 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
538 __FUNCTION__
, self
->slsap_sel
, self
->dlsap_sel
);
540 /* Make room for MUX control header (3 bytes) */
541 ASSERT(skb_headroom(userdata
) >= LMP_CONTROL_HEADER
, return -1;);
542 skb_push(userdata
, LMP_CONTROL_HEADER
);
544 irlmp_do_lsap_event(self
, LM_CONNECT_RESPONSE
, userdata
);
546 /* Drop reference count - see irlap_data_request(). */
547 dev_kfree_skb(userdata
);
553 * Function irlmp_connect_confirm (handle, skb)
555 * LSAP connection confirmed peer device!
557 void irlmp_connect_confirm(struct lsap_cb
*self
, struct sk_buff
*skb
)
563 IRDA_DEBUG(3, "%s()\n", __FUNCTION__
);
565 ASSERT(skb
!= NULL
, return;);
566 ASSERT(self
!= NULL
, return;);
567 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
568 ASSERT(self
->lap
!= NULL
, return;);
570 self
->qos
= *self
->lap
->qos
;
572 max_seg_size
= self
->lap
->qos
->data_size
.value
-LMP_HEADER
;
573 lap_header_size
= IRLAP_GET_HEADER_SIZE(self
->lap
->irlap
);
574 max_header_size
= LMP_HEADER
+ lap_header_size
;
576 IRDA_DEBUG(2, "%s(), max_header_size=%d\n",
577 __FUNCTION__
, max_header_size
);
579 /* Hide LMP_CONTROL_HEADER header from layer above */
580 skb_pull(skb
, LMP_CONTROL_HEADER
);
582 if (self
->notify
.connect_confirm
) {
583 /* Don't forget to refcount it - see irlap_driver_rcv() */
585 self
->notify
.connect_confirm(self
->notify
.instance
, self
,
586 &self
->qos
, max_seg_size
,
587 max_header_size
, skb
);
592 * Function irlmp_dup (orig, instance)
594 * Duplicate LSAP, can be used by servers to confirm a connection on a
595 * new LSAP so it can keep listening on the old one.
598 struct lsap_cb
*irlmp_dup(struct lsap_cb
*orig
, void *instance
)
603 IRDA_DEBUG(1, "%s()\n", __FUNCTION__
);
605 spin_lock_irqsave(&irlmp
->unconnected_lsaps
->hb_spinlock
, flags
);
607 /* Only allowed to duplicate unconnected LSAP's */
608 if (!hashbin_find(irlmp
->unconnected_lsaps
, (long) orig
, NULL
)) {
609 IRDA_DEBUG(0, "%s(), unable to find LSAP\n", __FUNCTION__
);
610 spin_unlock_irqrestore(&irlmp
->unconnected_lsaps
->hb_spinlock
,
614 /* Allocate a new instance */
615 new = kmalloc(sizeof(struct lsap_cb
), GFP_ATOMIC
);
617 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__
);
618 spin_unlock_irqrestore(&irlmp
->unconnected_lsaps
->hb_spinlock
,
623 memcpy(new, orig
, sizeof(struct lsap_cb
));
624 /* new->lap = orig->lap; => done in the memcpy() */
625 /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
626 new->conn_skb
= NULL
;
628 spin_unlock_irqrestore(&irlmp
->unconnected_lsaps
->hb_spinlock
, flags
);
630 /* Not everything is the same */
631 new->notify
.instance
= instance
;
633 init_timer(&new->watchdog_timer
);
635 hashbin_insert(irlmp
->unconnected_lsaps
, (irda_queue_t
*) new,
638 /* Make sure that we invalidate the cache */
639 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
640 new->lap
->cache
.valid
= FALSE
;
641 #endif /* CONFIG_IRDA_CACHE_LAST_LSAP */
647 * Function irlmp_disconnect_request (handle, userdata)
649 * The service user is requesting disconnection, this will not remove the
650 * LSAP, but only mark it as disconnected
652 int irlmp_disconnect_request(struct lsap_cb
*self
, struct sk_buff
*userdata
)
654 struct lsap_cb
*lsap
;
656 ASSERT(self
!= NULL
, return -1;);
657 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return -1;);
658 ASSERT(userdata
!= NULL
, return -1;);
660 /* Already disconnected ?
661 * There is a race condition between irlmp_disconnect_indication()
662 * and us that might mess up the hashbins below. This fixes it.
664 if (! test_and_clear_bit(0, &self
->connected
)) {
665 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__
);
666 dev_kfree_skb(userdata
);
670 skb_push(userdata
, LMP_CONTROL_HEADER
);
673 * Do the event before the other stuff since we must know
674 * which lap layer that the frame should be transmitted on
676 irlmp_do_lsap_event(self
, LM_DISCONNECT_REQUEST
, userdata
);
678 /* Drop reference count - see irlap_data_request(). */
679 dev_kfree_skb(userdata
);
682 * Remove LSAP from list of connected LSAPs for the particular link
683 * and insert it into the list of unconnected LSAPs
685 ASSERT(self
->lap
!= NULL
, return -1;);
686 ASSERT(self
->lap
->magic
== LMP_LAP_MAGIC
, return -1;);
687 ASSERT(self
->lap
->lsaps
!= NULL
, return -1;);
689 lsap
= hashbin_remove(self
->lap
->lsaps
, (long) self
, NULL
);
690 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
691 self
->lap
->cache
.valid
= FALSE
;
694 ASSERT(lsap
!= NULL
, return -1;);
695 ASSERT(lsap
->magic
== LMP_LSAP_MAGIC
, return -1;);
696 ASSERT(lsap
== self
, return -1;);
698 hashbin_insert(irlmp
->unconnected_lsaps
, (irda_queue_t
*) self
,
701 /* Reset some values */
702 self
->dlsap_sel
= LSAP_ANY
;
709 * Function irlmp_disconnect_indication (reason, userdata)
711 * LSAP is being closed!
713 void irlmp_disconnect_indication(struct lsap_cb
*self
, LM_REASON reason
,
716 struct lsap_cb
*lsap
;
718 IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__
, lmp_reasons
[reason
]);
719 ASSERT(self
!= NULL
, return;);
720 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
722 IRDA_DEBUG(3, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
723 __FUNCTION__
, self
->slsap_sel
, self
->dlsap_sel
);
725 /* Already disconnected ?
726 * There is a race condition between irlmp_disconnect_request()
727 * and us that might mess up the hashbins below. This fixes it.
729 if (! test_and_clear_bit(0, &self
->connected
)) {
730 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__
);
735 * Remove association between this LSAP and the link it used
737 ASSERT(self
->lap
!= NULL
, return;);
738 ASSERT(self
->lap
->lsaps
!= NULL
, return;);
740 lsap
= hashbin_remove(self
->lap
->lsaps
, (long) self
, NULL
);
741 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
742 self
->lap
->cache
.valid
= FALSE
;
745 ASSERT(lsap
!= NULL
, return;);
746 ASSERT(lsap
== self
, return;);
747 hashbin_insert(irlmp
->unconnected_lsaps
, (irda_queue_t
*) lsap
,
750 self
->dlsap_sel
= LSAP_ANY
;
754 * Inform service user
756 if (self
->notify
.disconnect_indication
) {
757 /* Don't forget to refcount it - see irlap_driver_rcv(). */
760 self
->notify
.disconnect_indication(self
->notify
.instance
,
763 IRDA_DEBUG(0, "%s(), no handler\n", __FUNCTION__
);
768 * Function irlmp_do_expiry (void)
770 * Do a cleanup of the discovery log (remove old entries)
772 * Note : separate from irlmp_do_discovery() so that we can handle
773 * passive discovery properly.
775 void irlmp_do_expiry()
780 * Expire discovery on all links which are *not* connected.
781 * On links which are connected, we can't do discovery
782 * anymore and can't refresh the log, so we freeze the
783 * discovery log to keep info about the device we are
785 * This info is mandatory if we want irlmp_connect_request()
786 * to work properly. - Jean II
788 lap
= (struct lap_cb
*) hashbin_get_first(irlmp
->links
);
789 while (lap
!= NULL
) {
790 ASSERT(lap
->magic
== LMP_LAP_MAGIC
, return;);
792 if (lap
->lap_state
== LAP_STANDBY
) {
793 /* Expire discoveries discovered on this link */
794 irlmp_expire_discoveries(irlmp
->cachelog
, lap
->saddr
,
797 lap
= (struct lap_cb
*) hashbin_get_next(irlmp
->links
);
802 * Function irlmp_do_discovery (nslots)
804 * Do some discovery on all links
806 * Note : log expiry is done above.
808 void irlmp_do_discovery(int nslots
)
812 /* Make sure the value is sane */
813 if ((nslots
!= 1) && (nslots
!= 6) && (nslots
!= 8) && (nslots
!= 16)){
814 WARNING("%s: invalid value for number of slots!\n",
816 nslots
= sysctl_discovery_slots
= 8;
819 /* Construct new discovery info to be used by IrLAP, */
820 u16ho(irlmp
->discovery_cmd
.data
.hints
) = irlmp
->hints
.word
;
823 * Set character set for device name (we use ASCII), and
824 * copy device name. Remember to make room for a \0 at the
827 irlmp
->discovery_cmd
.data
.charset
= CS_ASCII
;
828 strncpy(irlmp
->discovery_cmd
.data
.info
, sysctl_devname
,
830 irlmp
->discovery_cmd
.name_len
= strlen(irlmp
->discovery_cmd
.data
.info
);
831 irlmp
->discovery_cmd
.nslots
= nslots
;
834 * Try to send discovery packets on all links
836 lap
= (struct lap_cb
*) hashbin_get_first(irlmp
->links
);
837 while (lap
!= NULL
) {
838 ASSERT(lap
->magic
== LMP_LAP_MAGIC
, return;);
840 if (lap
->lap_state
== LAP_STANDBY
) {
841 /* Try to discover */
842 irlmp_do_lap_event(lap
, LM_LAP_DISCOVERY_REQUEST
,
845 lap
= (struct lap_cb
*) hashbin_get_next(irlmp
->links
);
850 * Function irlmp_discovery_request (nslots)
852 * Do a discovery of devices in front of the computer
854 * If the caller has registered a client discovery callback, this
855 * allow him to receive the full content of the discovery log through
856 * this callback (as normally he will receive only new discoveries).
858 void irlmp_discovery_request(int nslots
)
860 /* Return current cached discovery log (in full) */
861 irlmp_discovery_confirm(irlmp
->cachelog
, DISCOVERY_LOG
);
864 * Start a single discovery operation if discovery is not already
867 if (!sysctl_discovery
) {
868 /* Check if user wants to override the default */
869 if (nslots
== DISCOVERY_DEFAULT_SLOTS
)
870 nslots
= sysctl_discovery_slots
;
872 irlmp_do_discovery(nslots
);
873 /* Note : we never do expiry here. Expiry will run on the
874 * discovery timer regardless of the state of sysctl_discovery
880 * Function irlmp_get_discoveries (pn, mask, slots)
882 * Return the current discovery log
884 * If discovery is not enabled, you should call this function again
885 * after 1 or 2 seconds (i.e. after discovery has been done).
887 struct irda_device_info
*irlmp_get_discoveries(int *pn
, __u16 mask
, int nslots
)
889 /* If discovery is not enabled, it's likely that the discovery log
890 * will be empty. So, we trigger a single discovery, so that next
891 * time the user call us there might be some results in the log.
894 if (!sysctl_discovery
) {
895 /* Check if user wants to override the default */
896 if (nslots
== DISCOVERY_DEFAULT_SLOTS
)
897 nslots
= sysctl_discovery_slots
;
899 /* Start discovery - will complete sometime later */
900 irlmp_do_discovery(nslots
);
901 /* Note : we never do expiry here. Expiry will run on the
902 * discovery timer regardless of the state of sysctl_discovery
906 /* Return current cached discovery log */
907 return(irlmp_copy_discoveries(irlmp
->cachelog
, pn
, mask
, TRUE
));
911 * Function irlmp_notify_client (log)
913 * Notify all about discovered devices
915 * Clients registered with IrLMP are :
918 * o Any socket (in any state - ouch, that may be a lot !)
919 * The client may have defined a callback to be notified in case of
920 * partial/selective discovery based on the hints that it passed to IrLMP.
923 irlmp_notify_client(irlmp_client_t
*client
,
924 hashbin_t
*log
, DISCOVERY_MODE mode
)
926 discinfo_t
*discoveries
; /* Copy of the discovery log */
927 int number
; /* Number of nodes in the log */
930 IRDA_DEBUG(3, "%s()\n", __FUNCTION__
);
932 /* Check if client wants or not partial/selective log (optimisation) */
933 if (!client
->disco_callback
)
938 * the old code was manipulating the log directly, which was
939 * very racy. Now, we use copy_discoveries, that protects
940 * itself while dumping the log for us.
941 * The overhead of the copy is compensated by the fact that
942 * we only pass new discoveries in normal mode and don't
943 * pass the same old entry every 3s to the caller as we used
944 * to do (virtual function calling is expensive).
949 * Now, check all discovered devices (if any), and notify client
950 * only about the services that the client is interested in
951 * We also notify only about the new devices unless the caller
952 * explicitly request a dump of the log. Jean II
954 discoveries
= irlmp_copy_discoveries(log
, &number
,
955 client
->hint_mask
.word
,
956 (mode
== DISCOVERY_LOG
));
957 /* Check if the we got some results */
958 if (discoveries
== NULL
)
959 return; /* No nodes discovered */
961 /* Pass all entries to the listener */
962 for(i
= 0; i
< number
; i
++)
963 client
->disco_callback(&(discoveries
[i
]), mode
, client
->priv
);
965 /* Free up our buffer */
970 * Function irlmp_discovery_confirm ( self, log)
972 * Some device(s) answered to our discovery request! Check to see which
973 * device it is, and give indication to the client(s)
976 void irlmp_discovery_confirm(hashbin_t
*log
, DISCOVERY_MODE mode
)
978 irlmp_client_t
*client
;
979 irlmp_client_t
*client_next
;
981 IRDA_DEBUG(3, "%s()\n", __FUNCTION__
);
983 ASSERT(log
!= NULL
, return;);
985 if (!(HASHBIN_GET_SIZE(log
)))
988 /* For each client - notify callback may touch client list */
989 client
= (irlmp_client_t
*) hashbin_get_first(irlmp
->clients
);
990 while (NULL
!= hashbin_find_next(irlmp
->clients
, (long) client
, NULL
,
991 (void *) &client_next
) ) {
992 /* Check if we should notify client */
993 irlmp_notify_client(client
, log
, mode
);
995 client
= client_next
;
1000 * Function irlmp_discovery_expiry (expiry)
1002 * This device is no longer been discovered, and therefore it is being
1003 * purged from the discovery log. Inform all clients who have
1004 * registered for this event...
1006 * Note : called exclusively from discovery.c
1007 * Note : this is no longer called under discovery spinlock, so the
1008 * client can do whatever he wants in the callback.
1010 void irlmp_discovery_expiry(discinfo_t
*expiries
, int number
)
1012 irlmp_client_t
*client
;
1013 irlmp_client_t
*client_next
;
1016 IRDA_DEBUG(3, "%s()\n", __FUNCTION__
);
1018 ASSERT(expiries
!= NULL
, return;);
1020 /* For each client - notify callback may touch client list */
1021 client
= (irlmp_client_t
*) hashbin_get_first(irlmp
->clients
);
1022 while (NULL
!= hashbin_find_next(irlmp
->clients
, (long) client
, NULL
,
1023 (void *) &client_next
) ) {
1025 /* Pass all entries to the listener */
1026 for(i
= 0; i
< number
; i
++) {
1027 /* Check if we should notify client */
1028 if ((client
->expir_callback
) &&
1029 (client
->hint_mask
.word
& u16ho(expiries
[i
].hints
)
1031 client
->expir_callback(&(expiries
[i
]),
1037 client
= client_next
;
1042 * Function irlmp_get_discovery_response ()
1044 * Used by IrLAP to get the discovery info it needs when answering
1045 * discovery requests by other devices.
1047 discovery_t
*irlmp_get_discovery_response()
1049 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1051 ASSERT(irlmp
!= NULL
, return NULL
;);
1053 u16ho(irlmp
->discovery_rsp
.data
.hints
) = irlmp
->hints
.word
;
1056 * Set character set for device name (we use ASCII), and
1057 * copy device name. Remember to make room for a \0 at the
1060 irlmp
->discovery_rsp
.data
.charset
= CS_ASCII
;
1062 strncpy(irlmp
->discovery_rsp
.data
.info
, sysctl_devname
,
1064 irlmp
->discovery_rsp
.name_len
= strlen(irlmp
->discovery_rsp
.data
.info
);
1066 return &irlmp
->discovery_rsp
;
1070 * Function irlmp_data_request (self, skb)
1072 * Send some data to peer device
1074 * Note on skb management :
1075 * After calling the lower layers of the IrDA stack, we always
1076 * kfree() the skb, which drop the reference count (and potentially
1078 * IrLMP and IrLAP may queue the packet, and in those cases will need
1079 * to use skb_get() to keep it around.
1082 int irlmp_data_request(struct lsap_cb
*self
, struct sk_buff
*userdata
)
1086 ASSERT(self
!= NULL
, return -1;);
1087 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return -1;);
1089 /* Make room for MUX header */
1090 ASSERT(skb_headroom(userdata
) >= LMP_HEADER
, return -1;);
1091 skb_push(userdata
, LMP_HEADER
);
1093 ret
= irlmp_do_lsap_event(self
, LM_DATA_REQUEST
, userdata
);
1095 /* Drop reference count - see irlap_data_request(). */
1096 dev_kfree_skb(userdata
);
1102 * Function irlmp_data_indication (handle, skb)
1104 * Got data from LAP layer so pass it up to upper layer
1107 void irlmp_data_indication(struct lsap_cb
*self
, struct sk_buff
*skb
)
1109 /* Hide LMP header from layer above */
1110 skb_pull(skb
, LMP_HEADER
);
1112 if (self
->notify
.data_indication
) {
1113 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1115 self
->notify
.data_indication(self
->notify
.instance
, self
, skb
);
1120 * Function irlmp_udata_request (self, skb)
1122 int irlmp_udata_request(struct lsap_cb
*self
, struct sk_buff
*userdata
)
1126 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1128 ASSERT(userdata
!= NULL
, return -1;);
1130 /* Make room for MUX header */
1131 ASSERT(skb_headroom(userdata
) >= LMP_HEADER
, return -1;);
1132 skb_push(userdata
, LMP_HEADER
);
1134 ret
= irlmp_do_lsap_event(self
, LM_UDATA_REQUEST
, userdata
);
1136 /* Drop reference count - see irlap_data_request(). */
1137 dev_kfree_skb(userdata
);
1143 * Function irlmp_udata_indication (self, skb)
1145 * Send unreliable data (but still within the connection)
1148 void irlmp_udata_indication(struct lsap_cb
*self
, struct sk_buff
*skb
)
1150 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1152 ASSERT(self
!= NULL
, return;);
1153 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
1154 ASSERT(skb
!= NULL
, return;);
1156 /* Hide LMP header from layer above */
1157 skb_pull(skb
, LMP_HEADER
);
1159 if (self
->notify
.udata_indication
) {
1160 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1162 self
->notify
.udata_indication(self
->notify
.instance
, self
,
1168 * Function irlmp_connless_data_request (self, skb)
1170 #ifdef CONFIG_IRDA_ULTRA
1171 int irlmp_connless_data_request(struct lsap_cb
*self
, struct sk_buff
*userdata
)
1173 struct sk_buff
*clone_skb
;
1176 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1178 ASSERT(userdata
!= NULL
, return -1;);
1180 /* Make room for MUX and PID header */
1181 ASSERT(skb_headroom(userdata
) >= LMP_HEADER
+LMP_PID_HEADER
,
1184 /* Insert protocol identifier */
1185 skb_push(userdata
, LMP_PID_HEADER
);
1186 userdata
->data
[0] = self
->pid
;
1188 /* Connectionless sockets must use 0x70 */
1189 skb_push(userdata
, LMP_HEADER
);
1190 userdata
->data
[0] = userdata
->data
[1] = LSAP_CONNLESS
;
1192 /* Try to send Connectionless packets out on all links */
1193 lap
= (struct lap_cb
*) hashbin_get_first(irlmp
->links
);
1194 while (lap
!= NULL
) {
1195 ASSERT(lap
->magic
== LMP_LAP_MAGIC
, return -1;);
1197 clone_skb
= skb_clone(userdata
, GFP_ATOMIC
);
1199 dev_kfree_skb(userdata
);
1203 irlap_unitdata_request(lap
->irlap
, clone_skb
);
1204 /* irlap_unitdata_request() don't increase refcount,
1205 * so no dev_kfree_skb() - Jean II */
1207 lap
= (struct lap_cb
*) hashbin_get_next(irlmp
->links
);
1209 dev_kfree_skb(userdata
);
1213 #endif /* CONFIG_IRDA_ULTRA */
1216 * Function irlmp_connless_data_indication (self, skb)
1218 * Receive unreliable data outside any connection. Mostly used by Ultra
1221 #ifdef CONFIG_IRDA_ULTRA
1222 void irlmp_connless_data_indication(struct lsap_cb
*self
, struct sk_buff
*skb
)
1224 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1226 ASSERT(self
!= NULL
, return;);
1227 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return;);
1228 ASSERT(skb
!= NULL
, return;);
1230 /* Hide LMP and PID header from layer above */
1231 skb_pull(skb
, LMP_HEADER
+LMP_PID_HEADER
);
1233 if (self
->notify
.udata_indication
) {
1234 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1236 self
->notify
.udata_indication(self
->notify
.instance
, self
,
1240 #endif /* CONFIG_IRDA_ULTRA */
1242 void irlmp_status_request(void)
1244 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__
);
1248 * Propagate status indication from LAP to LSAPs (via LMP)
1249 * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb,
1250 * and the event is stateless, therefore we can bypass both state machines
1251 * and send the event direct to the LSAP user.
1254 void irlmp_status_indication(struct lap_cb
*self
,
1255 LINK_STATUS link
, LOCK_STATUS lock
)
1257 struct lsap_cb
*next
;
1258 struct lsap_cb
*curr
;
1260 /* Send status_indication to all LSAPs using this link */
1261 curr
= (struct lsap_cb
*) hashbin_get_first( self
->lsaps
);
1262 while (NULL
!= hashbin_find_next(self
->lsaps
, (long) curr
, NULL
,
1264 ASSERT(curr
->magic
== LMP_LSAP_MAGIC
, return;);
1266 * Inform service user if he has requested it
1268 if (curr
->notify
.status_indication
!= NULL
)
1269 curr
->notify
.status_indication(curr
->notify
.instance
,
1272 IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__
);
1279 * Receive flow control indication from LAP.
1280 * LAP want us to send it one more frame. We implement a simple round
1281 * robin scheduler between the active sockets so that we get a bit of
1282 * fairness. Note that the round robin is far from perfect, but it's
1283 * better than nothing.
1284 * We then poll the selected socket so that we can do synchronous
1285 * refilling of IrLAP (which allow to minimise the number of buffers).
1288 void irlmp_flow_indication(struct lap_cb
*self
, LOCAL_FLOW flow
)
1290 struct lsap_cb
*next
;
1291 struct lsap_cb
*curr
;
1294 ASSERT(self
->magic
== LMP_LAP_MAGIC
, return;);
1295 ASSERT(flow
== FLOW_START
, return;);
1297 /* Get the number of lsap. That's the only safe way to know
1298 * that we have looped around... - Jean II */
1299 lsap_todo
= HASHBIN_GET_SIZE(self
->lsaps
);
1300 IRDA_DEBUG(4, "%s() : %d lsaps to scan\n", __FUNCTION__
, lsap_todo
);
1302 /* Poll lsap in order until the queue is full or until we
1304 * Most often, the current LSAP will have something to send,
1305 * so we will go through this loop only once. - Jean II */
1306 while((lsap_todo
--) &&
1307 (IRLAP_GET_TX_QUEUE_LEN(self
->irlap
) < LAP_HIGH_THRESHOLD
)) {
1308 /* Try to find the next lsap we should poll. */
1309 next
= self
->flow_next
;
1310 /* If we have no lsap, restart from first one */
1312 next
= (struct lsap_cb
*) hashbin_get_first(self
->lsaps
);
1313 /* Verify current one and find the next one */
1314 curr
= hashbin_find_next(self
->lsaps
, (long) next
, NULL
,
1315 (void *) &self
->flow_next
);
1316 /* Uh-oh... Paranoia */
1319 IRDA_DEBUG(4, "%s() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d\n", __FUNCTION__
, curr
, next
, self
->flow_next
, lsap_todo
, IRLAP_GET_TX_QUEUE_LEN(self
->irlap
));
1321 /* Inform lsap user that it can send one more packet. */
1322 if (curr
->notify
.flow_indication
!= NULL
)
1323 curr
->notify
.flow_indication(curr
->notify
.instance
,
1326 IRDA_DEBUG(1, "%s(), no handler\n", __FUNCTION__
);
1332 * Function irlmp_hint_to_service (hint)
1334 * Returns a list of all servics contained in the given hint bits. This
1335 * function assumes that the hint bits have the size of two bytes only
1337 __u8
*irlmp_hint_to_service(__u8
*hint
)
1343 * Allocate array to store services in. 16 entries should be safe
1344 * since we currently only support 2 hint bytes
1346 service
= kmalloc(16, GFP_ATOMIC
);
1348 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__
);
1353 IRDA_DEBUG(1, "<None>\n");
1357 if (hint
[0] & HINT_PNP
)
1358 IRDA_DEBUG(1, "PnP Compatible ");
1359 if (hint
[0] & HINT_PDA
)
1360 IRDA_DEBUG(1, "PDA/Palmtop ");
1361 if (hint
[0] & HINT_COMPUTER
)
1362 IRDA_DEBUG(1, "Computer ");
1363 if (hint
[0] & HINT_PRINTER
) {
1364 IRDA_DEBUG(1, "Printer ");
1365 service
[i
++] = S_PRINTER
;
1367 if (hint
[0] & HINT_MODEM
)
1368 IRDA_DEBUG(1, "Modem ");
1369 if (hint
[0] & HINT_FAX
)
1370 IRDA_DEBUG(1, "Fax ");
1371 if (hint
[0] & HINT_LAN
) {
1372 IRDA_DEBUG(1, "LAN Access ");
1373 service
[i
++] = S_LAN
;
1376 * Test if extension byte exists. This byte will usually be
1377 * there, but this is not really required by the standard.
1380 if (hint
[0] & HINT_EXTENSION
) {
1381 if (hint
[1] & HINT_TELEPHONY
) {
1382 IRDA_DEBUG(1, "Telephony ");
1383 service
[i
++] = S_TELEPHONY
;
1384 } if (hint
[1] & HINT_FILE_SERVER
)
1385 IRDA_DEBUG(1, "File Server ");
1387 if (hint
[1] & HINT_COMM
) {
1388 IRDA_DEBUG(1, "IrCOMM ");
1389 service
[i
++] = S_COMM
;
1391 if (hint
[1] & HINT_OBEX
) {
1392 IRDA_DEBUG(1, "IrOBEX ");
1393 service
[i
++] = S_OBEX
;
1396 IRDA_DEBUG(1, "\n");
1398 /* So that client can be notified about any discovery */
1399 service
[i
++] = S_ANY
;
1407 const __u16 service_hint_mapping
[S_END
][2] = {
1408 { HINT_PNP
, 0 }, /* S_PNP */
1409 { HINT_PDA
, 0 }, /* S_PDA */
1410 { HINT_COMPUTER
, 0 }, /* S_COMPUTER */
1411 { HINT_PRINTER
, 0 }, /* S_PRINTER */
1412 { HINT_MODEM
, 0 }, /* S_MODEM */
1413 { HINT_FAX
, 0 }, /* S_FAX */
1414 { HINT_LAN
, 0 }, /* S_LAN */
1415 { HINT_EXTENSION
, HINT_TELEPHONY
}, /* S_TELEPHONY */
1416 { HINT_EXTENSION
, HINT_COMM
}, /* S_COMM */
1417 { HINT_EXTENSION
, HINT_OBEX
}, /* S_OBEX */
1418 { 0xFF, 0xFF }, /* S_ANY */
1422 * Function irlmp_service_to_hint (service)
1424 * Converts a service type, to a hint bit
1426 * Returns: a 16 bit hint value, with the service bit set
1428 __u16
irlmp_service_to_hint(int service
)
1430 __u16_host_order hint
;
1432 hint
.byte
[0] = service_hint_mapping
[service
][0];
1433 hint
.byte
[1] = service_hint_mapping
[service
][1];
1439 * Function irlmp_register_service (service)
1441 * Register local service with IrLMP
1444 void *irlmp_register_service(__u16 hints
)
1446 irlmp_service_t
*service
;
1448 IRDA_DEBUG(4, "%s(), hints = %04x\n", __FUNCTION__
, hints
);
1450 /* Make a new registration */
1451 service
= kmalloc(sizeof(irlmp_service_t
), GFP_ATOMIC
);
1453 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__
);
1456 service
->hints
.word
= hints
;
1457 hashbin_insert(irlmp
->services
, (irda_queue_t
*) service
,
1458 (long) service
, NULL
);
1460 irlmp
->hints
.word
|= hints
;
1462 return (void *)service
;
1466 * Function irlmp_unregister_service (handle)
1468 * Unregister service with IrLMP.
1470 * Returns: 0 on success, -1 on error
1472 int irlmp_unregister_service(void *handle
)
1474 irlmp_service_t
*service
;
1475 unsigned long flags
;
1477 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1482 /* Caller may call with invalid handle (it's legal) - Jean II */
1483 service
= hashbin_lock_find(irlmp
->services
, (long) handle
, NULL
);
1485 IRDA_DEBUG(1, "%s(), Unknown service!\n", __FUNCTION__
);
1489 hashbin_remove_this(irlmp
->services
, (irda_queue_t
*) service
);
1492 /* Remove old hint bits */
1493 irlmp
->hints
.word
= 0;
1495 /* Refresh current hint bits */
1496 spin_lock_irqsave(&irlmp
->services
->hb_spinlock
, flags
);
1497 service
= (irlmp_service_t
*) hashbin_get_first(irlmp
->services
);
1499 irlmp
->hints
.word
|= service
->hints
.word
;
1501 service
= (irlmp_service_t
*)hashbin_get_next(irlmp
->services
);
1503 spin_unlock_irqrestore(&irlmp
->services
->hb_spinlock
, flags
);
1508 * Function irlmp_register_client (hint_mask, callback1, callback2)
1510 * Register a local client with IrLMP
1511 * First callback is selective discovery (based on hints)
1512 * Second callback is for selective discovery expiries
1514 * Returns: handle > 0 on success, 0 on error
1516 void *irlmp_register_client(__u16 hint_mask
, DISCOVERY_CALLBACK1 disco_clb
,
1517 DISCOVERY_CALLBACK2 expir_clb
, void *priv
)
1519 irlmp_client_t
*client
;
1521 IRDA_DEBUG(1, "%s()\n", __FUNCTION__
);
1522 ASSERT(irlmp
!= NULL
, return 0;);
1524 /* Make a new registration */
1525 client
= kmalloc(sizeof(irlmp_client_t
), GFP_ATOMIC
);
1527 IRDA_DEBUG( 1, "%s(), Unable to kmalloc!\n", __FUNCTION__
);
1531 /* Register the details */
1532 client
->hint_mask
.word
= hint_mask
;
1533 client
->disco_callback
= disco_clb
;
1534 client
->expir_callback
= expir_clb
;
1535 client
->priv
= priv
;
1537 hashbin_insert(irlmp
->clients
, (irda_queue_t
*) client
,
1538 (long) client
, NULL
);
1540 return (void *) client
;
1544 * Function irlmp_update_client (handle, hint_mask, callback1, callback2)
1546 * Updates specified client (handle) with possibly new hint_mask and
1549 * Returns: 0 on success, -1 on error
1551 int irlmp_update_client(void *handle
, __u16 hint_mask
,
1552 DISCOVERY_CALLBACK1 disco_clb
,
1553 DISCOVERY_CALLBACK2 expir_clb
, void *priv
)
1555 irlmp_client_t
*client
;
1560 client
= hashbin_lock_find(irlmp
->clients
, (long) handle
, NULL
);
1562 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__
);
1566 client
->hint_mask
.word
= hint_mask
;
1567 client
->disco_callback
= disco_clb
;
1568 client
->expir_callback
= expir_clb
;
1569 client
->priv
= priv
;
1575 * Function irlmp_unregister_client (handle)
1577 * Returns: 0 on success, -1 on error
1580 int irlmp_unregister_client(void *handle
)
1582 struct irlmp_client
*client
;
1584 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1589 /* Caller may call with invalid handle (it's legal) - Jean II */
1590 client
= hashbin_lock_find(irlmp
->clients
, (long) handle
, NULL
);
1592 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__
);
1596 IRDA_DEBUG(4, "%s(), removing client!\n", __FUNCTION__
);
1597 hashbin_remove_this(irlmp
->clients
, (irda_queue_t
*) client
);
1604 * Function irlmp_slsap_inuse (slsap)
1606 * Check if the given source LSAP selector is in use
1608 int irlmp_slsap_inuse(__u8 slsap_sel
)
1610 struct lsap_cb
*self
;
1612 unsigned long flags
;
1614 ASSERT(irlmp
!= NULL
, return TRUE
;);
1615 ASSERT(irlmp
->magic
== LMP_MAGIC
, return TRUE
;);
1616 ASSERT(slsap_sel
!= LSAP_ANY
, return TRUE
;);
1618 IRDA_DEBUG(4, "%s()\n", __FUNCTION__
);
1620 #ifdef CONFIG_IRDA_ULTRA
1621 /* Accept all bindings to the connectionless LSAP */
1622 if (slsap_sel
== LSAP_CONNLESS
)
1624 #endif /* CONFIG_IRDA_ULTRA */
1626 /* Valid values are between 0 and 127 */
1627 if (slsap_sel
> LSAP_MAX
)
1631 * Check if slsap is already in use. To do this we have to loop over
1632 * every IrLAP connection and check every LSAP associated with each
1635 spin_lock_irqsave(&irlmp
->links
->hb_spinlock
, flags
);
1636 lap
= (struct lap_cb
*) hashbin_get_first(irlmp
->links
);
1637 while (lap
!= NULL
) {
1638 ASSERT(lap
->magic
== LMP_LAP_MAGIC
, return TRUE
;);
1640 /* Careful for priority inversions here !
1641 * All other uses of attrib spinlock are independent of
1642 * the object spinlock, so we are safe. Jean II */
1643 spin_lock(&lap
->lsaps
->hb_spinlock
);
1645 self
= (struct lsap_cb
*) hashbin_get_first(lap
->lsaps
);
1646 while (self
!= NULL
) {
1647 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, return TRUE
;);
1649 if ((self
->slsap_sel
== slsap_sel
)) {
1650 IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n",
1654 self
= (struct lsap_cb
*) hashbin_get_next(lap
->lsaps
);
1656 spin_unlock(&lap
->lsaps
->hb_spinlock
);
1658 lap
= (struct lap_cb
*) hashbin_get_next(irlmp
->links
);
1660 spin_unlock_irqrestore(&irlmp
->links
->hb_spinlock
, flags
);
1665 * Function irlmp_find_free_slsap ()
1667 * Find a free source LSAP to use. This function is called if the service
1668 * user has requested a source LSAP equal to LM_ANY
1670 __u8
irlmp_find_free_slsap(void)
1675 ASSERT(irlmp
!= NULL
, return -1;);
1676 ASSERT(irlmp
->magic
== LMP_MAGIC
, return -1;);
1678 lsap_sel
= irlmp
->free_lsap_sel
++;
1680 /* Check if the new free lsap is really free */
1681 while (irlmp_slsap_inuse(irlmp
->free_lsap_sel
)) {
1682 irlmp
->free_lsap_sel
++;
1684 /* Check if we need to wraparound (0x70-0x7f are reserved) */
1685 if (irlmp
->free_lsap_sel
> LSAP_MAX
) {
1686 irlmp
->free_lsap_sel
= 10;
1688 /* Make sure we terminate the loop */
1693 IRDA_DEBUG(4, "%s(), next free lsap_sel=%02x\n",
1694 __FUNCTION__
, lsap_sel
);
1700 * Function irlmp_convert_lap_reason (lap_reason)
1702 * Converts IrLAP disconnect reason codes to IrLMP disconnect reason
1706 LM_REASON
irlmp_convert_lap_reason( LAP_REASON lap_reason
)
1708 int reason
= LM_LAP_DISCONNECT
;
1710 switch (lap_reason
) {
1711 case LAP_DISC_INDICATION
: /* Received a disconnect request from peer */
1712 IRDA_DEBUG( 1, "%s(), LAP_DISC_INDICATION\n", __FUNCTION__
);
1713 reason
= LM_USER_REQUEST
;
1715 case LAP_NO_RESPONSE
: /* To many retransmits without response */
1716 IRDA_DEBUG( 1, "%s(), LAP_NO_RESPONSE\n", __FUNCTION__
);
1717 reason
= LM_LAP_DISCONNECT
;
1719 case LAP_RESET_INDICATION
:
1720 IRDA_DEBUG( 1, "%s(), LAP_RESET_INDICATION\n", __FUNCTION__
);
1721 reason
= LM_LAP_RESET
;
1723 case LAP_FOUND_NONE
:
1724 case LAP_MEDIA_BUSY
:
1725 case LAP_PRIMARY_CONFLICT
:
1726 IRDA_DEBUG(1, "%s(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n", __FUNCTION__
);
1727 reason
= LM_CONNECT_FAILURE
;
1730 IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n",
1731 __FUNCTION__
, lap_reason
);
1732 reason
= LM_LAP_DISCONNECT
;
1739 __u32
irlmp_get_saddr(struct lsap_cb
*self
)
1741 ASSERT(self
!= NULL
, return 0;);
1742 ASSERT(self
->lap
!= NULL
, return 0;);
1744 return self
->lap
->saddr
;
1747 __u32
irlmp_get_daddr(struct lsap_cb
*self
)
1749 ASSERT(self
!= NULL
, return 0;);
1750 ASSERT(self
->lap
!= NULL
, return 0;);
1752 return self
->lap
->daddr
;
1755 #ifdef CONFIG_PROC_FS
1757 * Function irlmp_proc_read (buf, start, offset, len, unused)
1759 * Give some info to the /proc file system
1762 int irlmp_proc_read(char *buf
, char **start
, off_t offset
, int len
)
1764 struct lsap_cb
*self
;
1766 unsigned long flags
;
1768 ASSERT(irlmp
!= NULL
, return 0;);
1772 len
+= sprintf( buf
+len
, "Unconnected LSAPs:\n");
1773 spin_lock_irqsave(&irlmp
->unconnected_lsaps
->hb_spinlock
, flags
);
1774 self
= (struct lsap_cb
*) hashbin_get_first( irlmp
->unconnected_lsaps
);
1775 while (self
!= NULL
) {
1776 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, break;);
1777 len
+= sprintf(buf
+len
, "lsap state: %s, ",
1778 irlsap_state
[ self
->lsap_state
]);
1779 len
+= sprintf(buf
+len
,
1780 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1781 self
->slsap_sel
, self
->dlsap_sel
);
1782 len
+= sprintf(buf
+len
, "(%s)", self
->notify
.name
);
1783 len
+= sprintf(buf
+len
, "\n");
1785 self
= (struct lsap_cb
*) hashbin_get_next(
1786 irlmp
->unconnected_lsaps
);
1788 spin_unlock_irqrestore(&irlmp
->unconnected_lsaps
->hb_spinlock
, flags
);
1790 len
+= sprintf(buf
+len
, "\nRegistred Link Layers:\n");
1791 spin_lock_irqsave(&irlmp
->links
->hb_spinlock
, flags
);
1792 lap
= (struct lap_cb
*) hashbin_get_first(irlmp
->links
);
1793 while (lap
!= NULL
) {
1794 len
+= sprintf(buf
+len
, "lap state: %s, ",
1795 irlmp_state
[lap
->lap_state
]);
1797 len
+= sprintf(buf
+len
, "saddr: %#08x, daddr: %#08x, ",
1798 lap
->saddr
, lap
->daddr
);
1799 len
+= sprintf(buf
+len
, "num lsaps: %d",
1800 HASHBIN_GET_SIZE(lap
->lsaps
));
1801 len
+= sprintf(buf
+len
, "\n");
1803 /* Careful for priority inversions here !
1804 * All other uses of attrib spinlock are independent of
1805 * the object spinlock, so we are safe. Jean II */
1806 spin_lock(&lap
->lsaps
->hb_spinlock
);
1808 len
+= sprintf(buf
+len
, "\n Connected LSAPs:\n");
1809 self
= (struct lsap_cb
*) hashbin_get_first(lap
->lsaps
);
1810 while (self
!= NULL
) {
1811 ASSERT(self
->magic
== LMP_LSAP_MAGIC
, break;);
1812 len
+= sprintf(buf
+len
, " lsap state: %s, ",
1813 irlsap_state
[ self
->lsap_state
]);
1814 len
+= sprintf(buf
+len
,
1815 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1816 self
->slsap_sel
, self
->dlsap_sel
);
1817 len
+= sprintf(buf
+len
, "(%s)", self
->notify
.name
);
1818 len
+= sprintf(buf
+len
, "\n");
1820 self
= (struct lsap_cb
*) hashbin_get_next(
1823 spin_unlock(&lap
->lsaps
->hb_spinlock
);
1824 len
+= sprintf(buf
+len
, "\n");
1826 lap
= (struct lap_cb
*) hashbin_get_next(irlmp
->links
);
1828 spin_unlock_irqrestore(&irlmp
->links
->hb_spinlock
, flags
);
1833 #endif /* PROC_FS */