From 7d31cb4d456185a951fc98276b1244039317a0a2 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 8 Oct 2007 16:55:50 +0100 Subject: [PATCH] Basic device discovery infrastructure --- libfprint/core.c | 78 +++++++++++++++++++++++++++++++++++++++++ libfprint/fp_internal.h | 9 +++++ libfprint/fprint.h | 7 ++++ 3 files changed, 94 insertions(+) diff --git a/libfprint/core.c b/libfprint/core.c index e7ee538..744424f 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -20,6 +20,7 @@ #include #include +#include #include "fp_internal.h" @@ -42,8 +43,85 @@ static void register_drivers(void) register_driver(drivers[i]); } +static const struct fp_driver *find_supporting_driver(struct usb_device *udev) +{ + GList *elem = registered_drivers; + + do { + const struct fp_driver *drv = elem->data; + const struct usb_id *id; + + for (id = drv->id_table; id->vendor; id++) + if (udev->descriptor.idVendor == id->vendor && + udev->descriptor.idProduct == id->product) + return drv; + } while (elem = g_list_next(elem)); + return NULL; +} + +API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) +{ + GList *tmplist = NULL; + struct fp_dscv_dev **list; + struct usb_device *udev; + struct usb_bus *bus; + int dscv_count = 0; + + if (registered_drivers == NULL) + return NULL; + + usb_find_busses(); + usb_find_devices(); + + /* Check each device against each driver, temporarily storing successfully + * discovered devices in a GList. + * + * Quite inefficient but excusable as we'll only be dealing with small + * sets of drivers against small sets of USB devices */ + for (bus = usb_get_busses(); bus; bus = bus->next) + for (udev = bus->devices; udev; udev = udev->next) { + const struct fp_driver *drv = find_supporting_driver(udev); + struct fp_dscv_dev *ddev; + if (!drv) + continue; + ddev = g_malloc0(sizeof(*ddev)); + ddev->drv = drv; + ddev->udev = udev; + tmplist = g_list_prepend(tmplist, (gpointer) ddev); + dscv_count++; + } + + /* Convert our temporary GList into a standard NULL-terminated pointer + * array. */ + list = g_malloc(sizeof(*list) * (dscv_count + 1)); + if (dscv_count > 0) { + GList *elem = tmplist; + int i = 0; + do { + list[i++] = elem->data; + } while (elem = g_list_next(elem)); + } + list[dscv_count] = NULL; /* NULL-terminate */ + + g_list_free(tmplist); + return list; +} + +API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs) +{ + int i; + if (!devs) + return; + + for (i = 0; devs[i]; i++) + g_free(devs[i]); + g_free(devs); +} + API_EXPORTED int fp_init(void) { + usb_init(); register_drivers(); return 0; } + diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 19f5ee5..3b6ab05 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -22,6 +22,10 @@ #include +#include + +#include + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) struct usb_id { @@ -38,5 +42,10 @@ struct fp_driver { extern const struct fp_driver upekts_driver; +struct fp_dscv_dev { + struct usb_device *udev; + const struct fp_driver *drv; +}; + #endif diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 889dda7..5be5311 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -20,6 +20,13 @@ #ifndef __FPRINT_H__ #define __FPRINT_H__ +/* structs that applications are not allowed to peek into */ +struct fp_dscv_dev; + +/* Device discovery */ +struct fp_dscv_dev **fp_discover_devs(void); +void fp_dscv_devs_free(struct fp_dscv_dev **devs); + int fp_init(void); #endif