fpi-core.c 21.6 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 273
 * Scans the system and returns a list of discovered devices. This is your
 * entry point into finding a fingerprint reader to operate.
274
 *
Bastien Nocera's avatar
Bastien Nocera committed
275
 * Returns: a nul-terminated list of discovered devices. Must be freed with
Daniel Drake's avatar
Daniel Drake committed
276 277
 * fp_dscv_devs_free() after use.
 */
278 279
API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void)
{
280
	GPtrArray *tmparray;
281 282 283 284
	libusb_device *udev;
	libusb_device **devs;
	int r;
	int i = 0;
285

286
	g_return_val_if_fail (registered_drivers != NULL, NULL);
287

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

294 295
	tmparray = g_ptr_array_new ();

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

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

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

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

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

350 351 352 353
/**
 * fp_dscv_dev_get_driver_id:
 * @dev: a discovered fingerprint device
 *
354 355 356 357
 * Returns a unique driver identifier for the underlying driver
 * for that device.
 *
 * Returns: the ID for #dev
358 359 360 361 362 363
 */
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));
}

364 365 366 367 368 369 370
/**
 * 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
371
 */
372 373 374 375 376
API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev)
{
	return dev->devtype;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
/**
 * 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;
}

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

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

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

679
	return fpi_imgdev_get_img_width(dev->img_dev);
680 681
}

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

701
	return fpi_imgdev_get_img_height(dev->img_dev);
702 703
}

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

715 716 717
/**
 * fp_init:
 *
Daniel Drake's avatar
Daniel Drake committed
718 719
 * Initialise libfprint. This function must be called before you attempt to
 * use the library in any way.
720
 *
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
 * 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
 * ```
 *
738
 * Returns: 0 on success, non-zero on error.
Daniel Drake's avatar
Daniel Drake committed
739
 */
Daniel Drake's avatar
Daniel Drake committed
740 741
API_EXPORTED int fp_init(void)
{
742
	int r;
743
	G_DEBUG_HERE();
744

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

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

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

765 766 767 768 769 770 771 772 773 774
	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);
775 776 777 778 779
		g_slist_free(opened_devices);
		opened_devices = NULL;
	}

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