~ubuntu-branches/ubuntu/saucy/libfprint/saucy

« back to all changes in this revision

Viewing changes to .pc/Fix-libusb-global-variables-FTBFS.patch/libfprint/core.c

  • Committer: Package Import Robot
  • Author(s): Didier Raboud
  • Date: 2012-07-09 00:46:05 UTC
  • mfrom: (2.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20120709004605-5mq86aro19eieovv
Tags: 1:0.4.0-4-gdfff16f-4
Fix libusb global variables FTBFS. (Closes: #680838)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Core functions for libfprint
 
3
 * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 */
 
19
 
 
20
#include <config.h>
 
21
#include <errno.h>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
 
 
25
#include <glib.h>
 
26
#include <libusb.h>
 
27
 
 
28
#include "fp_internal.h"
 
29
 
 
30
static int log_level = 0;
 
31
static int log_level_fixed = 0;
 
32
 
 
33
libusb_context *fpi_usb_ctx = NULL;
 
34
GSList *opened_devices = NULL;
 
35
 
 
36
/**
 
37
 * \mainpage libfprint API Reference
 
38
 * libfprint is an open source library to provide access to fingerprint
 
39
 * scanning devices. For more info, see the
 
40
 * <a href="http://www.reactivated.net/fprint/Libfprint">libfprint project
 
41
 * homepage</a>.
 
42
 *
 
43
 * This documentation is aimed at application developers who wish to integrate
 
44
 * fingerprint-related functionality into their software. libfprint has been
 
45
 * designed so that you only have to do this once - by integrating your
 
46
 * software with libfprint, you'll be supporting all the fingerprint readers
 
47
 * that we have got our hands on. As such, the API is rather general (and
 
48
 * therefore hopefully easy to comprehend!), and does its best to hide the
 
49
 * technical details that required to operate the hardware.
 
50
 *
 
51
 * This documentation is not aimed at developers wishing to develop and
 
52
 * contribute fingerprint device drivers to libfprint.
 
53
 *
 
54
 * Feedback on this API and its associated documentation is appreciated. Was
 
55
 * anything unclear? Does anything seem unreasonably complicated? Is anything
 
56
 * missing? Let us know on the
 
57
 * <a href="http://www.reactivated.net/fprint/Mailing_list">mailing list</a>.
 
58
 *
 
59
 * \section enrollment Enrollment
 
60
 *
 
61
 * Before you dive into the API, it's worth introducing a couple of concepts.
 
62
 *
 
63
 * The process of enrolling a finger is where you effectively scan your
 
64
 * finger for the purposes of teaching the system what your finger looks like.
 
65
 * This means that you scan your fingerprint, then the system processes it and
 
66
 * stores some data about your fingerprint to refer to later.
 
67
 *
 
68
 * \section verification Verification
 
69
 *
 
70
 * Verification is what most people think of when they think about fingerprint
 
71
 * scanning. The process of verification is effectively performing a fresh
 
72
 * fingerprint scan, and then comparing that scan to a finger that was 
 
73
 * previously enrolled.
 
74
 *
 
75
 * As an example scenario, verification can be used to implement what people
 
76
 * would picture as fingerprint login (i.e. fingerprint replaces password).
 
77
 * For example:
 
78
 *  - I enroll my fingerprint through some software that trusts I am who I say
 
79
 *    I am. This is a prerequisite before I can perform fingerprint-based
 
80
 *    login for my account.
 
81
 *  - Some time later, I want to login to my computer. I enter my username,
 
82
 *    but instead of prompting me for a password, it asks me to scan my finger.
 
83
 *    I scan my finger.
 
84
 *  - The system compares the finger I just scanned to the one that was
 
85
 *    enrolled earlier. If the system decides that the fingerprints match,
 
86
 *    I am successfully logged in. Otherwise, the system informs me that I am
 
87
 *    not authorised to login as that user.
 
88
 *
 
89
 * \section identification Identification
 
90
 *
 
91
 * Identification is the process of comparing a freshly scanned fingerprint
 
92
 * to a <em>collection</em> of previously enrolled fingerprints. For example,
 
93
 * imagine there are 100 people in an organisation, and they all have enrolled
 
94
 * their fingerprints. One user walks up to a fingerprint scanner and scans
 
95
 * their finger. With <em>no other knowledge</em> of who that user might be,
 
96
 * the system examines their fingerprint, looks in the database, and determines
 
97
 * that the user is user number #61.
 
98
 *
 
99
 * In other words, verification might be seen as a one-to-one fingerprint
 
100
 * comparison where you know the identity of the user that you wish to
 
101
 * authenticate, whereas identification is a one-to-many comparison where you
 
102
 * do not know the identity of the user that you wish to authenticate.
 
103
 *
 
104
 * \section compat_general Device and print compatibility
 
105
 * Moving off generic conceptual ideas and onto libfprint-specific
 
106
 * implementation details, here are some introductory notes regarding how
 
107
 * libfprint copes with compatibility of fingerprints.
 
108
 *
 
109
 * libfprint deals with a whole variety of different fingerprint readers and
 
110
 * the design includes considerations of compatibility and interoperability
 
111
 * between multiple devices. Your application should also be prepared to
 
112
 * work with more than one type of fingerprint reader and should consider that
 
113
 * enrolled fingerprint X may not be compatible with the device the user has
 
114
 * plugged in today.
 
115
 *
 
116
 * libfprint implements the principle that fingerprints from different devices
 
117
 * are not necessarily compatible. For example, different devices may see
 
118
 * significantly different areas of fingerprint surface, and comparing images
 
119
 * between the devices would be unreliable. Also, devices can stretch and
 
120
 * distort images in different ways.
 
121
 *
 
122
 * libfprint also implements the principle that in some cases, fingerprints
 
123
 * <em>are</em> compatible between different devices. If you go and buy two
 
124
 * identical fingerprint readers, it seems logical that you should be able
 
125
 * to enroll on one and verify on another without problems.
 
126
 *
 
127
 * libfprint takes a fairly simplistic approach to these issues. Internally,
 
128
 * fingerprint hardware is driven by individual drivers. libfprint enforces
 
129
 * that a fingerprint that came from a device backed by driver X is never
 
130
 * compared to a fingerprint that came from a device backed by driver Y.
 
131
 *
 
132
 * Additionally, libfprint is designed for the situation where a single driver
 
133
 * may support a range of devices which differ in imaging or scanning
 
134
 * properties. For example, a driver may support two ranges of devices which
 
135
 * even though are programmed over the same interface, one device sees
 
136
 * substantially less of the finger flesh, therefore images from the two
 
137
 * device types should be incompatible despite being from the same driver. To
 
138
 * implement this, each driver assigns a <em>device type</em> to each device
 
139
 * that it detects based on its imaging characteristics. libfprint ensures that
 
140
 * two prints being compared have the same device type.
 
141
 *
 
142
 * In summary, libfprint represents fingerprints in several internal structures
 
143
 * and each representation will offer you a way of determining the
 
144
 * \ref driver_id "driver ID" and \ref devtype "devtype" of the print in
 
145
 * question. Prints are only compatible if the driver ID <b>and</b> devtypes
 
146
 * match. libfprint does offer you some "is this print compatible?" helper
 
147
 * functions, so you don't have to worry about these details too much.
 
148
 *
 
149
 * \section sync Synchronity/asynchronity
 
150
 *
 
151
 * Currently, all data acquisition operations are synchronous and can
 
152
 * potentially block for extended periods of time. For example, the enroll
 
153
 * function will block for an unpredictable amount of time until the user
 
154
 * scans their finger.
 
155
 *
 
156
 * Alternative asynchronous/non-blocking functionality will be offered in
 
157
 * future but has not been implemented yet.
 
158
 *
 
159
 * \section getting_started Getting started
 
160
 *
 
161
 * libfprint includes several simple functional examples under the examples/
 
162
 * directory in the libfprint source distribution. Those are good starting
 
163
 * points.
 
164
 *
 
165
 * Usually the first thing you want to do is determine which fingerprint
 
166
 * devices are present. This is done through \ref dscv_dev "device discovery".
 
167
 *
 
168
 * Once you have found a device you would like to operate, you should open it.
 
169
 * Refer to \ref dev "device operations". This section also details enrollment,
 
170
 * image capture, and verification.
 
171
 *
 
172
 *
 
173
 * That should be enough to get you started, but do remember there are
 
174
 * documentation pages on other aspects of libfprint's API (see the modules
 
175
 * page).
 
176
 */
 
177
 
 
178
/** @defgroup core Core library operations */
 
179
 
 
180
/**
 
181
 * @defgroup dev Device operations
 
182
 * In order to interact with fingerprint scanners, your software will
 
183
 * interface primarily with libfprint's representation of devices, detailed
 
184
 * on this page.
 
185
 *
 
186
 * \section enrolling Enrolling
 
187
 * Enrolling is represented within libfprint as a multi-stage process. This
 
188
 * slightly complicates things for application developers, but is required
 
189
 * for a smooth process.
 
190
 *
 
191
 * Some devices require the user to scan their finger multiple times in
 
192
 * order to complete the enrollment process. libfprint must return control
 
193
 * to your application inbetween each scan in order for your application to
 
194
 * instruct the user to swipe their finger again. Each scan is referred to
 
195
 * as a stage, so a device that requires 3 scans for enrollment corresponds
 
196
 * to you running 3 enrollment stages using libfprint.
 
197
 *
 
198
 * The fp_dev_get_nr_enroll_stages() function can be used to find out how
 
199
 * many enroll stages are needed.
 
200
 *
 
201
 * In order to complete an enroll stage, you call an enroll function such
 
202
 * as fp_enroll_finger(). The return of this function does not necessarily
 
203
 * indicate that a stage has completed though, as the user may not have
 
204
 * produced a good enough scan. Each stage may have to be retried several
 
205
 * times.
 
206
 *
 
207
 * The exact semantics of the enroll functions are described in the
 
208
 * fp_enroll_finger() documentation. You should pay careful attention to the
 
209
 * details.
 
210
 *
 
211
 * \section imaging Imaging
 
212
 * libfprint provides you with some ways to retrieve images of scanned
 
213
 * fingers, such as the fp_dev_img_capture() function, or some enroll/verify
 
214
 * function variants which provide images. You may wish to do something with
 
215
 * such images in your application.
 
216
 *
 
217
 * However, you must be aware that not all hardware supported by libfprint
 
218
 * operates like this. Most hardware does operate simply by sending
 
219
 * fingerprint images to the host computer for further processing, but some
 
220
 * devices do all fingerprint processing in hardware and do not present images
 
221
 * to the host computer.
 
222
 *
 
223
 * You can use fp_dev_supports_imaging() to see if image capture is possible
 
224
 * on a particular device. Your application must be able to cope with the
 
225
 * fact that libfprint does support regular operations (e.g. enrolling and
 
226
 * verification) on some devices which do not provide images.
 
227
 *
 
228
 * \section devtype Devtypes
 
229
 * Internally, the \ref drv "driver" behind a device assigns a 32-bit
 
230
 * <em>devtype</em> identifier to the device. This cannot be used as a unique
 
231
 * ID for a specific device as many devices under the same range may share
 
232
 * the same devtype. The devtype may even be 0 in all cases.
 
233
 *
 
234
 * The only reason you may be interested in retrieving the devtype for a
 
235
 * device is for the purpose of checking if some print data is compatible
 
236
 * with a device. libfprint uses the devtype as one way of checking that the
 
237
 * print you are verifying is compatible with the device in question - the
 
238
 * devtypes must be equal. This effectively allows drivers to support more
 
239
 * than one type of device where the data from each one is not compatible with
 
240
 * the other. Note that libfprint does provide you with helper functions to
 
241
 * determine whether a print is compatible with a device, so under most
 
242
 * circumstances, you don't have to worry about devtypes at all.
 
243
 */
 
244
 
 
245
/** @defgroup dscv_dev Device discovery
 
246
 * These functions allow you to scan the system for supported fingerprint
 
247
 * scanning hardware. This is your starting point when integrating libfprint
 
248
 * into your software.
 
249
 *
 
250
 * When you've identified a discovered device that you would like to control,
 
251
 * you can open it with fp_dev_open(). Note that discovered devices may no
 
252
 * longer be available at the time when you want to open them, for example
 
253
 * the user may have unplugged the device.
 
254
 */
 
255
 
 
256
/** @defgroup drv Driver operations
 
257
 * Internally, libfprint is abstracted into various drivers to communicate
 
258
 * with the different types of supported fingerprint readers. libfprint works
 
259
 * hard so that you don't have to care about these internal abstractions,
 
260
 * however there are some situations where you may be interested in a little
 
261
 * behind-the-scenes driver info.
 
262
 *
 
263
 * You can obtain the driver for a device using fp_dev_get_driver(), which
 
264
 * you can pass to the functions documented on this page.
 
265
 *
 
266
 * \section driver_id Driver IDs
 
267
 * Each driver is assigned a unique ID by the project maintainer. These
 
268
 * assignments are
 
269
 * <a href="http://www.reactivated.net/fprint/Driver_ID_assignments">
 
270
 * documented on the wiki</a> and will never change.
 
271
 *
 
272
 * The only reason you may be interested in retrieving the driver ID for a
 
273
 * driver is for the purpose of checking if some print data is compatible
 
274
 * with a device. libfprint uses the driver ID as one way of checking that
 
275
 * the print you are trying to verify is compatible with the device in
 
276
 * question - it ensures that enrollment data from one driver is never fed to
 
277
 * another. Note that libfprint does provide you with helper functions to
 
278
 * determine whether a print is compatible with a device, so under most
 
279
 * circumstances, you don't have to worry about driver IDs at all.
 
280
 */
 
281
 
 
282
static GSList *registered_drivers = NULL;
 
283
 
 
284
void fpi_log(enum fpi_log_level level, const char *component,
 
285
        const char *function, const char *format, ...)
 
286
{
 
287
        va_list args;
 
288
        FILE *stream = stdout;
 
289
        const char *prefix;
 
290
 
 
291
#ifndef ENABLE_DEBUG_LOGGING
 
292
        if (!log_level)
 
293
                return;
 
294
        if (level == LOG_LEVEL_WARNING && log_level < 2)
 
295
                return;
 
296
        if (level == LOG_LEVEL_INFO && log_level < 3)
 
297
                return;
 
298
#endif
 
299
 
 
300
        switch (level) {
 
301
        case LOG_LEVEL_INFO:
 
302
                prefix = "info";
 
303
                break;
 
304
        case LOG_LEVEL_WARNING:
 
305
                stream = stderr;
 
306
                prefix = "warning";
 
307
                break;
 
308
        case LOG_LEVEL_ERROR:
 
309
                stream = stderr;
 
310
                prefix = "error";
 
311
                break;
 
312
        case LOG_LEVEL_DEBUG:
 
313
                stream = stderr;
 
314
                prefix = "debug";
 
315
                break;
 
316
        default:
 
317
                stream = stderr;
 
318
                prefix = "unknown";
 
319
                break;
 
320
        }
 
321
 
 
322
        fprintf(stream, "%s:%s [%s] ", component ? component : "fp", prefix,
 
323
                function);
 
324
 
 
325
        va_start (args, format);
 
326
        vfprintf(stream, format, args);
 
327
        va_end (args);
 
328
 
 
329
        fprintf(stream, "\n");
 
330
}
 
331
 
 
332
static void register_driver(struct fp_driver *drv)
 
333
{
 
334
        if (drv->id == 0) {
 
335
                fp_err("not registering driver %s: driver ID is 0", drv->name);
 
336
                return;
 
337
        }
 
338
        registered_drivers = g_slist_prepend(registered_drivers, (gpointer) drv);
 
339
        fp_dbg("registered driver %s", drv->name);
 
340
}
 
341
 
 
342
static struct fp_driver * const primitive_drivers[] = {
 
343
#ifdef ENABLE_UPEKTS
 
344
        &upekts_driver,
 
345
#endif
 
346
#ifdef ENABLE_UPEKE2
 
347
    &upeke2_driver,
 
348
#endif
 
349
};
 
350
 
 
351
static struct fp_img_driver * const img_drivers[] = {
 
352
#ifdef ENABLE_AES4000
 
353
        &aes4000_driver,
 
354
#endif
 
355
#ifdef ENABLE_AES2501
 
356
        &aes2501_driver,
 
357
#endif
 
358
#ifdef ENABLE_URU4000
 
359
        &uru4000_driver,
 
360
#endif
 
361
#ifdef ENABLE_VCOM5S
 
362
        &vcom5s_driver,
 
363
#endif
 
364
#ifdef ENABLE_UPEKSONLY
 
365
        &upeksonly_driver,
 
366
#endif
 
367
 
 
368
#ifdef ENABLE_AES1610
 
369
        &aes1610_driver,
 
370
#endif
 
371
#ifdef ENABLE_VFS101
 
372
        &vfs101_driver,
 
373
#endif
 
374
/*#ifdef ENABLE_UPEKTC
 
375
        &upektc_driver,
 
376
#endif
 
377
#ifdef ENABLE_FDU2000
 
378
        &fdu2000_driver,
 
379
#endif
 
380
        */
 
381
};
 
382
 
 
383
static void register_drivers(void)
 
384
{
 
385
        unsigned int i;
 
386
 
 
387
        for (i = 0; i < G_N_ELEMENTS(primitive_drivers); i++)
 
388
                register_driver(primitive_drivers[i]);
 
389
 
 
390
        for (i = 0; i < G_N_ELEMENTS(img_drivers); i++) {
 
391
                struct fp_img_driver *imgdriver = img_drivers[i];
 
392
                fpi_img_driver_setup(imgdriver);
 
393
                register_driver(&imgdriver->driver);
 
394
        }
 
395
}
 
396
 
 
397
API_EXPORTED struct fp_driver **fprint_get_drivers (void)
 
398
{
 
399
        GPtrArray *array;
 
400
        unsigned int i;
 
401
 
 
402
        array = g_ptr_array_new ();
 
403
        for (i = 0; i < G_N_ELEMENTS(primitive_drivers); i++)
 
404
                g_ptr_array_add (array, primitive_drivers[i]);
 
405
 
 
406
        for (i = 0; i < G_N_ELEMENTS(img_drivers); i++)
 
407
                g_ptr_array_add (array, &(img_drivers[i]->driver));
 
408
 
 
409
        /* Add a null item terminating the array */
 
410
        g_ptr_array_add (array, NULL);
 
411
 
 
412
        return (struct fp_driver **) g_ptr_array_free (array, FALSE);
 
413
}
 
414
 
 
415
static struct fp_driver *find_supporting_driver(libusb_device *udev,
 
416
        const struct usb_id **usb_id, uint32_t *devtype)
 
417
{
 
418
        int ret;
 
419
        GSList *elem = registered_drivers;
 
420
        struct libusb_device_descriptor dsc;
 
421
 
 
422
        const struct usb_id *best_usb_id;
 
423
        struct fp_driver *best_drv;
 
424
        uint32_t best_devtype;
 
425
        int drv_score = 0;
 
426
 
 
427
        ret = libusb_get_device_descriptor(udev, &dsc);
 
428
        if (ret < 0) {
 
429
                fp_err("Failed to get device descriptor");
 
430
                return NULL;
 
431
        }
 
432
 
 
433
        best_drv = NULL;
 
434
        best_devtype = 0;
 
435
 
 
436
        do {
 
437
                struct fp_driver *drv = elem->data;
 
438
                uint32_t type = 0;
 
439
                const struct usb_id *id;
 
440
 
 
441
                for (id = drv->id_table; id->vendor; id++) {
 
442
                        if (dsc.idVendor == id->vendor && dsc.idProduct == id->product) {
 
443
                                if (drv->discover) {
 
444
                                        int r = drv->discover(&dsc, &type);
 
445
                                        if (r < 0)
 
446
                                                fp_err("%s discover failed, code %d", drv->name, r);
 
447
                                        if (r <= 0)
 
448
                                                continue;
 
449
                                        /* Has a discover function, and matched our device */
 
450
                                        drv_score = 100;
 
451
                                } else {
 
452
                                        /* Already got a driver as good */
 
453
                                        if (drv_score >= 50)
 
454
                                                continue;
 
455
                                        drv_score = 50;
 
456
                                }
 
457
                                fp_dbg("driver %s supports USB device %04x:%04x",
 
458
                                        drv->name, id->vendor, id->product);
 
459
                                best_usb_id = id;
 
460
                                best_drv = drv;
 
461
                                best_devtype = type;
 
462
 
 
463
                                /* We found the best possible driver */
 
464
                                if (drv_score == 100)
 
465
                                        break;
 
466
                        }
 
467
                }
 
468
        } while ((elem = g_slist_next(elem)));
 
469
 
 
470
        if (best_drv != NULL) {
 
471
                fp_dbg("selected driver %s supports USB device %04x:%04x",
 
472
                       best_drv->name, dsc.idVendor, dsc.idProduct);
 
473
                *devtype = best_devtype;
 
474
                *usb_id = best_usb_id;
 
475
        }
 
476
 
 
477
        return best_drv;
 
478
}
 
479
 
 
480
static struct fp_dscv_dev *discover_dev(libusb_device *udev)
 
481
{
 
482
        const struct usb_id *usb_id;
 
483
        struct fp_driver *drv;
 
484
        struct fp_dscv_dev *ddev;
 
485
        uint32_t devtype;
 
486
 
 
487
        drv = find_supporting_driver(udev, &usb_id, &devtype);
 
488
 
 
489
        if (!drv)
 
490
                return NULL;
 
491
 
 
492
        ddev = g_malloc0(sizeof(*ddev));
 
493
        ddev->drv = drv;
 
494
        ddev->udev = udev;
 
495
        ddev->driver_data = usb_id->driver_data;
 
496
        ddev->devtype = devtype;
 
497
        return ddev;
 
498
}
 
499
 
 
500
/** \ingroup dscv_dev
 
501
 * Scans the system and returns a list of discovered devices. This is your
 
502
 * entry point into finding a fingerprint reader to operate.
 
503
 * \returns a NULL-terminated list of discovered devices. Must be freed with
 
504
 * fp_dscv_devs_free() after use.
 
505
 */
 
506
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
 
507
{
 
508
        GSList *tmplist = NULL;
 
509
        struct fp_dscv_dev **list;
 
510
        libusb_device *udev;
 
511
        libusb_device **devs;
 
512
        int dscv_count = 0;
 
513
        int r;
 
514
        int i = 0;
 
515
 
 
516
        if (registered_drivers == NULL)
 
517
                return NULL;
 
518
 
 
519
        r = libusb_get_device_list(fpi_usb_ctx, &devs);
 
520
        if (r < 0) {
 
521
                fp_err("couldn't enumerate USB devices, error %d", r);
 
522
                return NULL;
 
523
        }
 
524
 
 
525
        /* Check each device against each driver, temporarily storing successfully
 
526
         * discovered devices in a GSList.
 
527
         *
 
528
         * Quite inefficient but excusable as we'll only be dealing with small
 
529
         * sets of drivers against small sets of USB devices */
 
530
        while ((udev = devs[i++]) != NULL) {
 
531
                struct fp_dscv_dev *ddev = discover_dev(udev);
 
532
                if (!ddev)
 
533
                        continue;
 
534
                tmplist = g_slist_prepend(tmplist, (gpointer) ddev);
 
535
                dscv_count++;
 
536
        }
 
537
 
 
538
        /* Convert our temporary GSList into a standard NULL-terminated pointer
 
539
         * array. */
 
540
        list = g_malloc(sizeof(*list) * (dscv_count + 1));
 
541
        if (dscv_count > 0) {
 
542
                GSList *elem = tmplist;
 
543
                i = 0;
 
544
                do {
 
545
                        list[i++] = elem->data;
 
546
                } while ((elem = g_slist_next(elem)));
 
547
        }
 
548
        list[dscv_count] = NULL; /* NULL-terminate */
 
549
 
 
550
        g_slist_free(tmplist);
 
551
        return list;
 
552
}
 
553
 
 
554
/** \ingroup dscv_dev
 
555
 * Free a list of discovered devices. This function destroys the list and all
 
556
 * discovered devices that it included, so make sure you have opened your
 
557
 * discovered device <b>before</b> freeing the list.
 
558
 * \param devs the list of discovered devices. If NULL, function simply
 
559
 * returns.
 
560
 */
 
561
API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs)
 
562
{
 
563
        int i;
 
564
        if (!devs)
 
565
                return;
 
566
 
 
567
        for (i = 0; devs[i]; i++)
 
568
                g_free(devs[i]);
 
569
        g_free(devs);
 
570
}
 
571
 
 
572
/** \ingroup dscv_dev
 
573
 * Gets the \ref drv "driver" for a discovered device.
 
574
 * \param dev the discovered device
 
575
 * \returns the driver backing the device
 
576
 */
 
577
API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
 
578
{
 
579
        return dev->drv;
 
580
}
 
581
 
 
582
/** \ingroup dscv_dev
 
583
 * Gets the \ref devtype "devtype" for a discovered device.
 
584
 * \param dev the discovered device
 
585
 * \returns the devtype of the device
 
586
 */
 
587
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
 
588
{
 
589
        return dev->devtype;
 
590
}
 
591
 
 
592
enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv)
 
593
{
 
594
        switch (drv->type) {
 
595
        case DRIVER_PRIMITIVE:
 
596
                return PRINT_DATA_RAW;
 
597
        case DRIVER_IMAGING:
 
598
                return PRINT_DATA_NBIS_MINUTIAE;
 
599
        default:
 
600
                fp_err("unrecognised drv type %d", drv->type);
 
601
                return PRINT_DATA_RAW;
 
602
        }
 
603
}
 
604
 
 
605
/** \ingroup dscv_dev
 
606
 * Determines if a specific \ref print_data "stored print" appears to be
 
607
 * compatible with a discovered device.
 
608
 * \param dev the discovered device
 
609
 * \param data the print for compatibility checking
 
610
 * \returns 1 if the print is compatible with the device, 0 otherwise
 
611
 */
 
612
API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
 
613
        struct fp_print_data *data)
 
614
{
 
615
        return fpi_print_data_compatible(dev->drv->id, dev->devtype,
 
616
                fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
 
617
                data->type);
 
618
}
 
619
 
 
620
/** \ingroup dscv_dev
 
621
 * Determines if a specific \ref dscv_print "discovered print" appears to be
 
622
 * compatible with a discovered device.
 
623
 * \param dev the discovered device
 
624
 * \param data the discovered print for compatibility checking
 
625
 * \returns 1 if the print is compatible with the device, 0 otherwise
 
626
 */
 
627
API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev,
 
628
        struct fp_dscv_print *data)
 
629
{
 
630
        return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0,
 
631
                data->driver_id, data->devtype, 0);
 
632
}
 
633
 
 
634
/** \ingroup dscv_dev
 
635
 * Searches a list of discovered devices for a device that appears to be
 
636
 * compatible with a \ref print_data "stored print".
 
637
 * \param devs a list of discovered devices
 
638
 * \param data the print under inspection
 
639
 * \returns the first discovered device that appears to support the print, or
 
640
 * NULL if no apparently compatible devices could be found
 
641
 */
 
642
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs,
 
643
        struct fp_print_data *data)
 
644
{
 
645
        struct fp_dscv_dev *ddev;
 
646
        int i;
 
647
 
 
648
        for (i = 0; (ddev = devs[i]); i++)
 
649
                if (fp_dscv_dev_supports_print_data(ddev, data))
 
650
                        return ddev;
 
651
        return NULL;
 
652
}
 
653
 
 
654
/** \ingroup dscv_dev
 
655
 * Searches a list of discovered devices for a device that appears to be
 
656
 * compatible with a \ref dscv_print "discovered print".
 
657
 * \param devs a list of discovered devices
 
658
 * \param print the print under inspection
 
659
 * \returns the first discovered device that appears to support the print, or
 
660
 * NULL if no apparently compatible devices could be found
 
661
 */
 
662
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs,
 
663
        struct fp_dscv_print *print)
 
664
{
 
665
        struct fp_dscv_dev *ddev;
 
666
        int i;
 
667
 
 
668
        for (i = 0; (ddev = devs[i]); i++)
 
669
                if (fp_dscv_dev_supports_dscv_print(ddev, print))
 
670
                        return ddev;
 
671
        return NULL;
 
672
}
 
673
 
 
674
/** \ingroup dev
 
675
 * Get the \ref drv "driver" for a fingerprint device.
 
676
 * \param dev the device
 
677
 * \returns the driver controlling the device
 
678
 */
 
679
API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
 
680
{
 
681
        return dev->drv;
 
682
}
 
683
 
 
684
/** \ingroup dev
 
685
 * Gets the number of \ref enrolling "enroll stages" required to enroll a
 
686
 * fingerprint with the device.
 
687
 * \param dev the device
 
688
 * \returns the number of enroll stages
 
689
 */
 
690
API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
 
691
{
 
692
        return dev->nr_enroll_stages;
 
693
}
 
694
 
 
695
/** \ingroup dev
 
696
 * Gets the \ref devtype "devtype" for a device.
 
697
 * \param dev the device
 
698
 * \returns the devtype
 
699
 */
 
700
API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
 
701
{
 
702
        return dev->devtype;
 
703
}
 
704
 
 
705
/** \ingroup dev
 
706
 * Determines if a stored print is compatible with a certain device.
 
707
 * \param dev the device
 
708
 * \param data the stored print
 
709
 * \returns 1 if the print is compatible with the device, 0 if not
 
710
 */
 
711
API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
 
712
        struct fp_print_data *data)
 
713
{
 
714
        return fpi_print_data_compatible(dev->drv->id, dev->devtype,
 
715
                fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
 
716
                data->type);
 
717
}
 
718
 
 
719
/** \ingroup dev
 
720
 * Determines if a \ref dscv_print "discovered print" appears to be compatible
 
721
 * with a certain device.
 
722
 * \param dev the device
 
723
 * \param data the discovered print
 
724
 * \returns 1 if the print is compatible with the device, 0 if not
 
725
 */
 
726
API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
 
727
        struct fp_dscv_print *data)
 
728
{
 
729
        return fpi_print_data_compatible(dev->drv->id, dev->devtype,
 
730
                0, data->driver_id, data->devtype, 0);
 
731
}
 
732
 
 
733
/** \ingroup drv
 
734
 * Retrieves the name of the driver. For example: "upekts"
 
735
 * \param drv the driver
 
736
 * \returns the driver name. Must not be modified or freed.
 
737
 */
 
738
API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
 
739
{
 
740
        return drv->name;
 
741
}
 
742
 
 
743
/** \ingroup drv
 
744
 * Retrieves a descriptive name of the driver. For example: "UPEK TouchStrip"
 
745
 * \param drv the driver
 
746
 * \returns the descriptive name. Must not be modified or freed.
 
747
 */
 
748
API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
 
749
{
 
750
        return drv->full_name;
 
751
}
 
752
 
 
753
/** \ingroup drv
 
754
 * Retrieves the driver ID code for a driver.
 
755
 * \param drv the driver
 
756
 * \returns the driver ID
 
757
 */
 
758
API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
 
759
{
 
760
        return drv->id;
 
761
}
 
762
 
 
763
/** \ingroup drv
 
764
 * Retrieves the scan type for the devices associated with the driver.
 
765
 * \param drv the driver
 
766
 * \returns the scan type
 
767
 */
 
768
API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv)
 
769
{
 
770
        return drv->scan_type;
 
771
}
 
772
 
 
773
static struct fp_img_dev *dev_to_img_dev(struct fp_dev *dev)
 
774
{
 
775
        if (dev->drv->type != DRIVER_IMAGING)
 
776
                return NULL;
 
777
        return dev->priv;
 
778
}
 
779
 
 
780
/** \ingroup dev
 
781
 * Determines if a device has imaging capabilities. If a device has imaging
 
782
 * capabilities you are able to perform imaging operations such as retrieving
 
783
 * scan images using fp_dev_img_capture(). However, not all devices are
 
784
 * imaging devices - some do all processing in hardware. This function will
 
785
 * indicate which class a device in question falls into.
 
786
 * \param dev the fingerprint device
 
787
 * \returns 1 if the device is an imaging device, 0 if the device does not
 
788
 * provide images to the host computer
 
789
 */
 
790
API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
 
791
{
 
792
        return dev->drv->type == DRIVER_IMAGING;
 
793
}
 
794
 
 
795
/** \ingroup dev
 
796
 * Determines if a device is capable of \ref identification "identification"
 
797
 * through fp_identify_finger() and similar. Not all devices support this
 
798
 * functionality.
 
799
 * \param dev the fingerprint device
 
800
 * \returns 1 if the device is capable of identification, 0 otherwise.
 
801
 */
 
802
API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
 
803
{
 
804
        return dev->drv->identify_start != NULL;
 
805
}
 
806
 
 
807
/** \ingroup dev
 
808
 * Captures an \ref img "image" from a device. The returned image is the raw
 
809
 * image provided by the device, you may wish to \ref img_std "standardize" it.
 
810
 *
 
811
 * If set, the <tt>unconditional</tt> flag indicates that the device should
 
812
 * capture an image unconditionally, regardless of whether a finger is there
 
813
 * or not. If unset, this function will block until a finger is detected on
 
814
 * the sensor.
 
815
 *
 
816
 * \param dev the device
 
817
 * \param unconditional whether to unconditionally capture an image, or to only capture when a finger is detected
 
818
 * \param image a location to return the captured image. Must be freed with
 
819
 * fp_img_free() after use.
 
820
 * \return 0 on success, non-zero on error. -ENOTSUP indicates that either the
 
821
 * unconditional flag was set but the device does not support this, or that the
 
822
 * device does not support imaging.
 
823
 * \sa fp_dev_supports_imaging()
 
824
 */
 
825
API_EXPORTED int fp_dev_img_capture(struct fp_dev *dev, int unconditional,
 
826
        struct fp_img **image)
 
827
{
 
828
        struct fp_img_dev *imgdev = dev_to_img_dev(dev);
 
829
        if (!imgdev) {
 
830
                fp_dbg("image capture on non-imaging device");
 
831
                return -ENOTSUP;
 
832
        }
 
833
 
 
834
        //return fpi_imgdev_capture(imgdev, unconditional, image);
 
835
        /* FIXME reimplement async */
 
836
        return -ENOTSUP;
 
837
}
 
838
 
 
839
/** \ingroup dev
 
840
 * Gets the expected width of images that will be captured from the device.
 
841
 * This function will return -1 for devices that are not
 
842
 * \ref imaging "imaging devices". If the width of images from this device
 
843
 * can vary, 0 will be returned.
 
844
 * \param dev the device
 
845
 * \returns the expected image width, or 0 for variable, or -1 for non-imaging
 
846
 * devices.
 
847
 */
 
848
API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
 
849
{
 
850
        struct fp_img_dev *imgdev = dev_to_img_dev(dev);
 
851
        if (!imgdev) {
 
852
                fp_dbg("get image width for non-imaging device");
 
853
                return -1;
 
854
        }
 
855
 
 
856
        return fpi_imgdev_get_img_width(imgdev);
 
857
}
 
858
 
 
859
/** \ingroup dev
 
860
 * Gets the expected height of images that will be captured from the device.
 
861
 * This function will return -1 for devices that are not
 
862
 * \ref imaging "imaging devices". If the height of images from this device
 
863
 * can vary, 0 will be returned.
 
864
 * \param dev the device
 
865
 * \returns the expected image height, or 0 for variable, or -1 for non-imaging
 
866
 * devices.
 
867
 */
 
868
API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev)
 
869
{
 
870
        struct fp_img_dev *imgdev = dev_to_img_dev(dev);
 
871
        if (!imgdev) {
 
872
                fp_dbg("get image height for non-imaging device");
 
873
                return -1;
 
874
        }
 
875
 
 
876
        return fpi_imgdev_get_img_height(imgdev);
 
877
}
 
878
 
 
879
/** \ingroup core
 
880
 * Set message verbosity.
 
881
 *  - Level 0: no messages ever printed by the library (default)
 
882
 *  - Level 1: error messages are printed to stderr
 
883
 *  - Level 2: warning and error messages are printed to stderr
 
884
 *  - Level 3: informational messages are printed to stdout, warning and error
 
885
 *    messages are printed to stderr
 
886
 *
 
887
 * The default level is 0, which means no messages are ever printed. If you
 
888
 * choose to increase the message verbosity level, ensure that your
 
889
 * application does not close the stdout/stderr file descriptors.
 
890
 *
 
891
 * You are advised to set level 3. libfprint is conservative with its message
 
892
 * logging and most of the time, will only log messages that explain error
 
893
 * conditions and other oddities. This will help you debug your software.
 
894
 *
 
895
 * If the LIBFPRINT_DEBUG environment variable was set when libfprint was
 
896
 * initialized, this function does nothing: the message verbosity is fixed
 
897
 * to the value in the environment variable.
 
898
 *
 
899
 * If libfprint was compiled without any message logging, this function does
 
900
 * nothing: you'll never get any messages.
 
901
 *
 
902
 * If libfprint was compiled with verbose debug message logging, this function
 
903
 * does nothing: you'll always get messages from all levels.
 
904
 *
 
905
 * \param ctx the context to operate on, or NULL for the default context
 
906
 * \param level debug level to set
 
907
 */
 
908
API_EXPORTED void fp_set_debug(int level)
 
909
{
 
910
        if (log_level_fixed)
 
911
                return;
 
912
 
 
913
        log_level = level;
 
914
        libusb_set_debug(fpi_usb_ctx, level);
 
915
}
 
916
 
 
917
/** \ingroup core
 
918
 * Initialise libfprint. This function must be called before you attempt to
 
919
 * use the library in any way.
 
920
 * \return 0 on success, non-zero on error.
 
921
 */
 
922
API_EXPORTED int fp_init(void)
 
923
{
 
924
        char *dbg = getenv("LIBFPRINT_DEBUG");
 
925
        int r;
 
926
        fp_dbg("");
 
927
 
 
928
        r = libusb_init(&fpi_usb_ctx);
 
929
        if (r < 0)
 
930
                return r;
 
931
 
 
932
        if (dbg) {
 
933
                log_level = atoi(dbg);
 
934
                if (log_level) {
 
935
                        log_level_fixed = 1;
 
936
                        libusb_set_debug(fpi_usb_ctx, log_level);
 
937
                }
 
938
        }
 
939
 
 
940
        register_drivers();
 
941
        fpi_poll_init();
 
942
        return 0;
 
943
}
 
944
 
 
945
/** \ingroup core
 
946
 * Deinitialise libfprint. This function should be called during your program
 
947
 * exit sequence. You must not use any libfprint functions after calling this
 
948
 * function, unless you call fp_init() again.
 
949
 */
 
950
API_EXPORTED void fp_exit(void)
 
951
{
 
952
        fp_dbg("");
 
953
 
 
954
        if (opened_devices) {
 
955
                GSList *copy = g_slist_copy(opened_devices);
 
956
                GSList *elem = copy;
 
957
                fp_dbg("naughty app left devices open on exit!");
 
958
 
 
959
                do
 
960
                        fp_dev_close((struct fp_dev *) elem->data);
 
961
                while ((elem = g_slist_next(elem)));
 
962
 
 
963
                g_slist_free(copy);
 
964
                g_slist_free(opened_devices);
 
965
                opened_devices = NULL;
 
966
        }
 
967
 
 
968
        fpi_data_exit();
 
969
        fpi_poll_exit();
 
970
        g_slist_free(registered_drivers);
 
971
        registered_drivers = NULL;
 
972
        libusb_exit(fpi_usb_ctx);
 
973
}
 
974