diff --git a/libfprint/core.c b/libfprint/core.c index a7741ad1..71ccaea9 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -798,7 +798,9 @@ API_EXPORTED int fp_dev_img_capture(struct fp_dev *dev, int unconditional, return -ENOTSUP; } - return fpi_imgdev_capture(imgdev, unconditional, image); + //return fpi_imgdev_capture(imgdev, unconditional, image); + /* FIXME reimplement async */ + return -ENOTSUP; } /** \ingroup dev diff --git a/libfprint/drv.c b/libfprint/drv.c index e45ce788..bb92126f 100644 --- a/libfprint/drv.c +++ b/libfprint/drv.c @@ -67,6 +67,7 @@ int fpi_drv_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback) { struct fp_driver *drv = dev->drv; int r; + fp_dbg(""); if (!drv->enroll_start) return -ENOTSUP; dev->state = DEV_STATE_ENROLL_STARTING; @@ -108,6 +109,7 @@ void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result, int fpi_drv_enroll_stop(struct fp_dev *dev) { struct fp_driver *drv = dev->drv; + fp_dbg(""); dev->enroll_cb = NULL; if (!drv->enroll_start) @@ -328,7 +330,7 @@ struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, int nr_states) { struct fpi_ssm *machine; - BUG_ON(nr_states < 1) + BUG_ON(nr_states < 1); machine = g_malloc0(sizeof(*machine)); machine->handler = handler; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 63d39cd9..6164672e 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -62,13 +62,15 @@ void fpi_log(enum fpi_log_level, const char *component, const char *function, #define fp_warn(fmt...) _fpi_log(LOG_LEVEL_WARNING, fmt) #define fp_err(fmt...) _fpi_log(LOG_LEVEL_ERROR, fmt) -#ifdef NDEBUG +#ifndef NDEBUG #define BUG_ON(condition) \ if ((condition)) fp_err("BUG at %s:%d", __FILE__, __LINE__) #else #define BUG_ON(condition) #endif +#define BUG() BUG_ON(1) + enum fp_dev_state { DEV_STATE_INITIAL = 0, DEV_STATE_ERROR, @@ -123,9 +125,48 @@ struct fp_dev { fp_identify_cb identify_cb; }; +enum fp_imgdev_state { + IMGDEV_STATE_INACTIVE, + IMGDEV_STATE_AWAIT_FINGER_ON, + IMGDEV_STATE_CAPTURE, + IMGDEV_STATE_AWAIT_FINGER_OFF, +}; + +enum fp_imgdev_action { + IMG_ACTION_NONE = 0, + IMG_ACTION_ENROLL, + IMG_ACTION_VERIFY, + IMG_ACTION_IDENTIFY, +}; + +enum fp_imgdev_enroll_state { + IMG_ACQUIRE_STATE_NONE = 0, + IMG_ACQUIRE_STATE_ACTIVATING, + IMG_ACQUIRE_STATE_AWAIT_FINGER_ON, + IMG_ACQUIRE_STATE_AWAIT_IMAGE, + IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF, + IMG_ACQUIRE_STATE_DONE, + IMG_ACQUIRE_STATE_DEACTIVATING, +}; + +enum fp_imgdev_verify_state { + IMG_VERIFY_STATE_NONE = 0, + IMG_VERIFY_STATE_ACTIVATING +}; + struct fp_img_dev { struct fp_dev *dev; libusb_dev_handle *udev; + enum fp_imgdev_action action; + int action_state; + + struct fp_print_data *acquire_data; + struct fp_img *acquire_img; + int action_result; + + /* FIXME: better place to put this? */ + size_t identify_match_offset; + void *priv; }; @@ -181,11 +222,10 @@ struct fp_img_driver { /* Device operations */ int (*init)(struct fp_img_dev *dev, unsigned long driver_data); - void (*exit)(struct fp_img_dev *dev); - int (*await_finger_on)(struct fp_img_dev *dev); - int (*await_finger_off)(struct fp_img_dev *dev); - int (*capture)(struct fp_img_dev *dev, gboolean unconditional, - struct fp_img **image); + void (*deinit)(struct fp_img_dev *dev); + int (*activate)(struct fp_img_dev *dev, enum fp_imgdev_state state); + int (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state); + void (*deactivate)(struct fp_img_dev *dev); }; extern struct fp_driver upekts_driver; @@ -277,7 +317,7 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, struct fp_print_data *new_print); int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, - struct fp_print_data **gallery, int match_threshold, int *match_offset); + struct fp_print_data **gallery, int match_threshold, size_t *match_offset); /* async drv <--> lib comms */ @@ -340,5 +380,15 @@ void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result, int fpi_drv_identify_stop(struct fp_dev *dev); void fpi_drvcb_identify_stopped(struct fp_dev *dev); +/* for image drivers */ +void fpi_imgdev_init_complete(struct fp_img_dev *imgdev, int status); +void fpi_imgdev_deinit_complete(struct fp_img_dev *imgdev); +void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status); +void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev); +void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, + gboolean present); +void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img); +void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error); + #endif diff --git a/libfprint/img.c b/libfprint/img.c index da831d5b..1c708582 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -334,7 +334,7 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, /* FIXME: the print buffer at this point is endian-specific, and will * only work when loaded onto machines with identical endianness. not good! - * data format should be platform-independant. */ + * data format should be platform-independent. */ *ret = print; return 0; @@ -365,7 +365,7 @@ int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, } int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, - struct fp_print_data **gallery, int match_threshold, int *match_offset) + struct fp_print_data **gallery, int match_threshold, size_t *match_offset) { struct xyt_struct *pstruct = (struct xyt_struct *) print->data; struct fp_print_data *gallery_print; diff --git a/libfprint/imgdev.c b/libfprint/imgdev.c index a511a198..e3eb8c5f 100644 --- a/libfprint/imgdev.c +++ b/libfprint/imgdev.c @@ -1,6 +1,6 @@ /* * Core imaging device functions for libfprint - * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2007-2008 Daniel Drake * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,9 @@ #include "fp_internal.h" +#define MIN_ACCEPTABLE_MINUTIAE 10 +#define BOZORTH3_DEFAULT_THRESHOLD 40 + static int img_dev_init(struct fp_dev *dev, unsigned long driver_data) { struct fp_img_dev *imgdev = g_malloc0(sizeof(*imgdev)); @@ -41,6 +44,8 @@ static int img_dev_init(struct fp_dev *dev, unsigned long driver_data) r = imgdrv->init(imgdev, driver_data); if (r) goto err; + } else { + fpi_drvcb_init_complete(dev, 0); } return 0; @@ -49,43 +54,37 @@ err: return r; } -static void img_dev_exit(struct fp_dev *dev) +void fpi_imgdev_init_complete(struct fp_img_dev *imgdev, int status) +{ + fpi_drvcb_init_complete(imgdev->dev, status); +} + +static void img_dev_deinit(struct fp_dev *dev) { struct fp_img_dev *imgdev = dev->priv; struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv); - if (imgdrv->exit) - imgdrv->exit(imgdev); + if (imgdrv->deinit) + imgdrv->deinit(imgdev); + else + fpi_drvcb_deinit_complete(dev); +} +void fpi_imgdev_deinit_complete(struct fp_img_dev *imgdev) +{ + fpi_drvcb_deinit_complete(imgdev->dev); g_free(imgdev); } -int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev) +static int dev_change_state(struct fp_img_dev *imgdev, + enum fp_imgdev_state state) { struct fp_driver *drv = imgdev->dev->drv; struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); - int width = imgdrv->img_width; - if (width > 0 && imgdrv->enlarge_factor > 1) - width *= imgdrv->enlarge_factor; - else if (width == -1) - width = 0; - - return width; -} - -int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev) -{ - struct fp_driver *drv = imgdev->dev->drv; - struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); - int height = imgdrv->img_height; - - if (height > 0 && imgdrv->enlarge_factor > 1) - height *= imgdrv->enlarge_factor; - else if (height == -1) - height = 0; - - return height; + if (!imgdrv->change_state) + return 0; + return imgdrv->change_state(imgdev, state); } static struct fp_img *im_resize(struct fp_img *img, unsigned int factor) @@ -131,79 +130,31 @@ static struct fp_img *im_resize(struct fp_img *img, unsigned int factor) return newimg; } -int fpi_imgdev_capture(struct fp_img_dev *imgdev, int unconditional, - struct fp_img **_img) +/* check image properties and resize it if necessary. potentially returns a new + * image after freeing the old one. */ +static int sanitize_image(struct fp_img_dev *imgdev, struct fp_img **_img) { struct fp_driver *drv = imgdev->dev->drv; struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); - struct fp_img *img; - int r; - - if (!_img) { - fp_err("no image pointer given"); - return -EINVAL; - } - - if (!imgdrv->capture) { - fp_err("img driver %s has no capture func", drv->name); - return -ENOTSUP; - } - - if (unconditional) { - if (!(imgdrv->flags & FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE)) { - fp_dbg("requested unconditional capture, but driver %s does not " - "support it", drv->name); - return -ENOTSUP; - } - } - - fp_dbg("%s will handle capture request", drv->name); - - if (!unconditional && imgdrv->await_finger_on) { - r = imgdrv->await_finger_on(imgdev); - if (r) { - fp_err("await_finger_on failed with error %d", r); - return r; - } - } - - r = imgdrv->capture(imgdev, unconditional, &img); - if (r) { - fp_err("capture failed with error %d", r); - return r; - } - - if (img == NULL) { - fp_err("capture succeeded but no image returned?"); - return -ENODATA; - } - - if (!unconditional && imgdrv->await_finger_off) { - r = imgdrv->await_finger_off(imgdev); - if (r) { - fp_err("await_finger_off failed with error %d", r); - fp_img_free(img); - return r; - } - } + struct fp_img *img = *_img; if (imgdrv->img_width > 0) { img->width = imgdrv->img_width; } else if (img->width <= 0) { fp_err("no image width assigned"); - goto err; + return -EINVAL; } if (imgdrv->img_height > 0) { img->height = imgdrv->img_height; } else if (img->height <= 0) { fp_err("no image height assigned"); - goto err; + return -EINVAL; } if (!fpi_img_is_sane(img)) { fp_err("image is not sane!"); - goto err; + return -EINVAL; } if (imgdrv->enlarge_factor > 1) { @@ -213,145 +164,335 @@ int fpi_imgdev_capture(struct fp_img_dev *imgdev, int unconditional, * were bigger. */ struct fp_img *tmp = im_resize(img, imgdrv->enlarge_factor); fp_img_free(img); - img = tmp; + *_img = tmp; } - - *_img = img; return 0; -err: - fp_img_free(img); - return -EIO; } -#define MIN_ACCEPTABLE_MINUTIAE 10 - -int img_dev_enroll(struct fp_dev *dev, gboolean initial, int stage, - struct fp_print_data **ret, struct fp_img **_img) +void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, + gboolean present) { - struct fp_img *img = NULL; - struct fp_img_dev *imgdev = dev->priv; - struct fp_print_data *print; - int r; + int r = imgdev->action_result; + fp_dbg(present ? "finger on sensor" : "finger removed"); - /* FIXME: convert to 3-stage enroll mechanism, where we scan 3 prints, - * use NFIQ to pick the best one, and discard the others */ - - r = fpi_imgdev_capture(imgdev, 0, &img); - - /* If we got an image, standardize it and return it even if the scan - * quality was too low for processing. */ - if (img) - fp_img_standardize(img); - if (_img) - *_img = img; - if (r) - return r; - - r = fpi_img_to_print_data(imgdev, img, &print); - if (r < 0) - return r; - if (img->minutiae->num < MIN_ACCEPTABLE_MINUTIAE) { - fp_dbg("not enough minutiae, %d/%d", r, MIN_ACCEPTABLE_MINUTIAE); - fp_print_data_free(print); - return FP_ENROLL_RETRY; + if (present && imgdev->action_state == IMG_ACQUIRE_STATE_AWAIT_FINGER_ON) { + dev_change_state(imgdev, IMGDEV_STATE_CAPTURE); + imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_IMAGE; + return; + } else if (present + || imgdev->action_state != IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF) { + fp_dbg("ignoring status report"); + return; } - *ret = print; - return FP_ENROLL_COMPLETE; + switch (imgdev->action) { + case IMG_ACTION_ENROLL: + fpi_drvcb_enroll_stage_completed(imgdev->dev, r, imgdev->acquire_data, + imgdev->acquire_img); + break; + case IMG_ACTION_VERIFY: + fpi_drvcb_report_verify_result(imgdev->dev, r, imgdev->acquire_img); + fp_print_data_free(imgdev->acquire_data); + break; + case IMG_ACTION_IDENTIFY: + fpi_drvcb_report_identify_result(imgdev->dev, r, + imgdev->identify_match_offset, imgdev->acquire_img); + fp_print_data_free(imgdev->acquire_data); + default: + fp_err("unhandled action %d", imgdev->action); + break; + } + imgdev->acquire_img = NULL; + imgdev->acquire_data = NULL; } -#define BOZORTH3_DEFAULT_THRESHOLD 40 - -static int img_dev_verify(struct fp_dev *dev, - struct fp_print_data *enrolled_print, struct fp_img **_img) +static void verify_process_img(struct fp_img_dev *imgdev) { - struct fp_img_dev *imgdev = dev->priv; - struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv); - struct fp_img *img = NULL; - struct fp_print_data *print; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(imgdev->dev->drv); int match_score = imgdrv->bz3_threshold; int r; - r = fpi_imgdev_capture(imgdev, 0, &img); - - /* If we got an image, standardize it and return it even if the scan - * quality was too low for processing. */ - if (img) - fp_img_standardize(img); - if (_img) - *_img = img; - if (r) - return r; - - r = fpi_img_to_print_data(imgdev, img, &print); - if (r < 0) - return r; - if (img->minutiae->num < MIN_ACCEPTABLE_MINUTIAE) { - fp_dbg("not enough minutiae, %d/%d", r, MIN_ACCEPTABLE_MINUTIAE); - fp_print_data_free(print); - return FP_VERIFY_RETRY; - } - if (match_score == 0) match_score = BOZORTH3_DEFAULT_THRESHOLD; - r = fpi_img_compare_print_data(enrolled_print, print); - fp_print_data_free(print); - if (r < 0) - return r; + r = fpi_img_compare_print_data(imgdev->dev->verify_data, + imgdev->acquire_data); + if (r >= match_score) - return FP_VERIFY_MATCH; - else - return FP_VERIFY_NO_MATCH; + r = FP_VERIFY_MATCH; + else if (r >= 0) + r = FP_VERIFY_NO_MATCH; + + imgdev->action_result = r; } -static int img_dev_identify(struct fp_dev *dev, - struct fp_print_data **print_gallery, size_t *match_offset, - struct fp_img **_img) +static void identify_process_img(struct fp_img_dev *imgdev) { - struct fp_img_dev *imgdev = dev->priv; - struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(dev->drv); - struct fp_img *img = NULL; - struct fp_print_data *print; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(imgdev->dev->drv); int match_score = imgdrv->bz3_threshold; + size_t match_offset; int r; - r = fpi_imgdev_capture(imgdev, 0, &img); - - /* If we got an image, standardize it and return it even if the scan - * quality was too low for processing. */ - if (img) - fp_img_standardize(img); - if (_img) - *_img = img; - if (r) - return r; - - r = fpi_img_to_print_data(imgdev, img, &print); - if (r < 0) - return r; - if (img->minutiae->num < MIN_ACCEPTABLE_MINUTIAE) { - fp_dbg("not enough minutiae, %d/%d", r, MIN_ACCEPTABLE_MINUTIAE); - fp_print_data_free(print); - return FP_VERIFY_RETRY; - } - if (match_score == 0) match_score = BOZORTH3_DEFAULT_THRESHOLD; - r = fpi_img_compare_print_data_to_gallery(print, print_gallery, - match_score, match_offset); - fp_print_data_free(print); + r = fpi_img_compare_print_data_to_gallery(imgdev->acquire_data, + imgdev->dev->identify_data, match_score, &match_offset); + + imgdev->action_result = r; + imgdev->identify_match_offset = match_offset; +} + +void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img) +{ + struct fp_print_data *print; + int r; + fp_dbg(""); + + if (imgdev->action_state != IMG_ACQUIRE_STATE_AWAIT_IMAGE) { + fp_dbg("ignoring due to current state %d", imgdev->action_state); + return; + } + + if (imgdev->action_result) { + fp_dbg("not overwriting existing action result"); + return; + } + + r = sanitize_image(imgdev, &img); + if (r < 0) { + imgdev->action_result = r; + fp_img_free(img); + goto next_state; + } + + fp_img_standardize(img); + imgdev->acquire_img = img; + fpi_img_to_print_data(imgdev, img, &print); + if (img->minutiae->num < MIN_ACCEPTABLE_MINUTIAE) { + fp_dbg("not enough minutiae, %d/%d", img->minutiae->num, + MIN_ACCEPTABLE_MINUTIAE); + fp_print_data_free(print); + /* depends on FP_ENROLL_RETRY == FP_VERIFY_RETRY */ + imgdev->action = FP_ENROLL_RETRY; + goto next_state; + } + + imgdev->acquire_data = print; + switch (imgdev->action) { + case IMG_ACTION_ENROLL: + imgdev->action_result = FP_ENROLL_COMPLETE; + break; + case IMG_ACTION_VERIFY: + verify_process_img(imgdev); + break; + case IMG_ACTION_IDENTIFY: + identify_process_img(imgdev); + break; + default: + BUG(); + break; + } + +next_state: + imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF; + dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF); +} + +void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error) +{ + fp_dbg("error %d", error); + BUG_ON(error == 0); + switch (imgdev->action) { + case IMG_ACTION_ENROLL: + fpi_drvcb_enroll_stage_completed(imgdev->dev, error, NULL, NULL); + break; + case IMG_ACTION_VERIFY: + fpi_drvcb_report_verify_result(imgdev->dev, error, NULL); + break; + case IMG_ACTION_IDENTIFY: + fpi_drvcb_report_identify_result(imgdev->dev, error, 0, NULL); + break; + default: + fp_err("unhandled action %d", imgdev->action); + break; + } +} + +void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status) +{ + fp_dbg("status %d", status); + + switch (imgdev->action) { + case IMG_ACTION_ENROLL: + fpi_drvcb_enroll_started(imgdev->dev, status); + break; + case IMG_ACTION_VERIFY: + fpi_drvcb_verify_started(imgdev->dev, status); + break; + case IMG_ACTION_IDENTIFY: + fpi_drvcb_identify_started(imgdev->dev, status); + break; + default: + fp_err("unhandled action %d", imgdev->action); + return; + } + + if (status == 0) { + imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_ON; + dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_ON); + } +} + +void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev) +{ + fp_dbg(""); + + switch (imgdev->action) { + case IMG_ACTION_ENROLL: + fpi_drvcb_enroll_stopped(imgdev->dev); + break; + case IMG_ACTION_VERIFY: + fpi_drvcb_verify_stopped(imgdev->dev); + break; + case IMG_ACTION_IDENTIFY: + fpi_drvcb_identify_stopped(imgdev->dev); + break; + default: + fp_err("unhandled action %d", imgdev->action); + break; + } + + imgdev->action = IMG_ACTION_NONE; + imgdev->action_state = 0; +} + +int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev) +{ + struct fp_driver *drv = imgdev->dev->drv; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); + int width = imgdrv->img_width; + + if (width > 0 && imgdrv->enlarge_factor > 1) + width *= imgdrv->enlarge_factor; + else if (width == -1) + width = 0; + + return width; +} + +int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev) +{ + struct fp_driver *drv = imgdev->dev->drv; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); + int height = imgdrv->img_height; + + if (height > 0 && imgdrv->enlarge_factor > 1) + height *= imgdrv->enlarge_factor; + else if (height == -1) + height = 0; + + return height; +} + +static int dev_activate(struct fp_img_dev *imgdev, enum fp_imgdev_state state) +{ + struct fp_driver *drv = imgdev->dev->drv; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); + + if (!imgdrv->activate) + return 0; + return imgdrv->activate(imgdev, state); +} + +static void dev_deactivate(struct fp_img_dev *imgdev) +{ + struct fp_driver *drv = imgdev->dev->drv; + struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); + + if (!imgdrv->activate) + return; + return imgdrv->deactivate(imgdev); +} + +static int generic_acquire_start(struct fp_dev *dev, int action) +{ + struct fp_img_dev *imgdev = dev->priv; + int r; + fp_dbg("action %d", action); + imgdev->action = action; + imgdev->action_state = IMG_ACQUIRE_STATE_ACTIVATING; + + r = dev_activate(imgdev, IMGDEV_STATE_AWAIT_FINGER_ON); + if (r < 0) + fp_err("activation failed with error %d", r); + return r; + +} + +static void generic_acquire_stop(struct fp_img_dev *imgdev) +{ + imgdev->action_state = IMG_ACQUIRE_STATE_DEACTIVATING; + dev_deactivate(imgdev); + + fp_print_data_free(imgdev->acquire_data); + fp_img_free(imgdev->acquire_img); + imgdev->acquire_data = NULL; + imgdev->acquire_img = NULL; + imgdev->action_result = 0; +} + +static int img_dev_enroll_start(struct fp_dev *dev) +{ + return generic_acquire_start(dev, IMG_ACTION_ENROLL); +} + +static int img_dev_verify_start(struct fp_dev *dev) +{ + return generic_acquire_start(dev, IMG_ACTION_VERIFY); +} + +static int img_dev_identify_start(struct fp_dev *dev) +{ + return generic_acquire_start(dev, IMG_ACTION_IDENTIFY); +} + +static int img_dev_enroll_stop(struct fp_dev *dev) +{ + struct fp_img_dev *imgdev = dev->priv; + BUG_ON(imgdev->action != IMG_ACTION_ENROLL); + generic_acquire_stop(imgdev); + return 0; +} + +static int img_dev_verify_stop(struct fp_dev *dev, gboolean iterating) +{ + struct fp_img_dev *imgdev = dev->priv; + BUG_ON(imgdev->action != IMG_ACTION_VERIFY); + generic_acquire_stop(imgdev); + return 0; +} + +static int img_dev_identify_stop(struct fp_dev *dev, gboolean iterating) +{ + struct fp_img_dev *imgdev = dev->priv; + BUG_ON(imgdev->action != IMG_ACTION_IDENTIFY); + generic_acquire_stop(imgdev); + imgdev->identify_match_offset = 0; + return 0; } void fpi_img_driver_setup(struct fp_img_driver *idriver) { idriver->driver.type = DRIVER_IMAGING; idriver->driver.init = img_dev_init; - //idriver->driver.exit = img_dev_exit; - //idriver->driver.enroll = img_dev_enroll; - //idriver->driver.verify = img_dev_verify; - //idriver->driver.identify = img_dev_identify; + idriver->driver.deinit = img_dev_deinit; + idriver->driver.enroll_start = img_dev_enroll_start; + idriver->driver.enroll_stop = img_dev_enroll_stop; + idriver->driver.verify_start = img_dev_verify_start; + idriver->driver.verify_stop = img_dev_verify_stop; + idriver->driver.identify_start = img_dev_identify_start; + idriver->driver.identify_stop = img_dev_identify_stop; }