core.c 35.6 KB
Newer Older
Daniel Drake's avatar
Daniel Drake committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Core functions for libfprint
 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <config.h>
21 22
#include <errno.h>
#include <stdio.h>
Daniel Drake's avatar
Daniel Drake committed
23

24
#include <glib.h>
25
#include <usb.h>
26 27 28

#include "fp_internal.h"

Daniel Drake's avatar
Daniel Drake committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
/**
 * \mainpage libfprint API Reference
 * libfprint is an open source library to provide access to fingerprint
 * scanning devices. For more info, see the
 * <a href="http://www.reactivated.net/fprint/Libfprint">libfprint project
 * homepage</a>.
 *
 * This documentation is aimed at application developers who wish to integrate
 * fingerprint-related functionality into their software. libfprint has been
 * designed so that you only have to do this once - by integrating your
 * software with libfprint, you'll be supporting all the fingerprint readers
 * that we have got our hands on. As such, the API is rather general (and
 * therefore hopefully easy to comprehend!), and does it's best to hide the
 * technical details that required to operate the hardware.
 *
 * This documentation is not aimed at developers wishing to develop and
 * contribute fingerprint device drivers to libfprint.
 *
 * Feedback on this API and it's associated documentation is appreciated. Was
 * anything unclear? Does anything seem unreasonably complicated? Is anything
 * missing? Let us know on the
 * <a href="http://www.reactivated.net/fprint/Mailing_list">mailing list</a>.
 *
 * \section enrollment Enrollment
 *
 * Before you dive into the API, it's worth introducing a couple of concepts.
 *
 * The process of enrolling a finger is where you effectively scan your
 * finger for the purposes of teaching the system what your finger looks like.
 * This means that you scan your fingerprint, then the system processes it and
 * stores some data about your fingerprint to refer to later.
 *
 * \section verification Verification
 *
 * Verification is what most people think of when they think about fingerprint
 * scanning. The process of verification is effectively performing a fresh
 * fingerprint scan, and then comparing that scan to a finger that was 
 * previously enrolled.
 *
 * As an example scenario, verification can be used to implement what people
 * would picture as fingerprint login (i.e. fingerprint replaces password).
 * For example:
 *  - I enroll my fingerprint through some software that trusts I am who I say
 *    I am. This is a prerequisite before I can perform fingerprint-based
 *    login for my account.
 *  - Some time later, I want to login to my computer. I enter my username,
 *    but instead of prompting me for a password, it asks me to scan my finger.
 *    I scan my finger.
 *  - The system compares the finger I just scanned to the one that was
 *    enrolled earlier. If the system decides that the fingerprints match,
 *    I am successfully logged in. Otherwise, the system informs me that I am
 *    not authorised to login as that user.
 *
 * \section identification Identification
 *
 * libfprint supports enrollment and verification as described above. Although
 * libfprint does not yet support identification (it is planned), it is worth
 * introducing the concept to give you a complete picture.
 *
 * Identification is the process of comparing a freshly scanned fingerprint
 * to a <em>collection</em> of previously enrolled fingerprints. For example,
 * imagine there are 100 people in an organisation, and they all have enrolled
 * their fingerprints. One user walks up to a fingerprint scanner and scans
 * their finger. With <em>no other knowledge</em> of who that user might be,
 * the system examines their fingerprint, looks in the database, and determines
 * that the user is user number #61.
 *
 * In other words, verification might be seen as a one-to-one fingerprint
 * comparison where you know the identity of the user that you wish to
 * authenticate, whereas identification is a one-to-many comparison where you
 * do not know the identity of the user that you wish to authenticate.
 *
 * \section compat_general Device and print compatibility
 * Moving off generic conceptual ideas and onto libfprint-specific
 * implementation details, here are some introductory notes regarding how
 * libfprint copes with compatibility of fingerprints.
 *
 * libfprint deals with a whole variety of different fingerprint readers and
 * the design includes considerations of compatibility and interoperability
 * between multiple devices. Your application should also be prepared to
 * work with more than one type of fingerprint reader and should consider that
 * enrolled fingerprint X may not be compatible with the device the user has
 * plugged in today.
 *
 * libfprint implements the principle that fingerprints from different devices
 * are not necessarily compatible. For example, different devices may see
 * significantly different areas of fingerprint surface, and comparing images
 * between the devices would be unreliable. Also, devices can stretch and
 * distort images in different ways.
 *
 * libfprint also implements the principle that in some cases, fingerprints
 * <em>are</em> compatible between different devices. If you go and buy two
 * identical fingerprint readers, it seems logical that you should be able
 * to enroll on one and verify on another without problems.
 *
 * libfprint takes a fairly simplistic approach to these issues. Internally,
 * fingerprint hardware is driven by individual drivers. libfprint enforces
 * that a fingerprint that came from a device backed by driver X is never
 * compared to a fingerprint that came from a device backed by driver Y.
 *
 * Additionally, libfprint is designed for the situation where a single driver
 * may support a range of devices which differ in imaging or scanning
 * properties. For example, a driver may support two ranges of devices which
 * even though are programmed over the same interface, one device sees
 * substantially less of the finger flesh, therefore images from the two
 * device types should be incompatible despite being from the same driver. To
 * implement this, each driver assigns a <em>device type</em> to each device
 * that it detects based on its imaging characteristics. libfprint ensures that
 * two prints being compared have the same device type.
 *
 * In summary, libfprint represents fingerprints in several internal structures
 * and each representation will offer you a way of determining the
 * \ref driver_id "driver ID" and \ref devtype "devtype" of the print in
 * question. Prints are only compatible if the driver ID <b>and</b> devtypes
 * match. libfprint does offer you some "is this print compatible?" helper
 * functions, so you don't have to worry about these details too much.
 *
146
 * \section sync Synchronity/asynchronity
Daniel Drake's avatar
Daniel Drake committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
 *
 * Currently, all data acquisition operations are synchronous and can
 * potentially block for extended periods of time. For example, the enroll
 * function will block for an unpredictable amount of time until the user
 * scans their finger.
 *
 * Alternative asynchronous/non-blocking functionality will be offered in
 * future but has not been implemented yet.
 *
 * \section getting_started Getting started
 *
 * libfprint includes several simple functional examples under the examples/
 * directory in the libfprint source distribution. Those are good starting
 * points.
 *
 * Usually the first thing you want to do is determine which fingerprint
 * devices are present. This is done through \ref dscv_dev "device discovery".
 *
 * Once you have found a device you would like to operate, you should open it.
 * Refer to \ref dev "device operations". This section also details enrollment,
 * image capture, and verification.
 *
 *
 * That should be enough to get you started, but do remember there are
 * documentation pages on other aspects of libfprint's API (see the modules
 * page).
 */

/** @defgroup core Core library operations */

/**
 * @defgroup dev Device operations
 * In order to interact with fingerprint scanners, your software will
 * interface primarily with libfprint's representation of devices, detailed
 * on this page.
 *
 * \section enrolling Enrolling
 * Enrolling is represented within libfprint as a multi-stage process. This
 * slightly complicates things for application developers, but is required
 * for a smooth process.
 *
 * Some devices require the user to scan their finger multiple times in
 * order to complete the enrollment process. libfprint must return control
 * to your application inbetween each scan in order for your application to
 * instruct the user to swipe their finger again. Each scan is referred to
 * as a stage, so a device that requires 3 scans for enrollment corresponds
 * to you running 3 enrollment stages using libfprint.
 *
 * The fp_dev_get_nr_enroll_stages() function can be used to find out how
 * many enroll stages are needed.
 *
 * In order to complete an enroll stage, you call an enroll function such
 * as fp_enroll_finger(). The return of this function does not necessarily
 * indicate that a stage has completed though, as the user may not have
 * produced a good enough scan. Each stage may have to be retried several
 * times.
 *
 * The exact semantics of the enroll functions are described in the
 * fp_enroll_finger() documentation. You should pay careful attention to the
 * details.
 *
 * \section imaging Imaging
 * libfprint provides you with some ways to retrieve images of scanned
 * fingers, such as the fp_dev_img_capture() function, or some enroll/verify
 * function variants which provide images. You may wish to do something with
 * such images in your application.
 *
 * However, you must be aware that not all hardware supported by libfprint
 * operates like this. Most hardware does operate simply by sending
 * fingerprint images to the host computer for further processing, but some
 * devices do all fingerprint processing in hardware and do not present images
 * to the host computer.
 *
 * You can use fp_dev_supports_imaging() to see if image capture is possible
 * on a particular device. Your application must be able to cope with the
 * fact that libfprint does support regular operations (e.g. enrolling and
 * verification) on some devices which do not provide images.
 *
 * \section devtype Devtypes
 * Internally, the \ref drv "driver" behind a device assigns a 32-bit
 * <em>devtype</em> identifier to the device. This cannot be used as a unique
 * ID for a specific device as many devices under the same range may share
 * the same devtype. The devtype may even be 0 in all cases.
 *
 * The only reason you may be interested in retrieving the devtype for a
 * device is for the purpose of checking if some print data is compatible
 * with a device. libfprint uses the devtype as one way of checking that the
 * print you are verifying is compatible with the device in question - the
 * devtypes must be equal. This effectively allows drivers to support more
 * than one type of device where the data from each one is not compatible with
 * the other. Note that libfprint does provide you with helper functions to
 * determine whether a print is compatible with a device, so under most
 * circumstances, you don't have to worry about devtypes at all.
 */

/** @defgroup dscv_dev Device discovery
 * These functions allow you to scan the system for supported fingerprint
 * scanning hardware. This is your starting point when integrating libfprint
 * into your software.
 *
 * When you've identified a discovered device that you would like to control,
 * you can open it with fp_dev_open(). Note that discovered devices may no
 * longer be available at the time when you want to open them, for example
 * the user may have unplugged the device.
 */

/** @defgroup drv Driver operations
 * Internally, libfprint is abstracted into various drivers to communicate
 * with the different types of supported fingerprint readers. libfprint works
 * hard so that you don't have to care about these internal abstractions,
 * however there are some situations where you may be interested in a little
 * behind-the-scenes driver info.
 *
 * You can obtain the driver for a device using fp_dev_get_driver(), which
 * you can pass to the functions documented on this page.
 *
 * \section driver_id Driver IDs
 * Each driver is assigned a unique ID by the project maintainer. These
 * assignments are
 * <a href="http://www.reactivated.net/fprint/Driver_ID_assignments">
 * documented on the wiki</a> and will never change.
 *
 * The only reason you may be interested in retrieving the driver ID for a
 * driver is for the purpose of checking if some print data is compatible
 * with a device. libfprint uses the driver ID as one way of checking that
 * the print you are trying to verify is compatible with the device in
 * question - it ensures that enrollment data from one driver is never fed to
 * another. Note that libfprint does provide you with helper functions to
 * determine whether a print is compatible with a device, so under most
 * circumstances, you don't have to worry about driver IDs at all.
 */

279 280
static GSList *registered_drivers = NULL;
static GSList *opened_devices = NULL;
281

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
void fpi_log(enum fpi_log_level level, const char *component,
	const char *function, const char *format, ...)
{
	va_list args;
	FILE *stream = stdout;
	const char *prefix;

	switch (level) {
	case LOG_LEVEL_INFO:
		prefix = "info";
		break;
	case LOG_LEVEL_WARNING:
		stream = stderr;
		prefix = "warning";
		break;
	case LOG_LEVEL_ERROR:
		stream = stderr;
		prefix = "error";
		break;
	case LOG_LEVEL_DEBUG:
		stream = stderr;
		prefix = "debug";
		break;
Daniel Drake's avatar
Daniel Drake committed
305 306 307 308
	default:
		stream = stderr;
		prefix = "unknown";
		break;
309 310 311 312 313 314 315 316 317 318 319 320
	}

	fprintf(stream, "%s:%s [%s] ", component ? component : "fp", prefix,
		function);

	va_start (args, format);
	vfprintf(stream, format, args);
	va_end (args);

	fprintf(stream, "\n");
}

321
static void register_driver(struct fp_driver *drv)
322
{
323 324 325 326
	if (drv->id == 0) {
		fp_err("not registering driver %s: driver ID is 0");
		return;
	}
327
	registered_drivers = g_slist_prepend(registered_drivers, (gpointer) drv);
328
	fp_dbg("registered driver %s", drv->name);
329 330
}

331
static struct fp_driver * const primitive_drivers[] = {
332 333 334
	&upekts_driver,
};

335 336
static struct fp_img_driver * const img_drivers[] = {
	&uru4000_driver,
Daniel Drake's avatar
Daniel Drake committed
337
	&aes2501_driver,
338
	&aes4000_driver,
339 340
};

341 342
static void register_drivers(void)
{
Daniel Drake's avatar
Daniel Drake committed
343
	unsigned int i;
344

345 346 347 348 349 350 351 352
	for (i = 0; i < ARRAY_SIZE(primitive_drivers); i++)
		register_driver(primitive_drivers[i]);

	for (i = 0; i < ARRAY_SIZE(img_drivers); i++) {
		struct fp_img_driver *imgdriver = img_drivers[i];
		fpi_img_driver_setup(imgdriver);
		register_driver(&imgdriver->driver);
	}
353 354
}

355
static struct fp_driver *find_supporting_driver(struct usb_device *udev,
Daniel Drake's avatar
Daniel Drake committed
356
	const struct usb_id **usb_id)
357
{
358
	GSList *elem = registered_drivers;
359 360
	
	do {
361
		struct fp_driver *drv = elem->data;
362 363 364 365
		const struct usb_id *id;

		for (id = drv->id_table; id->vendor; id++)
			if (udev->descriptor.idVendor == id->vendor &&
366 367 368
					udev->descriptor.idProduct == id->product) {
				fp_dbg("driver %s supports USB device %04x:%04x",
					drv->name, id->vendor, id->product);
Daniel Drake's avatar
Daniel Drake committed
369
				*usb_id = id;
370
				return drv;
371
			}
372
	} while (elem = g_slist_next(elem));
373 374 375
	return NULL;
}

376 377
static struct fp_dscv_dev *discover_dev(struct usb_device *udev)
{
Daniel Drake's avatar
Daniel Drake committed
378
	const struct usb_id *usb_id;
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
	struct fp_driver *drv = find_supporting_driver(udev, &usb_id);
	struct fp_dscv_dev *ddev;
	uint32_t devtype = 0;

	if (!drv)
		return NULL;

	if (drv->discover) {
		int r = drv->discover(usb_id, &devtype);
		if (r < 0)
			fp_err("%s discover failed, code %d", drv->name, r);
		if (r <= 0)
			return NULL;
	}

	ddev = g_malloc0(sizeof(*ddev));
	ddev->drv = drv;
	ddev->udev = udev;
	ddev->driver_data = usb_id->driver_data;
	ddev->devtype = devtype;
	return ddev;
}

Daniel Drake's avatar
Daniel Drake committed
402 403 404 405 406 407
/** \ingroup dscv_dev
 * Scans the system and returns a list of discovered devices. This is your
 * entry point into finding a fingerprint reader to operate.
 * \returns a NULL-terminated list of discovered devices. Must be freed with
 * fp_dscv_devs_free() after use.
 */
408 409
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
{
410
	GSList *tmplist = NULL;
411 412 413 414 415 416 417 418 419 420 421 422
	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
423
	 * discovered devices in a GSList.
424 425 426 427 428
	 *
	 * 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) {
429 430
			struct fp_dscv_dev *ddev = discover_dev(udev);
			if (!ddev)
431
				continue;
432
			tmplist = g_slist_prepend(tmplist, (gpointer) ddev);
433 434 435
			dscv_count++;
		}

436
	/* Convert our temporary GSList into a standard NULL-terminated pointer
437 438 439
	 * array. */
	list = g_malloc(sizeof(*list) * (dscv_count + 1));
	if (dscv_count > 0) {
440
		GSList *elem = tmplist;
441 442 443
		int i = 0;
		do {
			list[i++] = elem->data;
444
		} while (elem = g_slist_next(elem));
445 446 447
	}
	list[dscv_count] = NULL; /* NULL-terminate */

448
	g_slist_free(tmplist);
449 450 451
	return list;
}

Daniel Drake's avatar
Daniel Drake committed
452 453 454 455
/** \ingroup dscv_dev
 * Free a list of discovered devices. This function destroys the list and all
 * discovered devices that it included, so make sure you have opened your
 * discovered device <b>before</b> freeing the list.
Daniel Drake's avatar
Daniel Drake committed
456 457
 * \param devs the list of discovered devices. If NULL, function simply
 * returns.
Daniel Drake's avatar
Daniel Drake committed
458
 */
459 460 461 462 463 464 465 466 467 468 469
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);
}

Daniel Drake's avatar
Daniel Drake committed
470 471 472 473 474
/** \ingroup dscv_dev
 * Gets the \ref drv "driver" for a discovered device.
 * \param dev the discovered device
 * \returns the driver backing the device
 */
475
API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
476 477 478 479
{
	return dev->drv;
}

Daniel Drake's avatar
Daniel Drake committed
480 481 482 483 484
/** \ingroup dscv_dev
 * Gets the \ref devtype "devtype" for a discovered device.
 * \param dev the discovered device
 * \returns the devtype of the device
 */
485 486 487 488 489
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
{
	return dev->devtype;
}

Daniel Drake's avatar
Daniel Drake committed
490 491 492 493 494 495 496 497 498 499 500 501 502
enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv)
{
	switch (drv->type) {
	case DRIVER_PRIMITIVE:
		return PRINT_DATA_RAW;
	case DRIVER_IMAGING:
		return PRINT_DATA_NBIS_MINUTIAE;
	default:
		fp_err("unrecognised drv type %d", drv->type);
		return PRINT_DATA_RAW;
	}
}

Daniel Drake's avatar
Daniel Drake committed
503 504 505 506 507 508 509
/** \ingroup dscv_dev
 * Determines if a specific \ref print_data "stored print" appears to be
 * compatible with a discovered device.
 * \param dev the discovered device
 * \param data the print for compatibility checking
 * \returns 1 if the print is compatible with the device, 0 otherwise
 */
Daniel Drake's avatar
Daniel Drake committed
510 511 512 513 514 515 516 517
API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
	struct fp_print_data *data)
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype,
		fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
		data->type);
}

Daniel Drake's avatar
Daniel Drake committed
518 519 520 521 522 523 524
/** \ingroup dscv_dev
 * Determines if a specific \ref dscv_print "discovered print" appears to be
 * compatible with a discovered device.
 * \param dev the discovered device
 * \param data the discovered print for compatibility checking
 * \returns 1 if the print is compatible with the device, 0 otherwise
 */
Daniel Drake's avatar
Daniel Drake committed
525 526 527 528 529 530 531
API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev,
	struct fp_dscv_print *data)
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0,
		data->driver_id, data->devtype, 0);
}

Daniel Drake's avatar
Daniel Drake committed
532 533 534 535 536 537 538 539
/** \ingroup dscv_dev
 * Searches a list of discovered devices for a device that appears to be
 * compatible with a \ref print_data "stored print".
 * \param devs a list of discovered devices
 * \param data the print under inspection
 * \returns the first discovered device that appears to support the print, or
 * NULL if no apparently compatible devices could be found
 */
Daniel Drake's avatar
Daniel Drake committed
540 541 542 543 544 545 546 547 548 549 550 551
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs,
	struct fp_print_data *data)
{
	struct fp_dscv_dev *ddev;
	int i;

	for (i = 0; ddev = devs[i]; i++)
		if (fp_dscv_dev_supports_print_data(ddev, data))
			return ddev;
	return NULL;
}

Daniel Drake's avatar
Daniel Drake committed
552 553 554 555 556 557 558 559
/** \ingroup dscv_dev
 * Searches a list of discovered devices for a device that appears to be
 * compatible with a \ref dscv_print "discovered print".
 * \param devs a list of discovered devices
 * \param print the print under inspection
 * \returns the first discovered device that appears to support the print, or
 * NULL if no apparently compatible devices could be found
 */
Daniel Drake's avatar
Daniel Drake committed
560 561 562 563 564 565 566 567 568 569 570 571
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs,
	struct fp_dscv_print *print)
{
	struct fp_dscv_dev *ddev;
	int i;

	for (i = 0; ddev = devs[i]; i++)
		if (fp_dscv_dev_supports_dscv_print(ddev, print))
			return ddev;
	return NULL;
}

Daniel Drake's avatar
Daniel Drake committed
572 573 574 575 576 577 578
/** \ingroup dev
 * Opens and initialises a device. This is the function you call in order
 * to convert a \ref dscv_dev "discovered device" into an actual device handle
 * that you can perform operations with.
 * \param ddev the discovered device to open
 * \returns the opened device handle, or NULL on error
 */
579 580 581
API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev)
{
	struct fp_dev *dev;
582
	struct fp_driver *drv = ddev->drv;
583 584 585
	int r;

	usb_dev_handle *udevh = usb_open(ddev->udev);
586 587
	if (!udevh) {
		fp_err("usb_open failed");
588
		return NULL;
589
	}
590

591 592 593
	dev = g_malloc0(sizeof(*dev));
	dev->drv = drv;
	dev->udev = udevh;
Daniel Drake's avatar
Daniel Drake committed
594
	dev->__enroll_stage = -1;
595 596

	if (drv->init) {
597
		r = drv->init(dev, ddev->driver_data);
598
		if (r) {
599
			fp_err("device initialisation failed, driver=%s", drv->name);
600 601 602 603 604 605
			usb_close(udevh);
			g_free(dev);
			return NULL;
		}
	}

606
	fp_dbg("");
607
	opened_devices = g_slist_prepend(opened_devices, (gpointer) dev);
608 609 610
	return dev;
}

611 612 613 614 615 616 617 618 619
/* performs close operation without modifying opened_devices list */
static void do_close(struct fp_dev *dev)
{
	if (dev->drv->exit)
		dev->drv->exit(dev);
	usb_close(dev->udev);
	g_free(dev);
}

Daniel Drake's avatar
Daniel Drake committed
620 621 622
/** \ingroup dev
 * Close a device. You must call this function when you are finished using
 * a fingerprint device.
Daniel Drake's avatar
Daniel Drake committed
623
 * \param dev the device to close. If NULL, function simply returns.
Daniel Drake's avatar
Daniel Drake committed
624
 */
625 626
API_EXPORTED void fp_dev_close(struct fp_dev *dev)
{
Daniel Drake's avatar
Daniel Drake committed
627 628 629
	if (!dev)
		return;

630
	fp_dbg("");
631 632 633 634 635

	if (g_slist_index(opened_devices, (gconstpointer) dev) == -1)
		fp_err("device %p not in opened list!", dev);
	opened_devices = g_slist_remove(opened_devices, (gconstpointer) dev);
	do_close(dev);
636 637
}

Daniel Drake's avatar
Daniel Drake committed
638 639 640 641 642
/** \ingroup dev
 * Get the \ref drv "driver" for a fingerprint device.
 * \param dev the device
 * \returns the driver controlling the device
 */
643
API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
644 645 646 647
{
	return dev->drv;
}

Daniel Drake's avatar
Daniel Drake committed
648 649 650 651 652 653
/** \ingroup dev
 * Gets the number of \ref enrolling "enroll stages" required to enroll a
 * fingerprint with the device.
 * \param dev the device
 * \returns the number of enroll stages
 */
Daniel Drake's avatar
Daniel Drake committed
654 655 656 657 658
API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
{
	return dev->nr_enroll_stages;
}

Daniel Drake's avatar
Daniel Drake committed
659 660 661 662 663
/** \ingroup dev
 * Gets the \ref devtype "devtype" for a device.
 * \param dev the device
 * \returns the devtype
 */
664 665 666 667 668
API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
{
	return dev->devtype;
}

Daniel Drake's avatar
Daniel Drake committed
669 670 671 672 673 674
/** \ingroup dev
 * Determines if a stored print is compatible with a certain device.
 * \param dev the device
 * \param data the stored print
 * \returns 1 if the print is compatible with the device, 0 if not
 */
Daniel Drake's avatar
Daniel Drake committed
675 676 677 678 679 680 681 682
API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev,
	struct fp_print_data *data)
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype,
		fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype,
		data->type);
}

Daniel Drake's avatar
Daniel Drake committed
683 684 685 686 687 688 689
/** \ingroup dev
 * Determines if a \ref dscv_print "discovered print" appears to be compatible
 * with a certain device.
 * \param dev the device
 * \param data the discovered print
 * \returns 1 if the print is compatible with the device, 0 if not
 */
Daniel Drake's avatar
Daniel Drake committed
690 691 692 693 694 695 696
API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
	struct fp_dscv_print *data)
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype,
		0, data->driver_id, data->devtype, 0);
}

Daniel Drake's avatar
Daniel Drake committed
697 698 699 700 701
/** \ingroup drv
 * Retrieves the name of the driver. For example: "upekts"
 * \param drv the driver
 * \returns the driver name. Must not be modified or freed.
 */
702
API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
703 704 705 706
{
	return drv->name;
}

Daniel Drake's avatar
Daniel Drake committed
707 708 709 710 711
/** \ingroup drv
 * Retrieves a descriptive name of the driver. For example: "UPEK TouchStrip"
 * \param drv the driver
 * \returns the descriptive name. Must not be modified or freed.
 */
712
API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
713 714 715 716
{
	return drv->full_name;
}

Daniel Drake's avatar
Daniel Drake committed
717 718 719 720 721
/** \ingroup drv
 * Retrieves the driver ID code for a driver.
 * \param drv the driver
 * \returns the driver ID
 */
722 723 724 725 726
API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
{
	return drv->id;
}

727
static struct fp_img_dev *dev_to_img_dev(struct fp_dev *dev)
728 729 730 731 732 733
{
	if (dev->drv->type != DRIVER_IMAGING)
		return NULL;
	return dev->priv;
}

Daniel Drake's avatar
Daniel Drake committed
734 735 736 737 738 739 740 741 742 743
/** \ingroup dev
 * Determines if a device has imaging capabilities. If a device has imaging
 * capabilities you are able to perform imaging operations such as retrieving
 * scan images using fp_dev_img_capture(). However, not all devices are
 * imaging devices - some do all processing in hardware. This function will
 * indicate which class a device in question falls into.
 * \param dev the fingerprint device
 * \returns 1 if the device is an imaging device, 0 if the device does not
 * provide images to the host computer
 */
744 745 746 747 748
API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
{
	return dev->drv->type == DRIVER_IMAGING;
}

Daniel Drake's avatar
Daniel Drake committed
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
/** \ingroup dev
 * Captures an \ref img "image" from a device. The returned image is the raw
 * image provided by the device, you may wish to \ref img_std "standardize" it.
 *
 * If set, the <tt>unconditional</tt> flag indicates that the device should
 * capture an image unconditionally, regardless of whether a finger is there
 * or not. If unset, this function will block until a finger is detected on
 * the sensor.
 *
 * \param dev the device
 * \param unconditional whether to unconditionally capture an image, or to only capture when a finger is detected
 * \param image a location to return the captured image. Must be freed with
 * fp_img_free() after use.
 * \return 0 on success, non-zero on error. -ENOTSUP indicates that either the
 * unconditional flag was set but the device does not support this, or that the
 * device does not support imaging.
 * \sa fp_dev_supports_imaging()
 */
767 768 769 770 771 772 773 774 775 776 777 778
API_EXPORTED int fp_dev_img_capture(struct fp_dev *dev, int unconditional,
	struct fp_img **image)
{
	struct fp_img_dev *imgdev = dev_to_img_dev(dev);
	if (!imgdev) {
		fp_dbg("image capture on non-imaging device");
		return -ENOTSUP;
	}

	return fpi_imgdev_capture(imgdev, unconditional, image);
}

Daniel Drake's avatar
Daniel Drake committed
779 780 781 782 783 784 785 786 787
/** \ingroup dev
 * Gets the expected width of images that will be captured from the device.
 * This function will return -1 for devices that are not
 * \ref imaging "imaging devices". If the width of images from this device
 * can vary, 0 will be returned.
 * \param dev the device
 * \returns the expected image width, or 0 for variable, or -1 for non-imaging
 * devices.
 */
788 789 790 791 792 793 794 795 796 797 798
API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
{
	struct fp_img_dev *imgdev = dev_to_img_dev(dev);
	if (!imgdev) {
		fp_dbg("get image width for non-imaging device");
		return -1;
	}

	return fpi_imgdev_get_img_width(imgdev);
}

Daniel Drake's avatar
Daniel Drake committed
799 800 801 802 803 804 805 806 807
/** \ingroup dev
 * Gets the expected height of images that will be captured from the device.
 * This function will return -1 for devices that are not
 * \ref imaging "imaging devices". If the height of images from this device
 * can vary, 0 will be returned.
 * \param dev the device
 * \returns the expected image height, or 0 for variable, or -1 for non-imaging
 * devices.
 */
808 809 810 811 812 813 814 815 816 817 818
API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev)
{
	struct fp_img_dev *imgdev = dev_to_img_dev(dev);
	if (!imgdev) {
		fp_dbg("get image height for non-imaging device");
		return -1;
	}

	return fpi_imgdev_get_img_height(imgdev);
}

Daniel Drake's avatar
Daniel Drake committed
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
/** \ingroup dev
 * Performs an enroll stage. See \ref enrolling for an explanation of enroll
 * stages.
 *
 * If no enrollment is in process, this kicks of the process and runs the
 * first stage. If an enrollment is already in progress, calling this
 * function runs the next stage, which may well be the last.
 *
 * A negative error code may be returned from any stage. When this occurs,
 * further calls to the enroll function will start a new enrollment process,
 * i.e. a negative error code indicates that the enrollment process has been
 * aborted. These error codes only ever indicate unexpected internal errors
 * or I/O problems.
 *
 * The RETRY codes from #fp_enroll_result may be returned from any enroll
 * stage. These codes indicate that the scan was not succesful in that the
 * user did not position their finger correctly or similar. When a RETRY code
 * is returned, the enrollment stage is <b>not</b> advanced, so the next call
 * into this function will retry the current stage again. The current stage may
 * need to be retried several times.
 *
 * The fp_enroll_result#FP_ENROLL_FAIL code may be returned from any enroll
 * stage. This code indicates that even though the scans themselves have been
 * acceptable, data processing applied to these scans produces incomprehensible
 * results. In other words, the user may have been scanning a different finger
 * for each stage or something like that. Like negative error codes, this
 * return code indicates that the enrollment process has been aborted.
 *
 * The fp_enroll_result#FP_ENROLL_PASS code will only ever be returned for
 * non-final stages. This return code indicates that the scan was acceptable
 * and the next call into this function will advance onto the next enroll
 * stage.
 *
 * The fp_enroll_result#FP_ENROLL_COMPLETE code will only ever be returned
 * from the final enroll stage. It indicates that enrollment completed
 * successfully, and that print_data has been assigned to point to the
 * resultant enrollment data. The print_data parameter will not be modified
 * during any other enrollment stages, hence it is actually legal to pass NULL
 * as this argument for all but the final stage.
858 859 860 861 862
 * 
 * If the device is an imaging device, it can also return the image from
 * the scan, even when the enroll fails with a RETRY or FAIL code. It is legal
 * to call this function even on non-imaging devices, just don't expect them to
 * provide images.
Daniel Drake's avatar
Daniel Drake committed
863 864 865 866
 *
 * \param dev the device
 * \param print_data a location to return the resultant enrollment data from
 * the final stage. Must be freed with fp_print_data_free() after use.
867 868 869 870
 * \param img location to store the scan image. accepts NULL for no image
 * storage. If an image is returned, it must be freed with fp_img_free() after
 * use.
 * \return negative code on error, otherwise a code from #fp_enroll_result
Daniel Drake's avatar
Daniel Drake committed
871
 */
872 873
API_EXPORTED int fp_enroll_finger_img(struct fp_dev *dev,
	struct fp_print_data **print_data, struct fp_img **img)
Daniel Drake's avatar
Daniel Drake committed
874
{
875
	struct fp_driver *drv = dev->drv;
876
	struct fp_img *_img = NULL;
877
	int ret;
Daniel Drake's avatar
Daniel Drake committed
878 879 880
	int stage = dev->__enroll_stage;
	gboolean initial = FALSE;

881 882
	if (!dev->nr_enroll_stages || !drv->enroll) {
		fp_err("driver %s has 0 enroll stages or no enroll func",
883 884
			drv->name);
		return -ENOTSUP;
885
	}
Daniel Drake's avatar
Daniel Drake committed
886

Daniel Drake's avatar
Daniel Drake committed
887 888 889 890 891 892 893
	if (stage == -1) {
		initial = TRUE;
		dev->__enroll_stage = ++stage;
	}

	if (stage >= dev->nr_enroll_stages) {
		fp_err("exceeding number of enroll stages for device claimed by "
894 895 896
			"driver %s (%d stages)", drv->name, dev->nr_enroll_stages);
		dev->__enroll_stage = -1;
		return -EINVAL;
Daniel Drake's avatar
Daniel Drake committed
897 898 899 900
	}
	fp_dbg("%s will handle enroll stage %d/%d%s", drv->name, stage,
		dev->nr_enroll_stages - 1, initial ? " (initial)" : "");

901
	ret = drv->enroll(dev, initial, stage, print_data, &_img);
902 903 904 905 906
	if (ret < 0) {
		fp_err("enroll failed with code %d", ret);
		dev->__enroll_stage = -1;
		return ret;
	}
907 908 909 910 911 912

	if (img)
		*img = _img;
	else
		fp_img_free(_img);

Daniel Drake's avatar
Daniel Drake committed
913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930
	switch (ret) {
	case FP_ENROLL_PASS:
		fp_dbg("enroll stage passed");
		dev->__enroll_stage = stage + 1;
		break;
	case FP_ENROLL_COMPLETE:
		fp_dbg("enroll complete");
		dev->__enroll_stage = -1;
		break;
	case FP_ENROLL_RETRY:
		fp_dbg("enroll should retry");
		break;
	case FP_ENROLL_RETRY_TOO_SHORT:
		fp_dbg("swipe was too short, enroll should retry");
		break;
	case FP_ENROLL_RETRY_CENTER_FINGER:
		fp_dbg("finger was not centered, enroll should retry");
		break;
931 932 933
	case FP_ENROLL_RETRY_REMOVE_FINGER:
		fp_dbg("scan failed, remove finger and retry");
		break;
Daniel Drake's avatar
Daniel Drake committed
934 935 936 937 938 939 940
	case FP_ENROLL_FAIL:
		fp_err("enroll failed");
		dev->__enroll_stage = -1;
		break;
	default:
		fp_err("unrecognised return code %d", ret);
		dev->__enroll_stage = -1;
941
		return -EINVAL;
Daniel Drake's avatar
Daniel Drake committed
942 943
	}
	return ret;
Daniel Drake's avatar
Daniel Drake committed
944 945
}

Daniel Drake's avatar
Daniel Drake committed
946 947
/** \ingroup dev
 * Performs a new scan and verify it against a previously enrolled print.
948 949 950 951 952
 * If the device is an imaging device, it can also return the image from
 * the scan, even when the verify fails with a RETRY code. It is legal to
 * call this function even on non-imaging devices, just don't expect them to
 * provide images.
 *
Daniel Drake's avatar
Daniel Drake committed
953 954 955
 * \param dev the device to perform the scan.
 * \param enrolled_print the print to verify against. Must have been previously
 * enrolled with a device compatible to the device selected to perform the scan.
956 957 958
 * \param img location to store the scan image. accepts NULL for no image
 * storage. If an image is returned, it must be freed with fp_img_free() after
 * use.
Daniel Drake's avatar
Daniel Drake committed
959 960
 * \return negative code on error, otherwise a code from #fp_verify_result
 */
961 962
API_EXPORTED int fp_verify_finger_img(struct fp_dev *dev,
	struct fp_print_data *enrolled_print, struct fp_img **img)
963
{
964
	struct fp_driver *drv = dev->drv;
965
	struct fp_img *_img = NULL;
966 967 968 969 970 971 972 973 974 975 976 977
	int r;

	if (!enrolled_print) {
		fp_err("no print given");
		return -EINVAL;
	}

	if (!drv->verify) {
		fp_err("driver %s has no verify func", drv->name);
		return -EINVAL;
	}

Daniel Drake's avatar
Daniel Drake committed
978
	if (!fp_dev_supports_print_data(dev, enrolled_print)) {
979 980 981 982 983
		fp_err("print is not compatible with device");
		return -EINVAL;
	}

	fp_dbg("to be handled by %s", drv->name);
984
	r = drv->verify(dev, enrolled_print, &_img);
Daniel Drake's avatar
Daniel Drake committed
985
	if (r < 0) {
986
		fp_dbg("verify error %d", r);
Daniel Drake's avatar
Daniel Drake committed
987 988 989
		return r;
	}

990 991 992 993 994
	if (img)
		*img = _img;
	else
		fp_img_free(_img);

Daniel Drake's avatar
Daniel Drake committed
995 996
	switch (r) {
	case FP_VERIFY_NO_MATCH:
997
		fp_dbg("result: no match");
Daniel Drake's avatar
Daniel Drake committed
998 999
		break;
	case FP_VERIFY_MATCH:
1000
		fp_dbg("result: match");
Daniel Drake's avatar
Daniel Drake committed
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
		break;
	case FP_VERIFY_RETRY:
		fp_dbg("verify should retry");
		break;
	case FP_VERIFY_RETRY_TOO_SHORT:
		fp_dbg("swipe was too short, verify should retry");
		break;
	case FP_VERIFY_RETRY_CENTER_FINGER:
		fp_dbg("finger was not centered, verify should retry");
		break;
	case FP_VERIFY_RETRY_REMOVE_FINGER:
		fp_dbg("scan failed, remove finger and retry");
		break;
	default:
		fp_err("unrecognised return code %d", r);
		return -EINVAL;
	}
1018 1019 1020 1021

	return r;
}

Daniel Drake's avatar
Daniel Drake committed
1022 1023 1024 1025 1026
/** \ingroup core
 * Initialise libfprint. This function must be called before you attempt to
 * use the library in any way.
 * \return 0 on success, non-zero on error.
 */
Daniel Drake's avatar
Daniel Drake committed
1027 1028
API_EXPORTED int fp_init(void)
{
1029
	fp_dbg("");
1030
	usb_init();
1031
	register_drivers();
Daniel Drake's avatar
Daniel Drake committed
1032 1033
	return 0;
}
1034

1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
/** \ingroup core
 * Deinitialise libfprint. This function should be called during your program
 * exit sequence. You must not use any libfprint functions after calling this
 * function, unless you call fp_init() again.
 */
API_EXPORTED void fp_exit(void)
{
	GSList *elem = opened_devices;
	fp_dbg("");

	if (elem != NULL) {
		do {
			fp_dbg("naughty app left a device open on exit!");
			do_close((struct fp_dev *) elem->data);
		} while (elem = g_slist_next(elem));
		g_slist_free(opened_devices);
		opened_devices = NULL;
	}

	fpi_data_exit();
	g_slist_free(registered_drivers);
	registered_drivers = NULL;
}