diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /net/irda/discovery.c | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'net/irda/discovery.c')
-rw-r--r-- | net/irda/discovery.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/net/irda/discovery.c b/net/irda/discovery.c new file mode 100644 index 000000000..22def3a1e --- /dev/null +++ b/net/irda/discovery.c @@ -0,0 +1,245 @@ +/********************************************************************* + * + * Filename: discovery.c + * Version: 0.1 + * Description: Routines for handling discoveries at the IrLMP layer + * Status: Experimental. + * Author: Dag Brattli <dagb@cs.uit.no> + * Created at: Tue Apr 6 15:33:50 1999 + * Modified at: Sun Apr 11 00:41:58 1999 + * Modified by: Dag Brattli <dagb@cs.uit.no> + * + * Copyright (c) 1999 Dag Brattli, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#include <linux/socket.h> +#include <linux/irda.h> + +#include <net/irda/irda.h> +#include <net/irda/irlmp.h> + +#include <net/irda/discovery.h> + +/* + * Function irlmp_add_discovery (cachelog, discovery) + * + * + * + */ +void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *discovery) +{ + discovery_t *old; + + DEBUG(4, __FUNCTION__ "()\n"); + + /* Check if we have discovered this device before */ + old = hashbin_remove(cachelog, discovery->daddr, NULL); + if (old) + kfree(old); + + /* Insert the new and updated version */ + hashbin_insert(cachelog, (QUEUE *) discovery, discovery->daddr, NULL); +} + +/* + * Function irlmp_add_discovery_log (cachelog, log) + * + * + * + */ +void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log) +{ + discovery_t *discovery; + + DEBUG(4, __FUNCTION__ "()\n"); + + /* + * If log is missing this means that IrLAP was unable to perform the + * discovery, so restart discovery again with just the half timeout + * of the normal one. + */ + if (log == NULL) { + /* irlmp_start_discovery_timer(irlmp, 150); */ + return; + } + + discovery = (discovery_t *) hashbin_remove_first(log); + while (discovery != NULL) { + irlmp_add_discovery(cachelog, discovery); + + discovery = (discovery_t *) hashbin_remove_first(log); + } + + /* Delete the now empty log */ + hashbin_delete(log, (FREE_FUNC) kfree); +} + +/* + * Function irlmp_expire_discoveries (log, saddr, force) + * + * Go through all discoveries and expire all that has stayed to long + * + */ +void irlmp_expire_discoveries(hashbin_t *log, int saddr, int force) +{ + discovery_t *discovery, *curr; + + DEBUG(4, __FUNCTION__ "()\n"); + + discovery = (discovery_t *) hashbin_get_first(log); + while (discovery != NULL) { + curr = discovery; + + /* Be sure to be one item ahead */ + discovery = (discovery_t *) hashbin_get_next(log); + + /* Test if it's time to expire this discovery */ + if ((curr->saddr == saddr) && (force || + ((jiffies - curr->timestamp) > DISCOVERY_EXPIRE_TIMEOUT))) + { + curr = hashbin_remove(log, curr->daddr, NULL); + if (curr) + kfree(curr); + } + } +} + +/* + * Function irlmp_dump_discoveries (log) + * + * Print out all discoveries in log + * + */ +void irlmp_dump_discoveries(hashbin_t *log) +{ + discovery_t *discovery; + + ASSERT(log != NULL, return;); + + discovery = (discovery_t *) hashbin_get_first(log); + while (discovery != NULL) { + DEBUG(0, "Discovery:\n"); + DEBUG(0, " daddr=%08x\n", discovery->daddr); + DEBUG(0, " saddr=%08x\n", discovery->saddr); + DEBUG(0, " name=%s\n", discovery->info); + + discovery = (discovery_t *) hashbin_get_next(log); + } +} + +/* + * Function irlmp_find_device (name, saddr) + * + * Look through the discovery log at each of the links and try to find + * the device with the given name. Return daddr and saddr. If saddr is + * specified, that look at that particular link only (not impl). + */ +__u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr) +{ + discovery_t *d; + unsigned long flags; + + spin_lock_irqsave(&irlmp->lock, flags); + + /* Look at all discoveries for that link */ + d = (discovery_t *) hashbin_get_first(cachelog); + while (d != NULL) { + DEBUG(1, "Discovery:\n"); + DEBUG(1, " daddr=%08x\n", d->daddr); + DEBUG(1, " name=%s\n", d->info); + + if (strcmp(name, d->info) == 0) { + *saddr = d->saddr; + + spin_unlock_irqrestore(&irlmp->lock, flags); + return d->daddr; + } + d = (discovery_t *) hashbin_get_next(cachelog); + } + + spin_unlock_irqrestore(&irlmp->lock, flags); + + return 0; +} + +/* + * Function proc_discovery_read (buf, start, offset, len, unused) + * + * Print discovery information in /proc file system + * + */ +int discovery_proc_read(char *buf, char **start, off_t offset, int len, + int unused) +{ + discovery_t *discovery; + unsigned long flags; + hashbin_t *cachelog = irlmp_get_cachelog(); + + if (!irlmp) + return len; + + len = sprintf(buf, "IrLMP: Discovery log:\n\n"); + + save_flags(flags); + cli(); + + discovery = (discovery_t *) hashbin_get_first(cachelog); + while ( discovery != NULL) { + len += sprintf( buf+len, " name: %s,", + discovery->info); + + len += sprintf( buf+len, " hint: "); + if ( discovery->hints.byte[0] & HINT_PNP) + len += sprintf( buf+len, "PnP Compatible "); + if ( discovery->hints.byte[0] & HINT_PDA) + len += sprintf( buf+len, "PDA/Palmtop "); + if ( discovery->hints.byte[0] & HINT_COMPUTER) + len += sprintf( buf+len, "Computer "); + if ( discovery->hints.byte[0] & HINT_PRINTER) + len += sprintf( buf+len, "Printer "); + if ( discovery->hints.byte[0] & HINT_MODEM) + len += sprintf( buf+len, "Modem "); + if ( discovery->hints.byte[0] & HINT_FAX) + len += sprintf( buf+len, "Fax "); + if ( discovery->hints.byte[0] & HINT_LAN) + len += sprintf( buf+len, "LAN Access "); + + if ( discovery->hints.byte[1] & HINT_TELEPHONY) + len += sprintf( buf+len, "Telephony "); + if ( discovery->hints.byte[1] & HINT_FILE_SERVER) + len += sprintf( buf+len, "File Server "); + if ( discovery->hints.byte[1] & HINT_COMM) + len += sprintf( buf+len, "IrCOMM "); + if ( discovery->hints.byte[1] & HINT_OBEX) + len += sprintf( buf+len, "IrOBEX "); + + len += sprintf(buf+len, ", saddr: 0x%08x", + discovery->saddr); + + len += sprintf(buf+len, ", daddr: 0x%08x\n", + discovery->daddr); + + len += sprintf( buf+len, "\n"); + + discovery = (discovery_t *) hashbin_get_next(cachelog); + } + restore_flags(flags); + + return len; +} |