Import 2.3.4pre3
[davej-history.git] / net / irda / discovery.c
blob41fc4d20a5e80ef3b674c96de4a5fd41e38f1a97
1 /*********************************************************************
2 *
3 * Filename: discovery.c
4 * Version: 0.1
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,
27 * MA 02111-1307 USA
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;
48 unsigned long flags;
50 spin_lock_irqsave(&irlmp->lock, flags);
52 /*
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 ) {
60 node = discovery;
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);
72 kfree(node);
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
98 * of the normal one.
100 if (log == NULL) {
101 /* irlmp_start_discovery_timer(irlmp, 150); */
102 return;
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) {
130 curr = discovery;
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);
140 if (curr)
141 kfree(curr);
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)
178 discovery_t *d;
179 unsigned long flags;
181 spin_lock_irqsave(&irlmp->lock, flags);
183 /* Look at all discoveries for that link */
184 d = (discovery_t *) hashbin_get_first(cachelog);
185 while (d != NULL) {
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) {
191 *saddr = d->saddr;
193 spin_unlock_irqrestore(&irlmp->lock, flags);
194 return d->daddr;
196 d = (discovery_t *) hashbin_get_next(cachelog);
199 spin_unlock_irqrestore(&irlmp->lock, flags);
201 return 0;
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,
211 int unused)
213 discovery_t *discovery;
214 unsigned long flags;
215 hashbin_t *cachelog = irlmp_get_cachelog();
217 if (!irlmp)
218 return len;
220 len = sprintf(buf, "IrLMP: Discovery log:\n\n");
222 save_flags(flags);
223 cli();
225 discovery = (discovery_t *) hashbin_get_first(cachelog);
226 while ( discovery != NULL) {
227 len += sprintf( buf+len, " name: %s,",
228 discovery->info);
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",
256 discovery->saddr);
258 len += sprintf(buf+len, ", daddr: 0x%08x\n",
259 discovery->daddr);
261 len += sprintf( buf+len, "\n");
263 discovery = (discovery_t *) hashbin_get_next(cachelog);
265 restore_flags(flags);
267 return len;