fpi-core.c 21.7 KB
Newer Older
Daniel Drake's avatar
Daniel Drake committed
1 2
/*
 * Core functions for libfprint
3
 * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
Daniel Drake's avatar
Daniel Drake committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * 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
#include <stdlib.h>
Daniel Drake's avatar
Daniel Drake committed
24

25
#include <glib.h>
26
#include <libusb.h>
27 28 29

#include "fp_internal.h"

Daniel Drake's avatar
Daniel Drake committed
30
libusb_context *fpi_usb_ctx = NULL;
31 32
GSList *opened_devices = NULL;

Daniel Drake's avatar
Daniel Drake committed
33
/**
34 35
 * SECTION:discovery
 * @title: Device discovery
36
 * @short_description: Device discovery functions
37 38 39 40 41 42 43 44 45
 *
 * 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.
Daniel Drake's avatar
Daniel Drake committed
46 47
 */

48 49 50
/**
 * SECTION:drv
 * @title: Driver operations
51
 * @short_description: Driver operation functions
52 53 54 55 56 57 58 59 60 61
 *
 * 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.
 */
Daniel Drake's avatar
Daniel Drake committed
62 63

/**
64 65
 * SECTION:dev
 * @title: Devices operations
66
 * @short_description: Device operation functions
67
 *
Daniel Drake's avatar
Daniel Drake committed
68 69 70 71
 * In order to interact with fingerprint scanners, your software will
 * interface primarily with libfprint's representation of devices, detailed
 * on this page.
 *
72 73
 * # Enrolling # {#enrolling}
 *
Daniel Drake's avatar
Daniel Drake committed
74 75 76 77 78 79
 * 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
80
 * to your application in-between each scan in order for your application to
Daniel Drake's avatar
Daniel Drake committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
 * 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.
 *
98 99
 * # Imaging # {#imaging}
 *
Daniel Drake's avatar
Daniel Drake committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
 * 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.
 */

117 118 119
/**
 * SECTION:fpi-core
 * @title: Driver structures
120
 * @short_description: Driver structures
121 122 123 124 125 126 127 128 129
 *
 * Driver structures need to be defined inside each driver in
 * order for the core library to know what function to call, and the capabilities
 * of the driver and the devices it supports.
 */

/**
 * SECTION:fpi-core-img
 * @title: Image driver structures
130
 * @short_description: Image driver structures
131 132 133 134 135 136 137
 *
 * Image driver structures need to be defined inside each image driver in
 * order for the core library to know what function to call, and the capabilities
 * of the driver and the devices it supports. Its structure is based off the
 * #fp_driver struct.
 */

138
static GSList *registered_drivers = NULL;
139

140
static void register_driver(struct fp_driver *drv)
141
{
142
	if (drv->id == 0) {
143
		fp_err("not registering driver %s: driver ID is 0", drv->name);
144 145
		return;
	}
146
	registered_drivers = g_slist_prepend(registered_drivers, (gpointer) drv);
147
	fp_dbg("registered driver %s", drv->name);
148 149
}

150
#include "drivers_arrays.h"
151

152 153
static void register_drivers(void)
{
Daniel Drake's avatar
Daniel Drake committed
154
	unsigned int i;
155

Daniel Drake's avatar
Daniel Drake committed
156
	for (i = 0; i < G_N_ELEMENTS(primitive_drivers); i++)
157 158
		register_driver(primitive_drivers[i]);

Daniel Drake's avatar
Daniel Drake committed
159
	for (i = 0; i < G_N_ELEMENTS(img_drivers); i++) {
160 161 162 163
		struct fp_img_driver *imgdriver = img_drivers[i];
		fpi_img_driver_setup(imgdriver);
		register_driver(&imgdriver->driver);
	}
164 165
}

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
API_EXPORTED struct fp_driver **fprint_get_drivers (void)
{
	GPtrArray *array;
	unsigned int i;

	array = g_ptr_array_new ();
	for (i = 0; i < G_N_ELEMENTS(primitive_drivers); i++)
		g_ptr_array_add (array, primitive_drivers[i]);

	for (i = 0; i < G_N_ELEMENTS(img_drivers); i++)
		g_ptr_array_add (array, &(img_drivers[i]->driver));

	/* Add a null item terminating the array */
	g_ptr_array_add (array, NULL);

	return (struct fp_driver **) g_ptr_array_free (array, FALSE);
}

184
static struct fp_driver *find_supporting_driver(libusb_device *udev,
185
	const struct usb_id **usb_id, uint32_t *devtype)
186
{
187
	int ret;
188
	GSList *elem = registered_drivers;
189 190
	struct libusb_device_descriptor dsc;

191 192 193 194 195
	const struct usb_id *best_usb_id;
	struct fp_driver *best_drv;
	uint32_t best_devtype;
	int drv_score = 0;

196 197 198 199 200
	ret = libusb_get_device_descriptor(udev, &dsc);
	if (ret < 0) {
		fp_err("Failed to get device descriptor");
		return NULL;
	}
201 202 203 204

	best_drv = NULL;
	best_devtype = 0;

205
	do {
206
		struct fp_driver *drv = elem->data;
207
		uint32_t type = 0;
208 209
		const struct usb_id *id;

210
		for (id = drv->id_table; id->vendor; id++) {
211
			if (dsc.idVendor == id->vendor && dsc.idProduct == id->product) {
212 213 214 215 216 217 218 219 220 221 222 223 224 225
				if (drv->discover) {
					int r = drv->discover(&dsc, &type);
					if (r < 0)
						fp_err("%s discover failed, code %d", drv->name, r);
					if (r <= 0)
						continue;
					/* Has a discover function, and matched our device */
					drv_score = 100;
				} else {
					/* Already got a driver as good */
					if (drv_score >= 50)
						continue;
					drv_score = 50;
				}
226 227
				fp_dbg("driver %s supports USB device %04x:%04x",
					drv->name, id->vendor, id->product);
228 229 230 231 232 233 234
				best_usb_id = id;
				best_drv = drv;
				best_devtype = type;

				/* We found the best possible driver */
				if (drv_score == 100)
					break;
235
			}
236
		}
Daniel Drake's avatar
Daniel Drake committed
237
	} while ((elem = g_slist_next(elem)));
238

239 240 241 242 243 244
	if (best_drv != NULL) {
		fp_dbg("selected driver %s supports USB device %04x:%04x",
		       best_drv->name, dsc.idVendor, dsc.idProduct);
		*devtype = best_devtype;
		*usb_id = best_usb_id;
	}
245 246

	return best_drv;
247 248
}

249
static struct fp_dscv_dev *discover_dev(libusb_device *udev)
250
{
Daniel Drake's avatar
Daniel Drake committed
251
	const struct usb_id *usb_id;
252
	struct fp_driver *drv;
253
	struct fp_dscv_dev *ddev;
254 255 256
	uint32_t devtype;

	drv = find_supporting_driver(udev, &usb_id, &devtype);
257 258 259 260 261 262 263 264 265 266 267 268

	if (!drv)
		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;
}

269 270 271
/**
 * fp_discover_devs:
 *
Daniel Drake's avatar
Daniel Drake committed
272
 * Scans the system and returns a list of discovered devices. This is your
273 274 275
 * entry point into finding a fingerprint reader to operate. Note that %NULL
 * is only returned on error. When there are no supported readers available,
 * an empty list is returned instead.
276
 *
277 278
 * Returns: a nul-terminated list of discovered devices or %NULL on error.
 * Must be freed with fp_dscv_devs_free() after use.
Daniel Drake's avatar
Daniel Drake committed
279
 */
280 281
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
{
282
	GPtrArray *tmparray;
283 284 285 286
	libusb_device *udev;
	libusb_device **devs;
	int r;
	int i = 0;
287

288
	g_return_val_if_fail (registered_drivers != NULL, NULL);
289

Daniel Drake's avatar
Daniel Drake committed
290
	r = libusb_get_device_list(fpi_usb_ctx, &devs);
291 292 293 294
	if (r < 0) {
		fp_err("couldn't enumerate USB devices, error %d", r);
		return NULL;
	}
295

296 297
	tmparray = g_ptr_array_new ();

298
	/* Check each device against each driver, temporarily storing successfully
299
	 * discovered devices in a GPtrArray. */
300 301 302 303
	while ((udev = devs[i++]) != NULL) {
		struct fp_dscv_dev *ddev = discover_dev(udev);
		if (!ddev)
			continue;
304 305 306
		/* discover_dev() doesn't hold a reference to the udev,
		 * so increase the reference for ddev to hold this ref */
		libusb_ref_device(udev);
307
		g_ptr_array_add (tmparray, (gpointer) ddev);
308
	}
309
	libusb_free_device_list(devs, 1);
310

311
	/* Convert our temporary array into a standard NULL-terminated pointer
312
	 * array. */
313 314
	g_ptr_array_add (tmparray, NULL);
	return (struct fp_dscv_dev **) g_ptr_array_free (tmparray, FALSE);
315 316
}

317 318 319 320 321
/**
 * fp_dscv_devs_free:
 * @devs: the list of discovered devices. If %NULL, function simply
 * returns.
 *
Daniel Drake's avatar
Daniel Drake committed
322 323
 * 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
324
 * discovered device <emphasis role="strong">before</emphasis> freeing the list.
Daniel Drake's avatar
Daniel Drake committed
325
 */
326 327 328 329 330 331
API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs)
{
	int i;
	if (!devs)
		return;

332 333
	for (i = 0; devs[i]; i++) {
		libusb_unref_device(devs[i]->udev);
334
		g_free(devs[i]);
335
	}
336 337 338
	g_free(devs);
}

339 340 341 342
/**
 * fp_dscv_dev_get_driver:
 * @dev: the discovered device
 *
343
 * Gets the #fp_driver for a discovered device.
344 345
 *
 * Returns: the driver backing the device
Daniel Drake's avatar
Daniel Drake committed
346
 */
347
API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev)
348 349 350 351
{
	return dev->drv;
}

352 353 354 355
/**
 * fp_dscv_dev_get_driver_id:
 * @dev: a discovered fingerprint device
 *
356 357 358 359
 * Returns a unique driver identifier for the underlying driver
 * for that device.
 *
 * Returns: the ID for #dev
360 361 362 363 364 365
 */
API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev)
{
	return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev));
}

366 367 368 369 370 371 372
/**
 * fp_dscv_dev_get_devtype:
 * @dev: the discovered device
 *
 * Gets the [devtype](advanced-topics.html#device-types) for a discovered device.
 *
 * Returns: the devtype of the device
Daniel Drake's avatar
Daniel Drake committed
373
 */
374 375 376 377 378
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
{
	return dev->devtype;
}

Daniel Drake's avatar
Daniel Drake committed
379 380 381 382 383 384 385 386 387 388 389 390 391
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;
	}
}

392 393 394 395 396
/**
 * fp_dscv_dev_supports_print_data:
 * @dev: the discovered device
 * @print: the print for compatibility checking
 *
397
 * Determines if a specific #fp_print_data stored print appears to be
Daniel Drake's avatar
Daniel Drake committed
398
 * compatible with a discovered device.
399 400
 *
 * Returns: 1 if the print is compatible with the device, 0 otherwise
Daniel Drake's avatar
Daniel Drake committed
401
 */
Daniel Drake's avatar
Daniel Drake committed
402
API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev,
403
	struct fp_print_data *print)
Daniel Drake's avatar
Daniel Drake committed
404 405
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype,
406 407
		fpi_driver_get_data_type(dev->drv), print->driver_id, print->devtype,
		print->type);
Daniel Drake's avatar
Daniel Drake committed
408 409
}

410 411 412 413 414
/**
 * fp_dscv_dev_supports_dscv_print:
 * @dev: the discovered device
 * @print: the discovered print for compatibility checking
 *
415
 * Determines if a specific #fp_dscv_print discovered print appears to be
Daniel Drake's avatar
Daniel Drake committed
416
 * compatible with a discovered device.
417 418
 *
 * Returns: 1 if the print is compatible with the device, 0 otherwise
419 420
 *
 * Deprecated: Do not use.
Daniel Drake's avatar
Daniel Drake committed
421
 */
Daniel Drake's avatar
Daniel Drake committed
422
API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev,
423
	struct fp_dscv_print *print)
Daniel Drake's avatar
Daniel Drake committed
424 425
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0,
426
		print->driver_id, print->devtype, 0);
Daniel Drake's avatar
Daniel Drake committed
427 428
}

429 430 431 432 433
/**
 * fp_dscv_dev_for_print_data:
 * @devs: a list of discovered devices
 * @print: the print under inspection
 *
Daniel Drake's avatar
Daniel Drake committed
434
 * Searches a list of discovered devices for a device that appears to be
435
 * compatible with a #fp_print_data stored print.
436 437 438
 *
 * Returns: the first discovered device that appears to support the print, or
 * %NULL if no apparently compatible devices could be found
439 440
 *
 * Deprecated: Do not use.
Daniel Drake's avatar
Daniel Drake committed
441
 */
Daniel Drake's avatar
Daniel Drake committed
442
API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs,
443
	struct fp_print_data *print)
Daniel Drake's avatar
Daniel Drake committed
444 445 446 447
{
	struct fp_dscv_dev *ddev;
	int i;

Daniel Drake's avatar
Daniel Drake committed
448
	for (i = 0; (ddev = devs[i]); i++)
449
		if (fp_dscv_dev_supports_print_data(ddev, print))
Daniel Drake's avatar
Daniel Drake committed
450 451 452 453
			return ddev;
	return NULL;
}

454 455 456 457 458
/**
 * fp_dscv_dev_for_dscv_print:
 * @devs: a list of discovered devices
 * @print: the print under inspection
 *
Daniel Drake's avatar
Daniel Drake committed
459
 * Searches a list of discovered devices for a device that appears to be
460
 * compatible with a #fp_dscv_print discovered print.
461 462 463
 *
 * Returns: the first discovered device that appears to support the print, or
 * %NULL if no apparently compatible devices could be found
464 465
 *
 * Deprecated: Do not use.
Daniel Drake's avatar
Daniel Drake committed
466
 */
Daniel Drake's avatar
Daniel Drake committed
467 468 469 470 471 472
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;

473 474 475
	for (i = 0; (ddev = devs[i]); i++) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
Daniel Drake's avatar
Daniel Drake committed
476 477
		if (fp_dscv_dev_supports_dscv_print(ddev, print))
			return ddev;
478 479
#pragma GCC diagnostic pop
	}
Daniel Drake's avatar
Daniel Drake committed
480 481 482
	return NULL;
}

483 484
/**
 * fp_dev_get_driver:
485
 * @dev: the struct #fp_dev device
486
 *
487
 * Get the #fp_driver for a fingerprint device.
488 489
 *
 * Returns: the driver controlling the device
Daniel Drake's avatar
Daniel Drake committed
490
 */
491
API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev)
492 493 494 495
{
	return dev->drv;
}

496 497
/**
 * fp_dev_get_nr_enroll_stages:
498
 * @dev: the struct #fp_dev device
499 500
 *
 * Gets the number of [enroll stages](intro.html#enrollment) required to enroll a
Daniel Drake's avatar
Daniel Drake committed
501
 * fingerprint with the device.
502 503
 *
 * Returns: the number of enroll stages
Daniel Drake's avatar
Daniel Drake committed
504
 */
Daniel Drake's avatar
Daniel Drake committed
505 506 507 508 509
API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev)
{
	return dev->nr_enroll_stages;
}

510 511
/**
 * fp_dev_get_devtype:
512
 * @dev: the struct #fp_dev device
513 514 515 516
 *
 * Gets the [devtype](advanced-topics.html#device-types) for a device.
 *
 * Returns: the devtype
Daniel Drake's avatar
Daniel Drake committed
517
 */
518 519 520 521 522
API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev)
{
	return dev->devtype;
}

523 524
/**
 * fp_dev_supports_print_data:
525
 * @dev: the struct #fp_dev device
526 527
 * @data: the stored print
 *
Daniel Drake's avatar
Daniel Drake committed
528
 * Determines if a stored print is compatible with a certain device.
529 530
 *
 * Returns: 1 if the print is compatible with the device, 0 if not
Daniel Drake's avatar
Daniel Drake committed
531
 */
Daniel Drake's avatar
Daniel Drake committed
532 533 534 535 536 537 538 539
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);
}

540 541
/**
 * fp_dev_supports_dscv_print:
542
 * @dev: the struct #fp_dev device
543 544
 * @print: the discovered print
 *
545
 * Determines if a #fp_dscv_print discovered print appears to be compatible
Daniel Drake's avatar
Daniel Drake committed
546
 * with a certain device.
547 548
 *
 * Returns: 1 if the print is compatible with the device, 0 if not
549 550
 *
 * Deprecated: Do not use.
Daniel Drake's avatar
Daniel Drake committed
551
 */
Daniel Drake's avatar
Daniel Drake committed
552
API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev,
553
	struct fp_dscv_print *print)
Daniel Drake's avatar
Daniel Drake committed
554 555
{
	return fpi_print_data_compatible(dev->drv->id, dev->devtype,
556
		0, print->driver_id, print->devtype, 0);
Daniel Drake's avatar
Daniel Drake committed
557 558
}

559 560 561 562
/**
 * fp_driver_get_name:
 * @drv: the driver
 *
Daniel Drake's avatar
Daniel Drake committed
563
 * Retrieves the name of the driver. For example: "upekts"
564 565
 *
 * Returns: the driver name. Must not be modified or freed.
Daniel Drake's avatar
Daniel Drake committed
566
 */
567
API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv)
568 569 570 571
{
	return drv->name;
}

572 573 574 575
/**
 * fp_driver_get_full_name:
 * @drv: the driver
 *
Daniel Drake's avatar
Daniel Drake committed
576
 * Retrieves a descriptive name of the driver. For example: "UPEK TouchStrip"
577 578
 *
 * Returns: the descriptive name. Must not be modified or freed.
Daniel Drake's avatar
Daniel Drake committed
579
 */
580
API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv)
581 582 583 584
{
	return drv->full_name;
}

585 586 587 588
/**
 * fp_driver_get_driver_id:
 * @drv: the driver
 *
Daniel Drake's avatar
Daniel Drake committed
589
 * Retrieves the driver ID code for a driver.
590 591
 *
 * Returns: the driver ID
Daniel Drake's avatar
Daniel Drake committed
592
 */
593 594 595 596 597
API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv)
{
	return drv->id;
}

598 599 600 601
/**
 * fp_driver_get_scan_type:
 * @drv: the driver
 *
602
 * Retrieves the scan type for the devices associated with the driver.
603 604
 *
 * Returns: the scan type
605 606 607 608 609 610
 */
API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv)
{
	return drv->scan_type;
}

611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
/**
 * fp_driver_supports_imaging:
 * @drv: the driver
 *
 * Determines if a driver has imaging capabilities. If a driver has imaging
 * capabilities you are able to perform imaging operations such as retrieving
 * scan images using fp_dev_img_capture(). However, not all drivers support
 * imaging devices – some do all processing in hardware. This function will
 * indicate which class a device in question falls into.
 *
 * Returns: 1 if the device is an imaging device, 0 if the device does not
 * provide images to the host computer
 */
API_EXPORTED int fp_driver_supports_imaging(struct fp_driver *drv)
{
	return drv->capture_start != NULL;
}

629 630
/**
 * fp_dev_supports_imaging:
631
 * @dev: the struct #fp_dev device
632
 *
Daniel Drake's avatar
Daniel Drake committed
633 634 635
 * 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
636
 * imaging devices – some do all processing in hardware. This function will
Daniel Drake's avatar
Daniel Drake committed
637
 * indicate which class a device in question falls into.
638 639
 *
 * Returns: 1 if the device is an imaging device, 0 if the device does not
Daniel Drake's avatar
Daniel Drake committed
640 641
 * provide images to the host computer
 */
642 643
API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev)
{
644
	return dev->drv->capture_start != NULL;
645 646
}

647 648
/**
 * fp_dev_supports_identification:
649
 * @dev: the struct #fp_dev device
650 651
 *
 * Determines if a device is capable of [identification](intro.html#identification)
652 653
 * through fp_identify_finger() and similar. Not all devices support this
 * functionality.
654 655
 *
 * Returns: 1 if the device is capable of identification, 0 otherwise.
656 657 658
 */
API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev)
{
659
	return dev->drv->identify_start != NULL;
660 661
}

662 663
/**
 * fp_dev_get_img_width:
664
 * @dev: the struct #fp_dev device
665
 *
Daniel Drake's avatar
Daniel Drake committed
666 667
 * Gets the expected width of images that will be captured from the device.
 * This function will return -1 for devices that are not
668
 * [imaging devices](libfprint-Devices-operations.html#imaging). If the width of images from this device
Daniel Drake's avatar
Daniel Drake committed
669
 * can vary, 0 will be returned.
670 671
 *
 * Returns: the expected image width, or 0 for variable, or -1 for non-imaging
Daniel Drake's avatar
Daniel Drake committed
672 673
 * devices.
 */
674 675
API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev)
{
676
	if (!dev->img_dev) {
677 678 679 680
		fp_dbg("get image width for non-imaging device");
		return -1;
	}

681
	return fpi_imgdev_get_img_width(dev->img_dev);
682 683
}

684 685
/**
 * fp_dev_get_img_height:
686
 * @dev: the struct #fp_dev device
687
 *
Daniel Drake's avatar
Daniel Drake committed
688 689
 * Gets the expected height of images that will be captured from the device.
 * This function will return -1 for devices that are not
690
 * [imaging devices](libfprint-Devices-operations.html#imaging). If the height of images from this device
Daniel Drake's avatar
Daniel Drake committed
691
 * can vary, 0 will be returned.
692 693
 *
 * Returns: the expected image height, or 0 for variable, or -1 for non-imaging
Daniel Drake's avatar
Daniel Drake committed
694 695
 * devices.
 */
696 697
API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev)
{
698
	if (!dev->img_dev) {
699 700 701 702
		fp_dbg("get image height for non-imaging device");
		return -1;
	}

703
	return fpi_imgdev_get_img_height(dev->img_dev);
704 705
}

706 707 708 709
/**
 * fp_set_debug:
 * @level: the verbosity level
 *
710
 * This call does nothing, see fp_init() for details.
Daniel Drake's avatar
Daniel Drake committed
711 712 713
 */
API_EXPORTED void fp_set_debug(int level)
{
714
	/* Nothing */
Daniel Drake's avatar
Daniel Drake committed
715 716
}

717 718 719
/**
 * fp_init:
 *
Daniel Drake's avatar
Daniel Drake committed
720 721
 * Initialise libfprint. This function must be called before you attempt to
 * use the library in any way.
722
 *
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
 * To enable debug output of libfprint specifically, use GLib's `G_MESSAGES_DEBUG`
 * environment variable as explained in [Running and debugging GLib Applications](https://developer.gnome.org/glib/stable/glib-running.html#G_MESSAGES_DEBUG).
 *
 * The log domains used in libfprint are either `libfprint` or `libfprint-FP_COMPONENT`
 * where `FP_COMPONENT` is defined in the source code for each driver, or component
 * of the library. Starting with `all` and trimming down is advised.
 *
 * To enable debugging of libusb, for USB-based fingerprint reader drivers, use
 * libusb's `LIBUSB_DEBUG` environment variable as explained in the
 * [libusb-1.0 API Reference](http://libusb.sourceforge.net/api-1.0/#msglog).
 *
 * Example:
 *
 * ```
 * LIBUSB_DEBUG=4 G_MESSAGES_DEBUG=all my-libfprint-application
 * ```
 *
740
 * Returns: 0 on success, non-zero on error.
Daniel Drake's avatar
Daniel Drake committed
741
 */
Daniel Drake's avatar
Daniel Drake committed
742 743
API_EXPORTED int fp_init(void)
{
744
	int r;
745
	G_DEBUG_HERE();
746

Daniel Drake's avatar
Daniel Drake committed
747
	r = libusb_init(&fpi_usb_ctx);
748 749 750
	if (r < 0)
		return r;

751
	register_drivers();
Daniel Drake's avatar
Daniel Drake committed
752
	fpi_poll_init();
Daniel Drake's avatar
Daniel Drake committed
753 754
	return 0;
}
755

756 757 758
/**
 * fp_exit:
 *
759 760 761 762 763 764
 * 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)
{
765
	G_DEBUG_HERE();
766

767 768 769 770 771 772 773 774 775 776
	if (opened_devices) {
		GSList *copy = g_slist_copy(opened_devices);
		GSList *elem = copy;
		fp_dbg("naughty app left devices open on exit!");

		do
			fp_dev_close((struct fp_dev *) elem->data);
		while ((elem = g_slist_next(elem)));

		g_slist_free(copy);
777 778 779 780 781
		g_slist_free(opened_devices);
		opened_devices = NULL;
	}

	fpi_data_exit();
782
	fpi_poll_exit();
783 784
	g_slist_free(registered_drivers);
	registered_drivers = NULL;
Daniel Drake's avatar
Daniel Drake committed
785
	libusb_exit(fpi_usb_ctx);
786 787
}