1 /*********************************************************************
3 * Filename: discovery.c
5 * Description: Routines for handling discoveries at the IrLMP layer
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Apr 6 15:33:50 1999
9 * Modified at: Sun May 9 22:40:43 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 ********************************************************************/
31 #include <linux/socket.h>
32 #include <linux/irda.h>
34 #include <net/irda/irda.h>
35 #include <net/irda/irlmp.h>
37 #include <net/irda/discovery.h>
40 * Function irlmp_add_discovery (cachelog, discovery)
42 * Add a new discovery to the cachelog, and remove any old discoveries
43 * from the same device
45 void irlmp_add_discovery(hashbin_t
*cachelog
, discovery_t
*new)
47 discovery_t
*discovery
, *node
;
50 spin_lock_irqsave(&irlmp
->lock
, flags
);
53 * Remove all discoveries of devices that has previously been
54 * discovered on the same link with the same name (info), or the
55 * same daddr. We do this since some devices (mostly PDAs) change
56 * their device address between every discovery.
58 discovery
= (discovery_t
*) hashbin_get_first(cachelog
);
59 while (discovery
!= NULL
) {
62 /* Be sure to stay one item ahead */
63 discovery
= (discovery_t
*) hashbin_get_next(cachelog
);
65 if ((node
->daddr
== new->daddr
) ||
66 (strcmp(node
->info
, new->info
) == 0))
68 /* This discovery is a previous discovery
69 * from the same device, so just remove it
71 hashbin_remove(cachelog
, node
->daddr
, NULL
);
77 /* Insert the new and updated version */
78 hashbin_insert(cachelog
, (QUEUE
*) new, new->daddr
, NULL
);
80 spin_unlock_irqrestore(&irlmp
->lock
, flags
);
84 * Function irlmp_add_discovery_log (cachelog, log)
86 * Merge a disovery log into the cachlog.
89 void irlmp_add_discovery_log(hashbin_t
*cachelog
, hashbin_t
*log
)
91 discovery_t
*discovery
;
93 DEBUG(4, __FUNCTION__
"()\n");
96 * If log is missing this means that IrLAP was unable to perform the
97 * discovery, so restart discovery again with just the half timeout
101 /* irlmp_start_discovery_timer(irlmp, 150); */
105 discovery
= (discovery_t
*) hashbin_remove_first(log
);
106 while (discovery
!= NULL
) {
107 irlmp_add_discovery(cachelog
, discovery
);
109 discovery
= (discovery_t
*) hashbin_remove_first(log
);
112 /* Delete the now empty log */
113 hashbin_delete(log
, (FREE_FUNC
) kfree
);
117 * Function irlmp_expire_discoveries (log, saddr, force)
119 * Go through all discoveries and expire all that has stayed to long
122 void irlmp_expire_discoveries(hashbin_t
*log
, int saddr
, int force
)
124 discovery_t
*discovery
, *curr
;
126 DEBUG(4, __FUNCTION__
"()\n");
128 discovery
= (discovery_t
*) hashbin_get_first(log
);
129 while (discovery
!= NULL
) {
132 /* Be sure to be one item ahead */
133 discovery
= (discovery_t
*) hashbin_get_next(log
);
135 /* Test if it's time to expire this discovery */
136 if ((curr
->saddr
== saddr
) && (force
||
137 ((jiffies
- curr
->timestamp
) > DISCOVERY_EXPIRE_TIMEOUT
)))
139 curr
= hashbin_remove(log
, curr
->daddr
, NULL
);
147 * Function irlmp_dump_discoveries (log)
149 * Print out all discoveries in log
152 void irlmp_dump_discoveries(hashbin_t
*log
)
154 discovery_t
*discovery
;
156 ASSERT(log
!= NULL
, return;);
158 discovery
= (discovery_t
*) hashbin_get_first(log
);
159 while (discovery
!= NULL
) {
160 DEBUG(0, "Discovery:\n");
161 DEBUG(0, " daddr=%08x\n", discovery
->daddr
);
162 DEBUG(0, " saddr=%08x\n", discovery
->saddr
);
163 DEBUG(0, " name=%s\n", discovery
->info
);
165 discovery
= (discovery_t
*) hashbin_get_next(log
);
170 * Function irlmp_find_device (name, saddr)
172 * Look through the discovery log at each of the links and try to find
173 * the device with the given name. Return daddr and saddr. If saddr is
174 * specified, that look at that particular link only (not impl).
176 __u32
irlmp_find_device(hashbin_t
*cachelog
, char *name
, __u32
*saddr
)
181 spin_lock_irqsave(&irlmp
->lock
, flags
);
183 /* Look at all discoveries for that link */
184 d
= (discovery_t
*) hashbin_get_first(cachelog
);
186 DEBUG(1, "Discovery:\n");
187 DEBUG(1, " daddr=%08x\n", d
->daddr
);
188 DEBUG(1, " name=%s\n", d
->info
);
190 if (strcmp(name
, d
->info
) == 0) {
193 spin_unlock_irqrestore(&irlmp
->lock
, flags
);
196 d
= (discovery_t
*) hashbin_get_next(cachelog
);
199 spin_unlock_irqrestore(&irlmp
->lock
, flags
);
205 * Function proc_discovery_read (buf, start, offset, len, unused)
207 * Print discovery information in /proc file system
210 int discovery_proc_read(char *buf
, char **start
, off_t offset
, int len
,
213 discovery_t
*discovery
;
215 hashbin_t
*cachelog
= irlmp_get_cachelog();
220 len
= sprintf(buf
, "IrLMP: Discovery log:\n\n");
225 discovery
= (discovery_t
*) hashbin_get_first(cachelog
);
226 while ( discovery
!= NULL
) {
227 len
+= sprintf( buf
+len
, " name: %s,",
230 len
+= sprintf( buf
+len
, " hint: ");
231 if ( discovery
->hints
.byte
[0] & HINT_PNP
)
232 len
+= sprintf( buf
+len
, "PnP Compatible ");
233 if ( discovery
->hints
.byte
[0] & HINT_PDA
)
234 len
+= sprintf( buf
+len
, "PDA/Palmtop ");
235 if ( discovery
->hints
.byte
[0] & HINT_COMPUTER
)
236 len
+= sprintf( buf
+len
, "Computer ");
237 if ( discovery
->hints
.byte
[0] & HINT_PRINTER
)
238 len
+= sprintf( buf
+len
, "Printer ");
239 if ( discovery
->hints
.byte
[0] & HINT_MODEM
)
240 len
+= sprintf( buf
+len
, "Modem ");
241 if ( discovery
->hints
.byte
[0] & HINT_FAX
)
242 len
+= sprintf( buf
+len
, "Fax ");
243 if ( discovery
->hints
.byte
[0] & HINT_LAN
)
244 len
+= sprintf( buf
+len
, "LAN Access ");
246 if ( discovery
->hints
.byte
[1] & HINT_TELEPHONY
)
247 len
+= sprintf( buf
+len
, "Telephony ");
248 if ( discovery
->hints
.byte
[1] & HINT_FILE_SERVER
)
249 len
+= sprintf( buf
+len
, "File Server ");
250 if ( discovery
->hints
.byte
[1] & HINT_COMM
)
251 len
+= sprintf( buf
+len
, "IrCOMM ");
252 if ( discovery
->hints
.byte
[1] & HINT_OBEX
)
253 len
+= sprintf( buf
+len
, "IrOBEX ");
255 len
+= sprintf(buf
+len
, ", saddr: 0x%08x",
258 len
+= sprintf(buf
+len
, ", daddr: 0x%08x\n",
261 len
+= sprintf( buf
+len
, "\n");
263 discovery
= (discovery_t
*) hashbin_get_next(cachelog
);
265 restore_flags(flags
);