imgdev: perform 5 scans for enrollment
This feature dramatically improves matching rate on devices with small sensors.
This commit is contained in:
parent
fe3fdd1f50
commit
e215b05094
6 changed files with 248 additions and 69 deletions
159
libfprint/data.c
159
libfprint/data.c
|
@ -95,21 +95,33 @@ static const char *finger_num_to_str(enum fp_finger finger)
|
|||
#endif
|
||||
|
||||
static struct fp_print_data *print_data_new(uint16_t driver_id,
|
||||
uint32_t devtype, enum fp_print_data_type type, size_t length)
|
||||
uint32_t devtype, enum fp_print_data_type type)
|
||||
{
|
||||
struct fp_print_data *data = g_malloc0(sizeof(*data) + length);
|
||||
fp_dbg("length=%zd driver=%02x devtype=%04x", length, driver_id, devtype);
|
||||
struct fp_print_data *data = g_malloc0(sizeof(*data));
|
||||
fp_dbg("driver=%02x devtype=%04x", driver_id, devtype);
|
||||
data->driver_id = driver_id;
|
||||
data->devtype = devtype;
|
||||
data->type = type;
|
||||
data->length = length;
|
||||
return data;
|
||||
}
|
||||
|
||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
|
||||
void fpi_print_data_item_free(struct fp_print_data_item *item)
|
||||
{
|
||||
g_free(item);
|
||||
}
|
||||
|
||||
struct fp_print_data_item *fpi_print_data_item_new(size_t length)
|
||||
{
|
||||
struct fp_print_data_item *item = g_malloc(sizeof(*item) + length);
|
||||
item->length = length;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev)
|
||||
{
|
||||
return print_data_new(dev->drv->id, dev->devtype,
|
||||
fpi_driver_get_data_type(dev->drv), length);
|
||||
fpi_driver_get_data_type(dev->drv));
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
|
@ -124,27 +136,115 @@ struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
|
|||
API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data,
|
||||
unsigned char **ret)
|
||||
{
|
||||
struct fpi_print_data_fp1 *buf;
|
||||
size_t buflen;
|
||||
struct fpi_print_data_fp2 *out_data;
|
||||
struct fpi_print_data_item_fp2 *out_item;
|
||||
struct fp_print_data_item *item;
|
||||
size_t buflen = 0;
|
||||
GSList *list_item;
|
||||
unsigned char *buf;
|
||||
|
||||
fp_dbg("");
|
||||
|
||||
buflen = sizeof(*buf) + data->length;
|
||||
buf = malloc(buflen);
|
||||
if (!buf)
|
||||
return 0;
|
||||
list_item = data->prints;
|
||||
while (list_item) {
|
||||
item = list_item->data;
|
||||
buflen += sizeof(*out_item);
|
||||
buflen += item->length;
|
||||
list_item = g_slist_next(list_item);
|
||||
}
|
||||
|
||||
buflen += sizeof(*out_data);
|
||||
out_data = g_malloc(buflen);
|
||||
|
||||
*ret = (unsigned char *) out_data;
|
||||
buf = out_data->data;
|
||||
out_data->prefix[0] = 'F';
|
||||
out_data->prefix[1] = 'P';
|
||||
out_data->prefix[2] = '2';
|
||||
out_data->driver_id = GUINT16_TO_LE(data->driver_id);
|
||||
out_data->devtype = GUINT32_TO_LE(data->devtype);
|
||||
out_data->data_type = data->type;
|
||||
|
||||
list_item = data->prints;
|
||||
while (list_item) {
|
||||
item = list_item->data;
|
||||
out_item = (struct fpi_print_data_item_fp2 *)buf;
|
||||
out_item->length = GUINT32_TO_LE(item->length);
|
||||
/* FIXME: fp_print_data_item->data content is not endianess agnostic */
|
||||
memcpy(out_item->data, item->data, item->length);
|
||||
buf += sizeof(*out_item);
|
||||
buf += item->length;
|
||||
list_item = g_slist_next(list_item);
|
||||
}
|
||||
|
||||
*ret = (unsigned char *) buf;
|
||||
buf->prefix[0] = 'F';
|
||||
buf->prefix[1] = 'P';
|
||||
buf->prefix[2] = '1';
|
||||
buf->driver_id = GUINT16_TO_LE(data->driver_id);
|
||||
buf->devtype = GUINT32_TO_LE(data->devtype);
|
||||
buf->data_type = data->type;
|
||||
memcpy(buf->data, data->data, data->length);
|
||||
return buflen;
|
||||
}
|
||||
|
||||
static struct fp_print_data *fpi_print_data_from_fp1_data(unsigned char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
size_t print_data_len;
|
||||
struct fp_print_data *data;
|
||||
struct fp_print_data_item *item;
|
||||
struct fpi_print_data_fp2 *raw = (struct fpi_print_data_fp2 *) buf;
|
||||
|
||||
print_data_len = buflen - sizeof(*raw);
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type);
|
||||
item = fpi_print_data_item_new(print_data_len);
|
||||
/* FIXME: fp_print_data->data content is not endianess agnostic */
|
||||
memcpy(item->data, raw->data, print_data_len);
|
||||
data->prints = g_slist_prepend(data->prints, item);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static struct fp_print_data *fpi_print_data_from_fp2_data(unsigned char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
size_t total_data_len, item_len;
|
||||
struct fp_print_data *data;
|
||||
struct fp_print_data_item *item;
|
||||
struct fpi_print_data_fp2 *raw = (struct fpi_print_data_fp2 *) buf;
|
||||
unsigned char *raw_buf;
|
||||
struct fpi_print_data_item_fp2 *raw_item;
|
||||
|
||||
total_data_len = buflen - sizeof(*raw);
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type);
|
||||
raw_buf = raw->data;
|
||||
while (total_data_len) {
|
||||
if (total_data_len < sizeof(*raw_item))
|
||||
break;
|
||||
total_data_len -= sizeof(*raw_item);
|
||||
|
||||
raw_item = (struct fpi_print_data_item_fp2 *)raw_buf;
|
||||
item_len = GUINT32_FROM_LE(raw_item->length);
|
||||
fp_dbg("item len %d, total_data_len %d", item_len, total_data_len);
|
||||
if (total_data_len < item_len) {
|
||||
fp_err("corrupted fingerprint data");
|
||||
break;
|
||||
}
|
||||
total_data_len -= item_len;
|
||||
|
||||
item = fpi_print_data_item_new(item_len);
|
||||
/* FIXME: fp_print_data->data content is not endianess agnostic */
|
||||
memcpy(item->data, raw_item->data, item_len);
|
||||
data->prints = g_slist_prepend(data->prints, item);
|
||||
|
||||
raw_buf += sizeof(*raw_item);
|
||||
raw_buf += item_len;
|
||||
}
|
||||
|
||||
if (g_slist_length(data->prints) == 0) {
|
||||
fp_print_data_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/** \ingroup print_data
|
||||
* Load a stored print from a data buffer. The contents of said buffer must
|
||||
* be the untouched contents of a buffer previously supplied to you by the
|
||||
|
@ -157,24 +257,21 @@ API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data,
|
|||
API_EXPORTED struct fp_print_data *fp_print_data_from_data(unsigned char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
struct fpi_print_data_fp1 *raw = (struct fpi_print_data_fp1 *) buf;
|
||||
size_t print_data_len;
|
||||
struct fp_print_data *data;
|
||||
struct fpi_print_data_fp2 *raw = (struct fpi_print_data_fp2 *) buf;
|
||||
|
||||
fp_dbg("buffer size %zd", buflen);
|
||||
if (buflen < sizeof(*raw))
|
||||
return NULL;
|
||||
|
||||
if (strncmp(raw->prefix, "FP1", 3) != 0) {
|
||||
if (strncmp(raw->prefix, "FP1", 3) == 0) {
|
||||
return fpi_print_data_from_fp1_data(buf, buflen);
|
||||
} else if (strncmp(raw->prefix, "FP2", 3) == 0) {
|
||||
return fpi_print_data_from_fp2_data(buf, buflen);
|
||||
} else {
|
||||
fp_dbg("bad header prefix");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
print_data_len = buflen - sizeof(*raw);
|
||||
data = print_data_new(GUINT16_FROM_LE(raw->driver_id),
|
||||
GUINT32_FROM_LE(raw->devtype), raw->data_type, print_data_len);
|
||||
memcpy(data->data, raw->data, print_data_len);
|
||||
return data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *get_path_to_storedir(uint16_t driver_id, uint32_t devtype)
|
||||
|
@ -405,6 +502,8 @@ API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print,
|
|||
*/
|
||||
API_EXPORTED void fp_print_data_free(struct fp_print_data *data)
|
||||
{
|
||||
if (data)
|
||||
g_slist_free_full(data->prints, (GDestroyNotify)fpi_print_data_item_free);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -1072,6 +1072,7 @@ static void e_handle_resp02(struct fp_dev *dev, unsigned char *data,
|
|||
size_t data_len)
|
||||
{
|
||||
struct fp_print_data *fdata = NULL;
|
||||
struct fp_print_data_item *item = NULL;
|
||||
int result = -EPROTO;
|
||||
|
||||
if (data_len < sizeof(scan_comp)) {
|
||||
|
@ -1080,9 +1081,11 @@ static void e_handle_resp02(struct fp_dev *dev, unsigned char *data,
|
|||
fp_err("unrecognised data prefix %x %x %x %x %x",
|
||||
data[0], data[1], data[2], data[3], data[4]);
|
||||
} else {
|
||||
fdata = fpi_print_data_new(dev, data_len - sizeof(scan_comp));
|
||||
memcpy(fdata->data, data + sizeof(scan_comp),
|
||||
fdata = fpi_print_data_new(dev);
|
||||
item = fpi_print_data_item_new(data_len - sizeof(scan_comp));
|
||||
memcpy(item->data, data + sizeof(scan_comp),
|
||||
data_len - sizeof(scan_comp));
|
||||
fdata->prints = g_slist_prepend(fdata->prints, item);
|
||||
|
||||
result = FP_ENROLL_COMPLETE;
|
||||
}
|
||||
|
@ -1244,12 +1247,13 @@ static void verify_start_sm_run_state(struct fpi_ssm *ssm)
|
|||
break;
|
||||
case VERIFY_INIT: ;
|
||||
struct fp_print_data *print = dev->verify_data;
|
||||
size_t data_len = sizeof(verify_hdr) + print->length;
|
||||
struct fp_print_data_item *item = print->prints->data;
|
||||
size_t data_len = sizeof(verify_hdr) + item->length;
|
||||
unsigned char *data = g_malloc(data_len);
|
||||
struct libusb_transfer *transfer;
|
||||
|
||||
memcpy(data, verify_hdr, sizeof(verify_hdr));
|
||||
memcpy(data + sizeof(verify_hdr), print->data, print->length);
|
||||
memcpy(data + sizeof(verify_hdr), item->data, item->length);
|
||||
transfer = alloc_send_cmd28_transfer(dev, 0x03, data, data_len,
|
||||
verify_init_2803_cb, ssm);
|
||||
g_free(data);
|
||||
|
|
|
@ -1077,6 +1077,7 @@ static void e_handle_resp02(struct fp_dev *dev, unsigned char *data,
|
|||
size_t data_len)
|
||||
{
|
||||
struct fp_print_data *fdata = NULL;
|
||||
struct fp_print_data_item *item = NULL;
|
||||
int result = -EPROTO;
|
||||
|
||||
if (data_len < sizeof(scan_comp)) {
|
||||
|
@ -1085,9 +1086,11 @@ static void e_handle_resp02(struct fp_dev *dev, unsigned char *data,
|
|||
fp_err("unrecognised data prefix %x %x %x %x %x",
|
||||
data[0], data[1], data[2], data[3], data[4]);
|
||||
} else {
|
||||
fdata = fpi_print_data_new(dev, data_len - sizeof(scan_comp));
|
||||
memcpy(fdata->data, data + sizeof(scan_comp),
|
||||
fdata = fpi_print_data_new(dev);
|
||||
item = fpi_print_data_item_new(data_len - sizeof(scan_comp));
|
||||
memcpy(item->data, data + sizeof(scan_comp),
|
||||
data_len - sizeof(scan_comp));
|
||||
fdata->prints = g_slist_prepend(fdata->prints, item);
|
||||
|
||||
result = FP_ENROLL_COMPLETE;
|
||||
}
|
||||
|
@ -1249,12 +1252,13 @@ static void verify_start_sm_run_state(struct fpi_ssm *ssm)
|
|||
break;
|
||||
case VERIFY_INIT: ;
|
||||
struct fp_print_data *print = dev->verify_data;
|
||||
size_t data_len = sizeof(verify_hdr) + print->length;
|
||||
struct fp_print_data_item *item = print->prints->data;
|
||||
size_t data_len = sizeof(verify_hdr) + item->length;
|
||||
unsigned char *data = g_malloc(data_len);
|
||||
struct libusb_transfer *transfer;
|
||||
|
||||
memcpy(data, verify_hdr, sizeof(verify_hdr));
|
||||
memcpy(data + sizeof(verify_hdr), print->data, print->length);
|
||||
memcpy(data + sizeof(verify_hdr), item->data, item->length);
|
||||
transfer = alloc_send_cmd28_transfer(dev, 0x03, data, data_len,
|
||||
verify_init_2803_cb, ssm);
|
||||
g_free(data);
|
||||
|
|
|
@ -179,7 +179,9 @@ struct fp_img_dev {
|
|||
int action_state;
|
||||
|
||||
struct fp_print_data *acquire_data;
|
||||
struct fp_print_data *enroll_data;
|
||||
struct fp_img *acquire_img;
|
||||
int enroll_stage;
|
||||
int action_result;
|
||||
|
||||
/* FIXME: better place to put this? */
|
||||
|
@ -325,15 +327,19 @@ enum fp_print_data_type {
|
|||
PRINT_DATA_NBIS_MINUTIAE,
|
||||
};
|
||||
|
||||
struct fp_print_data {
|
||||
uint16_t driver_id;
|
||||
uint32_t devtype;
|
||||
enum fp_print_data_type type;
|
||||
struct fp_print_data_item {
|
||||
size_t length;
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
struct fpi_print_data_fp1 {
|
||||
struct fp_print_data {
|
||||
uint16_t driver_id;
|
||||
uint32_t devtype;
|
||||
enum fp_print_data_type type;
|
||||
GSList *prints;
|
||||
};
|
||||
|
||||
struct fpi_print_data_fp2 {
|
||||
char prefix[3];
|
||||
uint16_t driver_id;
|
||||
uint32_t devtype;
|
||||
|
@ -341,8 +347,14 @@ struct fpi_print_data_fp1 {
|
|||
unsigned char data[0];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct fpi_print_data_item_fp2 {
|
||||
uint32_t length;
|
||||
unsigned char data[0];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void fpi_data_exit(void);
|
||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length);
|
||||
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev);
|
||||
struct fp_print_data_item *fpi_print_data_item_new(size_t length);
|
||||
gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1,
|
||||
enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2,
|
||||
enum fp_print_data_type type2);
|
||||
|
|
|
@ -313,6 +313,7 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img,
|
|||
struct fp_print_data **ret)
|
||||
{
|
||||
struct fp_print_data *print;
|
||||
struct fp_print_data_item *item;
|
||||
int r;
|
||||
|
||||
if (!img->minutiae) {
|
||||
|
@ -327,9 +328,11 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img,
|
|||
|
||||
/* FIXME: space is wasted if we dont hit the max minutiae count. would
|
||||
* be good to make this dynamic. */
|
||||
print = fpi_print_data_new(imgdev->dev, sizeof(struct xyt_struct));
|
||||
print = fpi_print_data_new(imgdev->dev);
|
||||
item = fpi_print_data_item_new(sizeof(struct xyt_struct));
|
||||
print->type = PRINT_DATA_NBIS_MINUTIAE;
|
||||
minutiae_to_xyt(img->minutiae, img->width, img->height, print->data);
|
||||
minutiae_to_xyt(img->minutiae, img->width, img->height, item->data);
|
||||
print->prints = g_slist_prepend(print->prints, item);
|
||||
|
||||
/* FIXME: the print buffer at this point is endian-specific, and will
|
||||
* only work when loaded onto machines with identical endianness. not good!
|
||||
|
@ -342,42 +345,73 @@ 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)
|
||||
{
|
||||
struct xyt_struct *gstruct = (struct xyt_struct *) enrolled_print->data;
|
||||
struct xyt_struct *pstruct = (struct xyt_struct *) new_print->data;
|
||||
GTimer *timer;
|
||||
int r;
|
||||
int score, max_score = 0, probe_len;
|
||||
struct xyt_struct *pstruct = NULL;
|
||||
struct xyt_struct *gstruct = NULL;
|
||||
struct fp_print_data_item *data_item;
|
||||
GSList *list_item;
|
||||
|
||||
if (enrolled_print->type != PRINT_DATA_NBIS_MINUTIAE ||
|
||||
new_print->type != PRINT_DATA_NBIS_MINUTIAE) {
|
||||
new_print->type != PRINT_DATA_NBIS_MINUTIAE) {
|
||||
fp_err("invalid print format");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
timer = g_timer_new();
|
||||
r = bozorth_main(pstruct, gstruct);
|
||||
g_timer_stop(timer);
|
||||
fp_dbg("bozorth processing took %f seconds, score=%d",
|
||||
g_timer_elapsed(timer, NULL), r);
|
||||
g_timer_destroy(timer);
|
||||
if (g_slist_length(new_print->prints) != 1) {
|
||||
fp_err("new_print contains more than one sample, is it enrolled print?");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return r;
|
||||
data_item = new_print->prints->data;
|
||||
pstruct = (struct xyt_struct *)data_item->data;
|
||||
|
||||
probe_len = bozorth_probe_init(pstruct);
|
||||
list_item = enrolled_print->prints;
|
||||
do {
|
||||
data_item = list_item->data;
|
||||
gstruct = (struct xyt_struct *)data_item->data;
|
||||
score = bozorth_to_gallery(probe_len, pstruct, gstruct);
|
||||
fp_dbg("score %d", score);
|
||||
max_score = max(score, max_score);
|
||||
list_item = g_slist_next(list_item);
|
||||
} while (list_item);
|
||||
|
||||
return max_score;
|
||||
}
|
||||
|
||||
int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print,
|
||||
struct fp_print_data **gallery, int match_threshold, size_t *match_offset)
|
||||
{
|
||||
struct xyt_struct *pstruct = (struct xyt_struct *) print->data;
|
||||
struct xyt_struct *pstruct;
|
||||
struct xyt_struct *gstruct;
|
||||
struct fp_print_data *gallery_print;
|
||||
int probe_len = bozorth_probe_init(pstruct);
|
||||
struct fp_print_data_item *data_item;
|
||||
int probe_len;
|
||||
size_t i = 0;
|
||||
int r;
|
||||
GSList *list_item;
|
||||
|
||||
if (g_slist_length(print->prints) != 1) {
|
||||
fp_err("new_print contains more than one sample, is it enrolled print?");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_item = print->prints->data;
|
||||
pstruct = (struct xyt_struct *)data_item->data;
|
||||
|
||||
probe_len = bozorth_probe_init(pstruct);
|
||||
while ((gallery_print = gallery[i++])) {
|
||||
struct xyt_struct *gstruct = (struct xyt_struct *) gallery_print->data;
|
||||
int r = bozorth_to_gallery(probe_len, pstruct, gstruct);
|
||||
if (r >= match_threshold) {
|
||||
*match_offset = i - 1;
|
||||
return FP_VERIFY_MATCH;
|
||||
}
|
||||
list_item = gallery_print->prints;
|
||||
do {
|
||||
data_item = list_item->data;
|
||||
gstruct = (struct xyt_struct *)data_item->data;
|
||||
r = bozorth_to_gallery(probe_len, pstruct, gstruct);
|
||||
if (r >= match_threshold) {
|
||||
*match_offset = i - 1;
|
||||
return FP_VERIFY_MATCH;
|
||||
}
|
||||
list_item = g_slist_next(list_item);
|
||||
} while (list_item);
|
||||
}
|
||||
return FP_VERIFY_NO_MATCH;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#define MIN_ACCEPTABLE_MINUTIAE 10
|
||||
#define BOZORTH3_DEFAULT_THRESHOLD 40
|
||||
#define IMG_ENROLL_STAGES 5
|
||||
|
||||
static int img_dev_open(struct fp_dev *dev, unsigned long driver_data)
|
||||
{
|
||||
|
@ -33,8 +34,9 @@ static int img_dev_open(struct fp_dev *dev, unsigned long driver_data)
|
|||
int r = 0;
|
||||
|
||||
imgdev->dev = dev;
|
||||
imgdev->enroll_stage = 0;
|
||||
dev->priv = imgdev;
|
||||
dev->nr_enroll_stages = 1;
|
||||
dev->nr_enroll_stages = IMG_ENROLL_STAGES;
|
||||
|
||||
/* for consistency in driver code, allow udev access through imgdev */
|
||||
imgdev->udev = dev->udev;
|
||||
|
@ -144,7 +146,13 @@ void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev,
|
|||
switch (imgdev->action) {
|
||||
case IMG_ACTION_ENROLL:
|
||||
fp_dbg("reporting enroll result");
|
||||
fpi_drvcb_enroll_stage_completed(imgdev->dev, r, data, img);
|
||||
data = imgdev->enroll_data;
|
||||
if (r == FP_ENROLL_COMPLETE) {
|
||||
imgdev->enroll_data = NULL;
|
||||
}
|
||||
fpi_drvcb_enroll_stage_completed(imgdev->dev, r,
|
||||
r == FP_ENROLL_COMPLETE ? data : NULL,
|
||||
img);
|
||||
/* the callback can cancel enrollment, so recheck current
|
||||
* action and the status to see if retry is needed */
|
||||
if (imgdev->action == IMG_ACTION_ENROLL &&
|
||||
|
@ -253,7 +261,22 @@ void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img)
|
|||
imgdev->acquire_data = print;
|
||||
switch (imgdev->action) {
|
||||
case IMG_ACTION_ENROLL:
|
||||
imgdev->action_result = FP_ENROLL_COMPLETE;
|
||||
if (!imgdev->enroll_data) {
|
||||
imgdev->enroll_data = fpi_print_data_new(imgdev->dev);
|
||||
}
|
||||
BUG_ON(g_slist_length(print->prints) != 1);
|
||||
/* Move print data from acquire data into enroll_data */
|
||||
imgdev->enroll_data->prints =
|
||||
g_slist_prepend(imgdev->enroll_data->prints, print->prints->data);
|
||||
print->prints = g_slist_remove(print->prints, print->prints->data);
|
||||
|
||||
fp_print_data_free(imgdev->acquire_data);
|
||||
imgdev->acquire_data = NULL;
|
||||
imgdev->enroll_stage++;
|
||||
if (imgdev->enroll_stage == imgdev->dev->nr_enroll_stages)
|
||||
imgdev->action_result = FP_ENROLL_COMPLETE;
|
||||
else
|
||||
imgdev->action_result = FP_ENROLL_PASS;
|
||||
break;
|
||||
case IMG_ACTION_VERIFY:
|
||||
verify_process_img(imgdev);
|
||||
|
@ -402,6 +425,7 @@ static int generic_acquire_start(struct fp_dev *dev, int action)
|
|||
fp_dbg("action %d", action);
|
||||
imgdev->action = action;
|
||||
imgdev->action_state = IMG_ACQUIRE_STATE_ACTIVATING;
|
||||
imgdev->enroll_stage = 0;
|
||||
|
||||
r = dev_activate(imgdev, IMGDEV_STATE_AWAIT_FINGER_ON);
|
||||
if (r < 0)
|
||||
|
@ -417,8 +441,10 @@ static void generic_acquire_stop(struct fp_img_dev *imgdev)
|
|||
dev_deactivate(imgdev);
|
||||
|
||||
fp_print_data_free(imgdev->acquire_data);
|
||||
fp_print_data_free(imgdev->enroll_data);
|
||||
fp_img_free(imgdev->acquire_img);
|
||||
imgdev->acquire_data = NULL;
|
||||
imgdev->enroll_data = NULL;
|
||||
imgdev->acquire_img = NULL;
|
||||
imgdev->action_result = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue