upekts: verify implementation

We can now verify live fingerprints using the verify example.
Error handling during verification needs to be improved.
This commit is contained in:
Daniel Drake 2007-10-15 22:09:46 +01:00
parent f59112d57c
commit bf9ce44f43

View file

@ -522,10 +522,12 @@ static const unsigned char scan_comp[] = {
0x12, 0xff, 0xff, 0xff, 0xff /* scan completion, prefixes print data */ 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, static int enroll(struct fp_dev *dev, gboolean initial,
int stage, struct fp_print_data **_data) int stage, struct fp_print_data **_data)
{ {
unsigned char poll_data[] = { 0x30, 0x01 };
unsigned char *data; unsigned char *data;
size_t data_len; size_t data_len;
int r; int r;
@ -539,6 +541,8 @@ static int enroll(struct fp_dev *dev, gboolean initial,
return r; return r;
/* FIXME: protocol misunderstanding here. device receives response /* FIXME: protocol misunderstanding here. device receives response
* to subcmd 0 after submitting subcmd 2? */ * 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) if (read_msg28(dev, 0x00, NULL, NULL) < 0)
return -EPROTO; return -EPROTO;
} }
@ -546,7 +550,8 @@ static int enroll(struct fp_dev *dev, gboolean initial,
while (!result) { while (!result) {
unsigned char status; 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) if (r < 0)
return r; return r;
if (read_msg28(dev, 0x00, &data, &data_len) < 0) 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) { if (result == FP_ENROLL_COMPLETE) {
struct fp_print_data *fdata; 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) if (r < 0)
return r; return r;
/* FIXME: protocol misunderstanding here. device receives response /* FIXME: protocol misunderstanding here. device receives response
@ -642,6 +648,121 @@ comp_out:
return result; 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[] = { static const struct usb_id id_table[] = {
{ .vendor = 0x0483, .product = 0x2016 }, { .vendor = 0x0483, .product = 0x2016 },
@ -655,5 +776,6 @@ const struct fp_driver upekts_driver = {
.init = dev_init, .init = dev_init,
.exit = dev_exit, .exit = dev_exit,
.enroll = enroll, .enroll = enroll,
.verify = verify,
}; };