From bf9ce44f43c013a3822fe63a5214faf946a2ce8b Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 15 Oct 2007 22:09:46 +0100 Subject: [PATCH] upekts: verify implementation We can now verify live fingerprints using the verify example. Error handling during verification needs to be improved. --- libfprint/drivers/upekts.c | 128 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index a2d3280..305001a 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -522,10 +522,12 @@ static const unsigned char scan_comp[] = { 0x12, 0xff, 0xff, 0xff, 0xff /* scan completion, prefixes print data */ }; +/* used for enrollment and verification */ +static const unsigned char poll_data[] = { 0x30, 0x01 }; + static int enroll(struct fp_dev *dev, gboolean initial, int stage, struct fp_print_data **_data) { - unsigned char poll_data[] = { 0x30, 0x01 }; unsigned char *data; size_t data_len; int r; @@ -539,6 +541,8 @@ static int enroll(struct fp_dev *dev, gboolean initial, return r; /* FIXME: protocol misunderstanding here. device receives response * to subcmd 0 after submitting subcmd 2? */ + /* actually this is probably a poll response? does the above cmd + * include a 30 01 poll somewhere? */ if (read_msg28(dev, 0x00, NULL, NULL) < 0) return -EPROTO; } @@ -546,7 +550,8 @@ static int enroll(struct fp_dev *dev, gboolean initial, while (!result) { unsigned char status; - r = send_cmd28(dev, 0x00, poll_data, sizeof(poll_data)); + r = send_cmd28(dev, 0x00, (unsigned char *) poll_data, + sizeof(poll_data)); if (r < 0) return r; if (read_msg28(dev, 0x00, &data, &data_len) < 0) @@ -607,7 +612,8 @@ static int enroll(struct fp_dev *dev, gboolean initial, if (result == FP_ENROLL_COMPLETE) { struct fp_print_data *fdata; - r = send_cmd28(dev, 0x00, poll_data, sizeof(poll_data)); + r = send_cmd28(dev, 0x00, (unsigned char *) poll_data, + sizeof(poll_data)); if (r < 0) return r; /* FIXME: protocol misunderstanding here. device receives response @@ -642,6 +648,121 @@ comp_out: return result; } +static const unsigned char verify_hdr[] = { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xd4, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00 +}; + +static int verify(struct fp_dev *dev, struct fp_print_data *print) +{ + size_t data_len = sizeof(verify_hdr) + print->length; + unsigned char *data; + int r; + unsigned char status; + gboolean need_poll = FALSE; + gboolean done = FALSE; + + if (data_len > 255) { + fp_err("file too long!\n"); + return -EINVAL; + } + + data = g_malloc(data_len); + memcpy(data, verify_hdr, sizeof(verify_hdr)); + memcpy(data + sizeof(verify_hdr), print->buffer, print->length); + + r = send_cmd28(dev, 0x03, data, data_len); + if (r < 0) + return r; + g_free(data); + + while (!done) { + if (need_poll) { + r = send_cmd28(dev, 0x00, (unsigned char *) poll_data, + sizeof(poll_data)); + if (r < 0) + return r; + } else { + need_poll = TRUE; + } + if (read_msg28(dev, 0x00, &data, &data_len) < 0) + return -EPROTO; + + if (data_len != 14) { + fp_err("received 3001 poll response of %d bytes?", data_len); + r = -EPROTO; + goto out; + } + + status = data[5]; + fp_dbg("poll result = %02x", status); + + /* These codes indicate that we're waiting for a finger scan, so poll + * again */ + switch (status) { + case 0x0c: /* no news, poll again */ + break; + case 0x20: + fp_dbg("processing scan for verification"); + break; + case 0x00: + fp_dbg("good image"); + done = TRUE; + break; + case 0x1c: /* FIXME what does this one mean? */ + r = FP_VERIFY_RETRY; + goto out; + case 0x0f: /* scan taking too long, remove finger and try again */ + r = FP_VERIFY_RETRY_REMOVE_FINGER; + goto out; + case 0x1e: /* swipe too short */ + r = FP_VERIFY_RETRY_TOO_SHORT; + goto out; + case 0x24: /* finger not centered */ + r = FP_VERIFY_RETRY_CENTER_FINGER; + goto out; + default: + fp_err("unrecognised verify status code %02x", status); + r = -EPROTO; + goto out; + } + g_free(data); + } + + if (status == 0x00) { + /* poll again for verify result */ + r = send_cmd28(dev, 0x00, (unsigned char *) poll_data, + sizeof(poll_data)); + if (r < 0) + return r; + if (read_msg28(dev, 0x03, &data, &data_len) < 0) + return -EPROTO; + if (data_len < 2) { + fp_err("verify result abnormally short!"); + r = -EPROTO; + goto out; + } + if (data[0] != 0x12) { + fp_err("unexpected verify header byte %02x", data[0]); + r = -EPROTO; + goto out; + } + if (data[1] == 0x00) { + r = FP_VERIFY_NO_MATCH; + } else if (data[1] == 0x01) { + r = FP_VERIFY_MATCH; + } else { + fp_err("unrecognised verify result %02x", data[1]); + r = -EPROTO; + goto out; + } + } + +out: + g_free(data); + return r; +} static const struct usb_id id_table[] = { { .vendor = 0x0483, .product = 0x2016 }, @@ -655,5 +776,6 @@ const struct fp_driver upekts_driver = { .init = dev_init, .exit = dev_exit, .enroll = enroll, + .verify = verify, }; -- 2.11.4.GIT