mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
examples: Add back examples using the async APIs
Add the examples back by using the new async API, support verification and enroll for devices with own storage.
This commit is contained in:
committed by
Benjamin Berg
parent
7d6b0c1376
commit
b46d336d2b
@@ -2,6 +2,7 @@
|
||||
* Example fingerprint enrollment program
|
||||
* Enrolls your right index finger and saves the print to disk
|
||||
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,91 +20,128 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
#include "storage.h"
|
||||
|
||||
struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs)
|
||||
typedef struct _EnrollData {
|
||||
GMainLoop *loop;
|
||||
int ret_value;
|
||||
} EnrollData;
|
||||
|
||||
static void
|
||||
enroll_data_free (EnrollData *enroll_data)
|
||||
{
|
||||
struct fp_dscv_dev *ddev = discovered_devs[0];
|
||||
struct fp_driver *drv;
|
||||
if (!ddev)
|
||||
g_main_loop_unref (enroll_data->loop);
|
||||
g_free (enroll_data);
|
||||
}
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (EnrollData, enroll_data_free)
|
||||
|
||||
FpDevice *discover_device (GPtrArray *devices)
|
||||
{
|
||||
FpDevice *dev;
|
||||
if (!devices->len)
|
||||
return NULL;
|
||||
|
||||
drv = fp_dscv_dev_get_driver(ddev);
|
||||
printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv));
|
||||
return ddev;
|
||||
|
||||
dev = g_ptr_array_index (devices, 0);
|
||||
printf("Found device claimed by %s driver\n", fp_device_get_driver (dev));
|
||||
return dev;
|
||||
}
|
||||
|
||||
struct fp_print_data *enroll(struct fp_dev *dev) {
|
||||
struct fp_print_data *enrolled_print = NULL;
|
||||
int r;
|
||||
static void
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||
EnrollData *enroll_data = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
printf("You will need to successfully scan your finger %d times to "
|
||||
"complete the process.\n", fp_dev_get_nr_enroll_stages(dev));
|
||||
fp_device_close_finish (dev, res, &error);
|
||||
|
||||
do {
|
||||
struct fp_img *img = NULL;
|
||||
if (error)
|
||||
g_warning ("Failed closing device %s\n", error->message);
|
||||
|
||||
printf("\nScan your finger now.\n");
|
||||
g_main_loop_quit (enroll_data->loop);
|
||||
}
|
||||
|
||||
r = fp_enroll_finger_img(dev, &enrolled_print, &img);
|
||||
if (img) {
|
||||
fp_img_save_to_file(img, "enrolled.pgm");
|
||||
printf("Wrote scanned image to enrolled.pgm\n");
|
||||
fp_img_free(img);
|
||||
static void
|
||||
on_enroll_completed (FpDevice *dev, GAsyncResult *res, void *user_data) {
|
||||
EnrollData *enroll_data = user_data;
|
||||
g_autoptr(FpPrint) print = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
print = fp_device_enroll_finish (dev, res, &error);
|
||||
|
||||
if (!error) {
|
||||
enroll_data->ret_value = EXIT_SUCCESS;
|
||||
|
||||
if (!fp_device_has_storage (dev)) {
|
||||
g_debug("Device has not storage, saving locally");
|
||||
int r = print_data_save(print, FP_FINGER_RIGHT_INDEX);
|
||||
if (r < 0) {
|
||||
g_warning("Data save failed, code %d", r);
|
||||
enroll_data->ret_value = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (r < 0) {
|
||||
printf("Enroll failed with error %d\n", r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (r) {
|
||||
case FP_ENROLL_COMPLETE:
|
||||
printf("Enroll complete!\n");
|
||||
break;
|
||||
case FP_ENROLL_FAIL:
|
||||
printf("Enroll failed, something wen't wrong :(\n");
|
||||
return NULL;
|
||||
case FP_ENROLL_PASS:
|
||||
printf("Enroll stage passed. Yay!\n");
|
||||
break;
|
||||
case FP_ENROLL_RETRY:
|
||||
printf("Didn't quite catch that. Please try again.\n");
|
||||
break;
|
||||
case FP_ENROLL_RETRY_TOO_SHORT:
|
||||
printf("Your swipe was too short, please try again.\n");
|
||||
break;
|
||||
case FP_ENROLL_RETRY_CENTER_FINGER:
|
||||
printf("Didn't catch that, please center your finger on the "
|
||||
"sensor and try again.\n");
|
||||
break;
|
||||
case FP_ENROLL_RETRY_REMOVE_FINGER:
|
||||
printf("Scan failed, please remove your finger and then try "
|
||||
"again.\n");
|
||||
break;
|
||||
}
|
||||
} while (r != FP_ENROLL_COMPLETE);
|
||||
|
||||
if (!enrolled_print) {
|
||||
fprintf(stderr, "Enroll complete but no print?\n");
|
||||
return NULL;
|
||||
} else {
|
||||
g_warning("Enroll failed with error %s\n", error->message);
|
||||
}
|
||||
|
||||
printf("Enrollment completed!\n\n");
|
||||
return enrolled_print;
|
||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
||||
enroll_data);
|
||||
}
|
||||
|
||||
static void
|
||||
on_enroll_progress (FpDevice *device,
|
||||
gint completed_stages,
|
||||
FpPrint *print,
|
||||
gpointer user_data,
|
||||
GError *error)
|
||||
{
|
||||
if (error) {
|
||||
g_warning ("Enroll stage %d of %d failed with error %s",
|
||||
completed_stages,
|
||||
fp_device_get_nr_enroll_stages (device),
|
||||
error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fp_device_supports_capture (device) &&
|
||||
print_image_save (print, "enrolled.pgm")) {
|
||||
printf ("Wrote scanned image to enrolled.pgm\n");
|
||||
}
|
||||
|
||||
printf ("Enroll stage %d of %d passed. Yay!\n", completed_stages,
|
||||
fp_device_get_nr_enroll_stages (device));
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
||||
{
|
||||
EnrollData *enroll_data = user_data;
|
||||
FpPrint *print_template;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
if (!fp_device_open_finish (dev, res, &error)) {
|
||||
g_warning ("Failed to open device: %s", error->message);
|
||||
g_main_loop_quit (enroll_data->loop);
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("Opened device. It's now time to enroll your finger.\n\n");
|
||||
printf ("You will need to successfully scan your finger %d times to "
|
||||
"complete the process.\n\n", fp_device_get_nr_enroll_stages (dev));
|
||||
printf ("Scan your finger now.\n");
|
||||
|
||||
print_template = print_create_template (dev, FP_FINGER_RIGHT_INDEX);
|
||||
fp_device_enroll (dev, print_template, NULL, on_enroll_progress, NULL,
|
||||
NULL, (GAsyncReadyCallback) on_enroll_completed,
|
||||
enroll_data);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int r = 1;
|
||||
struct fp_dscv_dev *ddev;
|
||||
struct fp_dscv_dev **discovered_devs;
|
||||
struct fp_dev *dev;
|
||||
struct fp_print_data *data;
|
||||
g_autoptr (FpContext) ctx = NULL;
|
||||
g_autoptr (EnrollData) enroll_data = NULL;
|
||||
GPtrArray *devices;
|
||||
FpDevice *dev;
|
||||
|
||||
printf("This program will enroll your right index finger, "
|
||||
"unconditionally overwriting any right-index print that was enrolled "
|
||||
@@ -112,48 +150,29 @@ int main(void)
|
||||
getchar();
|
||||
|
||||
setenv ("G_MESSAGES_DEBUG", "all", 0);
|
||||
setenv ("LIBUSB_DEBUG", "3", 0);
|
||||
|
||||
r = fp_init();
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Failed to initialize libfprint\n");
|
||||
exit(1);
|
||||
ctx = fp_context_new ();
|
||||
|
||||
devices = fp_context_get_devices (ctx);
|
||||
if (!devices) {
|
||||
g_warning("Impossible to get devices");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
discovered_devs = fp_discover_devs();
|
||||
if (!discovered_devs) {
|
||||
fprintf(stderr, "Could not discover devices\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ddev = discover_device(discovered_devs);
|
||||
if (!ddev) {
|
||||
fprintf(stderr, "No devices detected.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = fp_dev_open(ddev);
|
||||
fp_dscv_devs_free(discovered_devs);
|
||||
dev = discover_device (devices);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Could not open device.\n");
|
||||
goto out;
|
||||
g_warning("No devices detected.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Opened device. It's now time to enroll your finger.\n\n");
|
||||
data = enroll(dev);
|
||||
if (!data)
|
||||
goto out_close;
|
||||
enroll_data = g_new0 (EnrollData, 1);
|
||||
enroll_data->ret_value = EXIT_FAILURE;
|
||||
enroll_data->loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
r = print_data_save(data, RIGHT_INDEX);
|
||||
if (r < 0)
|
||||
fprintf(stderr, "Data save failed, code %d\n", r);
|
||||
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
|
||||
enroll_data);
|
||||
|
||||
fp_print_data_free(data);
|
||||
out_close:
|
||||
fp_dev_close(dev);
|
||||
out:
|
||||
fp_exit();
|
||||
return r;
|
||||
g_main_loop_run (enroll_data->loop);
|
||||
|
||||
return enroll_data->ret_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user