From 50e2de0730c5d93dd1ad5f0f07e010ee1d92ad01 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Fri, 12 Oct 2007 15:27:23 +0100 Subject: [PATCH] Enrollment tweaks upekts will need to know when the first enrollment stage is attempted for the first time, so add an __enroll_stage counter which actually indicates the next stage to enroll. -1 is a special value and it means 0 is next *and* it is the initial attemt. Added more debug output to the enroll handler. Added new fp_enroll_status codes for too short or uncentered scans. Changed the print_data allocator to consider the device rather than the driver, this feels more natural. Added missing return value. Make fp_enroll_status codes start at 1. 0 can now be used as a special/temporary value by the drivers. Also check that we aren't exceeding the number of enroll stages. Also add a missing exit() call to the verify example and update for the above. --- examples/verify.c | 8 +++++++ libfprint/core.c | 48 ++++++++++++++++++++++++++++++++++++++++- libfprint/data.c | 7 +++--- libfprint/fp_internal.h | 10 ++++++--- libfprint/fprint.h | 4 +++- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/examples/verify.c b/examples/verify.c index 1a424fdf..5f668606 100644 --- a/examples/verify.c +++ b/examples/verify.c @@ -60,6 +60,13 @@ struct fp_print_data *enroll(struct fp_dev *dev) { 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; } } while (status != FP_ENROLL_COMPLETE); @@ -103,6 +110,7 @@ int main(void) fp_dscv_devs_free(discovered_devs); if (!dev) { fprintf(stderr, "Could not open device.\n"); + exit(1); } printf("Opened device. It's now time to enroll your finger.\n\n"); diff --git a/libfprint/core.c b/libfprint/core.c index 19a78b8b..b6d90f02 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -178,6 +178,7 @@ API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev) dev = g_malloc0(sizeof(*dev)); dev->drv = drv; dev->udev = udevh; + dev->__enroll_stage = -1; if (drv->init) { r = drv->init(dev); @@ -226,13 +227,58 @@ API_EXPORTED enum fp_enroll_status fp_enroll_finger(struct fp_dev *dev, struct fp_print_data **print_data) { const struct fp_driver *drv = dev->drv; + enum fp_enroll_status ret; + int stage = dev->__enroll_stage; + gboolean initial = FALSE; + if (!dev->nr_enroll_stages || !drv->enroll) { fp_err("driver %s has 0 enroll stages or no enroll func", dev->drv->name); return FP_ENROLL_FAIL; } - return drv->enroll(dev, print_data); + 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 " + "driver %s (%d stages)", dev->drv->name, dev->nr_enroll_stages); + return FP_ENROLL_FAIL; + } + fp_dbg("%s will handle enroll stage %d/%d%s", drv->name, stage, + dev->nr_enroll_stages - 1, initial ? " (initial)" : ""); + + ret = drv->enroll(dev, initial, stage, print_data); + 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; + 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; + return FP_ENROLL_FAIL; + } + return ret; } API_EXPORTED int fp_init(void) diff --git a/libfprint/data.c b/libfprint/data.c index d3b416cb..9f940b83 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -24,12 +24,13 @@ #include "fp_internal.h" -struct fp_print_data *fpi_print_data_new(struct fp_driver *drv, size_t length) +struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length) { struct fp_print_data *data = g_malloc(sizeof(*data) + length); - fp_dbg("length=%z", length); - data->driver_name = drv->name; + fp_dbg("length=%zd", length); + data->driver_name = dev->drv->name; data->length = length; + return data; } unsigned char *fpi_print_data_get_buffer(struct fp_print_data *data) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 23213b61..5073866c 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -22,6 +22,7 @@ #include +#include #include #ifdef __DARWIN_NULL @@ -65,6 +66,9 @@ struct fp_dev { void *priv; int nr_enroll_stages; + + /* drivers should not mess with these */ + int __enroll_stage; }; struct usb_id { @@ -81,8 +85,8 @@ struct fp_driver { /* Device operations */ int (*init)(struct fp_dev *dev); void (*exit)(struct fp_dev *dev); - enum fp_enroll_status (*enroll)(struct fp_dev *dev, - struct fp_print_data **print_data); + enum fp_enroll_status (*enroll)(struct fp_dev *dev, gboolean initial, + int stage, struct fp_print_data **print_data); }; extern const struct fp_driver upekts_driver; @@ -98,7 +102,7 @@ struct fp_print_data { unsigned char buffer[0]; }; -struct fp_print_data *fpi_print_data_new(struct fp_driver *drv, size_t length); +struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length); unsigned char *fpi_print_data_get_buffer(struct fp_print_data *data); int fpi_print_data_compatible(struct fp_dev *dev, struct fp_print_data *data); diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 6a2ac9ab..721cf02b 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -43,10 +43,12 @@ const char *fp_driver_get_full_name(const struct fp_driver *drv); /* Enrolment */ enum fp_enroll_status { - FP_ENROLL_COMPLETE, + FP_ENROLL_COMPLETE = 1, FP_ENROLL_FAIL, FP_ENROLL_PASS, FP_ENROLL_RETRY, + FP_ENROLL_RETRY_TOO_SHORT, + FP_ENROLL_RETRY_CENTER_FINGER, }; enum fp_enroll_status fp_enroll_finger(struct fp_dev *dev,