open/close device functions
[libfprint.git] / libfprint / core.c
bloba8922c55b45ebdf12c6fd153c89e7e175f5909df
1 /*
2 * Core functions for libfprint
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
22 #include <glib.h>
23 #include <usb.h>
25 #include "fp_internal.h"
27 static GList *registered_drivers = NULL;
29 static void register_driver(const struct fp_driver *drv)
31 registered_drivers = g_list_prepend(registered_drivers, (gpointer) drv);
34 static const struct fp_driver * const drivers[] = {
35 &upekts_driver,
38 static void register_drivers(void)
40 int i;
42 for (i = 0; i < ARRAY_SIZE(drivers); i++)
43 register_driver(drivers[i]);
46 static const struct fp_driver *find_supporting_driver(struct usb_device *udev)
48 GList *elem = registered_drivers;
50 do {
51 const struct fp_driver *drv = elem->data;
52 const struct usb_id *id;
54 for (id = drv->id_table; id->vendor; id++)
55 if (udev->descriptor.idVendor == id->vendor &&
56 udev->descriptor.idProduct == id->product)
57 return drv;
58 } while (elem = g_list_next(elem));
59 return NULL;
62 API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
64 GList *tmplist = NULL;
65 struct fp_dscv_dev **list;
66 struct usb_device *udev;
67 struct usb_bus *bus;
68 int dscv_count = 0;
70 if (registered_drivers == NULL)
71 return NULL;
73 usb_find_busses();
74 usb_find_devices();
76 /* Check each device against each driver, temporarily storing successfully
77 * discovered devices in a GList.
79 * Quite inefficient but excusable as we'll only be dealing with small
80 * sets of drivers against small sets of USB devices */
81 for (bus = usb_get_busses(); bus; bus = bus->next)
82 for (udev = bus->devices; udev; udev = udev->next) {
83 const struct fp_driver *drv = find_supporting_driver(udev);
84 struct fp_dscv_dev *ddev;
85 if (!drv)
86 continue;
87 ddev = g_malloc0(sizeof(*ddev));
88 ddev->drv = drv;
89 ddev->udev = udev;
90 tmplist = g_list_prepend(tmplist, (gpointer) ddev);
91 dscv_count++;
94 /* Convert our temporary GList into a standard NULL-terminated pointer
95 * array. */
96 list = g_malloc(sizeof(*list) * (dscv_count + 1));
97 if (dscv_count > 0) {
98 GList *elem = tmplist;
99 int i = 0;
100 do {
101 list[i++] = elem->data;
102 } while (elem = g_list_next(elem));
104 list[dscv_count] = NULL; /* NULL-terminate */
106 g_list_free(tmplist);
107 return list;
110 API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs)
112 int i;
113 if (!devs)
114 return;
116 for (i = 0; devs[i]; i++)
117 g_free(devs[i]);
118 g_free(devs);
121 API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev)
123 struct fp_dev *dev;
124 const struct fp_driver *drv = ddev->drv;
125 int r;
127 usb_dev_handle *udevh = usb_open(ddev->udev);
128 if (!udevh)
129 return NULL;
131 dev = g_malloc0(sizeof(*dev));
132 dev->drv = drv;
133 dev->udev = udevh;
135 if (drv->init) {
136 r = drv->init(dev);
137 if (r) {
138 usb_close(udevh);
139 g_free(dev);
140 return NULL;
144 return dev;
147 API_EXPORTED void fp_dev_close(struct fp_dev *dev)
149 if (dev->drv->exit)
150 dev->drv->exit(dev);
151 usb_close(dev->udev);
152 g_free(dev);
155 API_EXPORTED int fp_init(void)
157 usb_init();
158 register_drivers();
159 return 0;