upekts: verify implementation
[libfprint.git] / libfprint / drivers / upekts.c
blob305001ad75a9c3b3be599f939543463a876a2f8e
1 /*
2 * UPEK TouchStrip driver for libfprint
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
5 * Based in part on libthinkfinger:
6 * Copyright (C) 2006-2007 Timo Hoenig <thoenig@suse.de>
7 * Copyright (C) 2006 Pavel Machek <pavel@suse.cz>
9 * LGPL CRC code copied from GStreamer-0.10.10:
10 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
11 * Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the
25 * Free Software Foundation, Inc.,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #define FP_COMPONENT "upekts"
31 #include <errno.h>
32 #include <string.h>
34 #include <glib.h>
36 #include <fp_internal.h>
38 #define EP_IN (1 | USB_ENDPOINT_IN)
39 #define EP_OUT (2 | USB_ENDPOINT_OUT)
40 #define TIMEOUT 5000
42 struct upekts_dev {
43 uint8_t seq;
46 static const uint16_t crc_table[256] = {
47 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
48 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
49 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
50 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
51 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
52 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
53 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
54 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
55 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
56 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
57 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
58 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
59 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
60 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
61 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
62 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
63 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
64 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
65 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
66 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
67 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
68 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
69 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
70 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
71 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
72 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
73 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
74 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
75 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
76 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
77 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
78 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
81 static uint16_t udf_crc(unsigned char *buffer, size_t size)
83 uint16_t crc = 0;
84 while (size--)
85 crc = (uint16_t) ((crc << 8) ^
86 crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
87 return crc;
91 * MESSAGE FORMAT
93 * Messages to and from the device have the same format.
95 * Byte-wise:
96 * 'C' 'i' 'a' 'o' A B L <DATA> C1 C2
98 * Ciao prefixes all messages. L is the length of the data, <DATA> is L bytes
99 * long. C1 and C2 are the UDF-CRC16 for the whole message minus the Ciao
100 * prefix.
102 * When the device wants to command the driver to do something, it sends
103 * a message where B=0 and A!=0. The A value indicates the type of command.
104 * If the system is expected to respond to the command, it sends a message back
105 * with B=0 and A incremented.
107 * When the driver sends a command to the device, A=0 and B is used as a
108 * sequence counter. It starts at 0, increments by 0x10 on each command, and
109 * wraps around.
110 * After each command is sent, the device responds with another message
111 * indicating completion of the command including any data that was requested.
112 * This message has the same A and B values.
114 * When the driver is sending commands as above, and when the device is
115 * responding, the <DATA> seems to follow this structure:
117 * 28 L 0 0 0 S <INNERDATA>
119 * Where the length of <INNERDATA> is L-3, and S is some kind of subcommand
120 * code. In the device's response to a command, the subcommand code will be
121 * unchanged.
123 * After deducing and documenting the above, I found a few places where the
124 * above doesn't hold true. Those are marked with FIXME's below.
127 #define CMD_SEQ_INCREMENT 0x10
129 static int send_cmd(struct fp_dev *dev, unsigned char seq_a,
130 unsigned char seq_b, unsigned char *data, uint8_t len)
132 int r;
133 uint16_t crc;
135 /* 9 bytes extra for: 4 byte 'Ciao', 1 byte A, 1 byte B, 1 byte length,
136 * 2 byte CRC */
137 size_t urblen = len + 9;
138 unsigned char *buf;
140 if (!data && len > 0) {
141 fp_err("len>0 but no data?");
142 return -EINVAL;
145 buf = g_malloc(urblen);
147 /* Write header */
148 strncpy(buf, "Ciao", 4);
149 buf[4] = seq_a;
150 buf[5] = seq_b;
151 buf[6] = len;
153 /* Copy data */
154 if (data)
155 memcpy(buf + 7, data, len);
157 /* Append CRC */
158 crc = cpu_to_be16(udf_crc(buf + 4, urblen - 6));
159 buf[urblen - 2] = crc >> 8;
160 buf[urblen - 1] = crc & 0xff;
162 r = usb_bulk_write(dev->udev, EP_OUT, buf, urblen, TIMEOUT);
163 g_free(buf);
164 if (r < 0) {
165 fp_err("cmd write failed, code %d", r);
166 return r;
167 } else if ((unsigned int) r < urblen) {
168 fp_err("cmd write too short (%d/%d)", r, urblen);
169 return -EIO;
172 return 0;
175 static int send_cmd28(struct fp_dev *dev, unsigned char subcmd,
176 unsigned char *data, uint8_t innerlen)
178 size_t len = innerlen + 6;
179 unsigned char *buf = g_malloc0(len);
180 struct upekts_dev *upekdev = dev->priv;
181 uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT;
182 int r;
184 fp_dbg("seq=%02x subcmd=%02x with %d bytes of data", seq, subcmd, innerlen);
186 buf[0] = 0x28;
187 buf[1] = innerlen + 3;
188 buf[5] = subcmd;
189 memcpy(buf + 6, data, innerlen);
191 r = send_cmd(dev, 0, seq, buf, len);
192 if (r == 0)
193 upekdev->seq = seq;
195 g_free(buf);
196 return r;
199 static int send_cmdresponse(struct fp_dev *dev, unsigned char seq,
200 unsigned char *data, uint8_t len)
202 fp_dbg("seq=%02x len=%d", seq, len);
203 return send_cmd(dev, seq, 0, data, len);
206 static unsigned char *__read_msg(struct fp_dev *dev, size_t *data_len)
208 #define MSG_READ_BUF_SIZE 0x40
209 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
210 unsigned char *buf = g_malloc(MSG_READ_BUF_SIZE);
211 size_t buf_size = MSG_READ_BUF_SIZE;
212 uint16_t computed_crc, msg_crc;
213 uint8_t len;
214 int r;
216 r = usb_bulk_read(dev->udev, EP_IN, buf, buf_size, TIMEOUT);
217 if (r < 0) {
218 fp_err("msg read failed, code %d", r);
219 goto err;
220 } else if (r < 9) {
221 fp_err("msg read too short (%d/%d)", r, buf_size);
222 goto err;
225 if (strncmp(buf, "Ciao", 4) != 0) {
226 fp_err("no Ciao for you!!");
227 goto err;
230 len = buf[6];
232 if (r != MSG_READ_BUF_SIZE && (len + 9) < r) {
233 /* Check that the length claimed inside the message is in line with
234 * the amount of data that was transferred over USB. */
235 fp_err("msg didn't include enough data, expected=%d recv=%d",
236 len + 9, r);
237 goto err;
240 /* We use a 64 byte buffer for reading messages. However, sometimes
241 * messages are longer, in which case we have to do another USB bulk read
242 * to read the remainder. This is handled below. */
243 if (len > MAX_DATA_IN_READ_BUF) {
244 int needed = len - MAX_DATA_IN_READ_BUF;
245 fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed);
246 buf = g_realloc((gpointer) buf, MSG_READ_BUF_SIZE + needed);
247 r = usb_bulk_read(dev->udev, EP_IN, buf + MSG_READ_BUF_SIZE, needed,
248 TIMEOUT);
249 if (r < 0) {
250 fp_err("extended msg read failed, code %d", r);
251 goto err;
252 } else if (r < needed) {
253 fp_err("extended msg short read (%d/%d)", r, needed);
254 goto err;
256 buf_size += needed;
259 computed_crc = udf_crc(buf + 4, len + 3);
260 msg_crc = le16_to_cpu((buf[len + 8] << 8) | buf[len + 7]);
261 if (computed_crc != msg_crc) {
262 fp_err("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
263 goto err;
266 *data_len = buf_size;
267 return buf;
268 err:
269 g_free(buf);
270 return NULL;
273 enum read_msg_status {
274 READ_MSG_ERROR = -1,
275 READ_MSG_CMD = 1,
276 READ_MSG_RESPONSE = 2,
279 static enum read_msg_status read_msg(struct fp_dev *dev, uint8_t *seq,
280 unsigned char *subcmd, unsigned char **data, size_t *data_len)
282 #define MSG_READ_BUF_SIZE 0x40
283 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
284 unsigned char *buf;
285 size_t buf_size;
286 unsigned char code_a;
287 unsigned char code_b;
288 uint8_t len;
289 enum read_msg_status ret = READ_MSG_ERROR;
291 retry:
292 buf = __read_msg(dev, &buf_size);
293 if (!buf)
294 return READ_MSG_ERROR;
296 code_a = buf[4];
297 code_b = buf[5];
298 len = buf[6];
299 fp_dbg("A=%02x B=%02x len=%d", code_a, code_b, len);
301 if (code_a && !code_b) {
302 /* device sends command to driver */
303 fp_dbg("cmd %x from device to driver", code_a);
305 if (code_a == 0x08) {
306 fp_dbg("device busy, send busy-ack");
307 send_cmdresponse(dev, 0x09, NULL, 0);
308 g_free(buf);
309 goto retry;
312 if (seq)
313 *seq = code_a;
314 if (data) {
315 if (len > 0) {
316 unsigned char *tmp = g_malloc(len);
317 memcpy(tmp, buf + 7, len);
318 *data = tmp;
320 *data_len = len;
322 ret = READ_MSG_CMD;
323 } else if (!code_a) {
324 /* device sends response to a previously executed command */
325 unsigned char *innerbuf = buf + 7;
326 unsigned char _subcmd;
327 uint8_t innerlen;
329 if (len < 6) {
330 fp_err("cmd response too short (%d)", len);
331 goto out;
333 if (innerbuf[0] != 0x28) {
334 fp_err("cmd response without 28 byte?");
335 goto out;
337 if (innerbuf[2] || innerbuf[3] || innerbuf[4]) {
338 fp_err("non-zero bytes in cmd response");
339 goto out;
342 innerlen = innerbuf[1] - 3;
343 _subcmd = innerbuf[5];
344 fp_dbg("device responds to subcmd %x with %d bytes", _subcmd, innerlen);
345 if (seq)
346 *seq = code_b;
347 if (subcmd)
348 *subcmd = _subcmd;
349 if (data) {
350 if (innerlen > 0) {
351 unsigned char *tmp = g_malloc(innerlen);
352 memcpy(tmp, innerbuf + 6, innerlen);
353 *data = tmp;
355 *data_len = innerlen;
357 ret = READ_MSG_RESPONSE;
358 } else {
359 fp_err("don't know how to handle this message");
362 out:
363 g_free(buf);
364 return ret;
367 static int read_msg28(struct fp_dev *dev, unsigned char subcmd,
368 unsigned char **data, size_t *data_len)
370 struct upekts_dev *upekdev = dev->priv;
371 uint8_t _seq;
372 unsigned char _subcmd;
373 enum read_msg_status msgstat;
375 msgstat = read_msg(dev, &_seq, &_subcmd, data, data_len);
376 if (msgstat != READ_MSG_RESPONSE) {
377 fp_err("expected response, got %d seq=%x", msgstat, _seq);
378 return -EPROTO;
380 if (_subcmd != subcmd) {
381 fp_warn("expected response to subcmd %02x, got response to %02x",
382 subcmd, _subcmd);
383 return -EPROTO;
385 if (_seq != upekdev->seq) {
386 fp_err("expected response to cmd seq=%02x, got response to %02x",
387 upekdev->seq, _seq);
388 return -EPROTO;
391 return 0;
394 static const unsigned char init_resp03[] = {
395 0x01, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xff, 0x07
397 static const unsigned char init28_08[] = {
398 0x04, 0x83, 0x00, 0x2c, 0x22, 0x23, 0x97, 0xc9, 0xa7, 0x15, 0xa0, 0x8a,
399 0xab, 0x3c, 0xd0, 0xbf, 0xdb, 0xf3, 0x92, 0x6f, 0xae, 0x3b, 0x1e, 0x44,
400 0xc4
402 static const unsigned char init28_0c[] = {
403 0x04, 0x03, 0x00, 0x00, 0x00
405 static const unsigned char init28_0b[] = {
406 0x04, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
408 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x64, 0x01, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
412 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a,
413 0x00, 0x64, 0x00, 0xf4, 0x01, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00
417 static int dev_init(struct fp_dev *dev)
419 struct upekts_dev *upekdev;
420 unsigned char dummy = 0x10;
421 enum read_msg_status msgstat;
422 uint8_t seq;
423 int r;
425 r = usb_claim_interface(dev->udev, 0);
426 if (r < 0)
427 return r;
429 r = usb_control_msg(dev->udev, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
430 0x0c, 0x100, 0x400, &dummy, sizeof(dummy), TIMEOUT);
431 if (r < 0)
432 return r;
434 upekdev = g_malloc(sizeof(*upekdev));
435 upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */
436 dev->priv = upekdev;
437 dev->nr_enroll_stages = 3;
439 msgstat = read_msg(dev, &seq, NULL, NULL, NULL);
440 if (msgstat != READ_MSG_CMD) {
441 fp_err("expected command, got %d seq=%x", msgstat, seq);
442 goto err;
444 if (seq != 3) {
445 fp_err("expected seq=3, got %x", seq);
446 goto err;
449 r = send_cmdresponse(dev, ++seq, (unsigned char *) init_resp03,
450 sizeof(init_resp03));
451 if (r < 0)
452 goto err;
454 msgstat = read_msg(dev, &seq, NULL, NULL, NULL);
455 if (msgstat != READ_MSG_CMD) {
456 fp_err("expected command, got %d seq=%x", msgstat, seq);
457 goto err;
459 if (seq != 5) {
460 fp_err("expected seq=5, got %x", seq);
461 goto err;
464 dummy = 0x04;
465 r = send_cmd28(dev, 0x06, &dummy, 1);
466 if (r < 0)
467 goto err;
468 if (read_msg28(dev, 0x06, NULL, NULL) < 0)
469 goto err;
471 dummy = 0x04;
472 r = send_cmd28(dev, 0x07, &dummy, 1);
473 if (r < 0)
474 goto err;
475 if (read_msg28(dev, 0x07, NULL, NULL) < 0)
476 goto err;
478 r = send_cmd28(dev, 0x08, (unsigned char *) init28_08,
479 sizeof(init28_08));
480 if (r < 0)
481 goto err;
482 if (read_msg28(dev, 0x08, NULL, NULL) < 0)
483 goto err;
485 r = send_cmd28(dev, 0x0c, (unsigned char *) init28_0c,
486 sizeof(init28_0c));
487 if (r < 0)
488 goto err;
489 if (read_msg28(dev, 0x0c, NULL, NULL) < 0)
490 goto err;
492 r = send_cmd28(dev, 0x0b, (unsigned char *) init28_0b,
493 sizeof(init28_0b));
494 if (r < 0)
495 goto err;
496 if (read_msg28(dev, 0x0b, NULL, NULL) < 0)
497 goto err;
499 return 0;
500 err:
501 g_free(upekdev);
502 return -EPROTO;
505 static void dev_exit(struct fp_dev *dev)
507 unsigned char dummy = 0;
509 /* FIXME: either i've misunderstood the message system or this is illegal
510 * here, since we arent responding to anything. */
511 send_cmdresponse(dev, 0x07, &dummy, 1);
513 // FIXME should read msg A=01
515 g_free(dev->priv);
518 static const unsigned char enroll_init[] = {
519 0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08
521 static const unsigned char scan_comp[] = {
522 0x12, 0xff, 0xff, 0xff, 0xff /* scan completion, prefixes print data */
525 /* used for enrollment and verification */
526 static const unsigned char poll_data[] = { 0x30, 0x01 };
528 static int enroll(struct fp_dev *dev, gboolean initial,
529 int stage, struct fp_print_data **_data)
531 unsigned char *data;
532 size_t data_len;
533 int r;
534 int result = 0;
535 int passed = 0;
537 if (initial) {
538 r = send_cmd28(dev, 0x02, (unsigned char *) enroll_init,
539 sizeof(enroll_init));
540 if (r < 0)
541 return r;
542 /* FIXME: protocol misunderstanding here. device receives response
543 * to subcmd 0 after submitting subcmd 2? */
544 /* actually this is probably a poll response? does the above cmd
545 * include a 30 01 poll somewhere? */
546 if (read_msg28(dev, 0x00, NULL, NULL) < 0)
547 return -EPROTO;
550 while (!result) {
551 unsigned char status;
553 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
554 sizeof(poll_data));
555 if (r < 0)
556 return r;
557 if (read_msg28(dev, 0x00, &data, &data_len) < 0)
558 return -EPROTO;
560 if (data_len != 14) {
561 fp_err("received 3001 poll response of %d bytes?", data_len);
562 g_free(data);
563 return -EPROTO;
566 status = data[5];
567 fp_dbg("poll result = %02x", status);
569 /* These codes indicate that we're waiting for a finger scan, so poll
570 * again */
571 switch (status) {
572 case 0x0c:
573 case 0x0d:
574 case 0x0e:
575 /* no news, poll again */
576 if (passed)
577 result = FP_ENROLL_PASS;
578 break;
579 case 0x1c: /* FIXME what does this one mean? */
580 result = FP_ENROLL_RETRY;
581 break;
582 case 0x0f: /* scan taking too long, remove finger and try again */
583 result = FP_ENROLL_RETRY_REMOVE_FINGER;
584 break;
585 case 0x1e: /* swipe too short */
586 result = FP_ENROLL_RETRY_TOO_SHORT;
587 break;
588 case 0x24: /* finger not centered */
589 result = FP_ENROLL_RETRY_CENTER_FINGER;
590 break;
591 case 0x20:
592 /* finger scanned successfully */
593 /* don't break out immediately, need to look at the next
594 * value to determine if enrollment is complete or not */
595 passed = 1;
596 break;
597 case 0x00:
598 if (passed)
599 result = FP_ENROLL_COMPLETE;
600 break;
601 default:
602 fp_err("unrecognised scan status code %02x", status);
603 result = -EPROTO;
604 break;
606 g_free(data);
609 /* FIXME: need to extend protocol research to handle the case when
610 * enrolment fails, e.g. you scan a different finger on each stage */
612 if (result == FP_ENROLL_COMPLETE) {
613 struct fp_print_data *fdata;
615 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
616 sizeof(poll_data));
617 if (r < 0)
618 return r;
619 /* FIXME: protocol misunderstanding here. device receives response
620 * to subcmd 0 after submitting subcmd 2? */
621 if (read_msg28(dev, 0x02, &data, &data_len) < 0)
622 return -EPROTO;
624 if (data_len < sizeof(scan_comp)) {
625 fp_err("fingerprint data too short (%d bytes)", data_len);
626 result = -EPROTO;
627 goto comp_out;
629 if (memcmp(data, scan_comp, sizeof(scan_comp)) != 0) {
630 fp_err("unrecognised data prefix %x %x %x %x %x",
631 data[0], data[1], data[2], data[3], data[4]);
632 result = -EPROTO;
633 goto comp_out;
635 if (!_data) {
636 fp_err("complete but no data storage!");
637 result = FP_ENROLL_COMPLETE;
638 goto comp_out;
641 fdata = fpi_print_data_new(dev, data_len - sizeof(scan_comp));
642 memcpy(fdata->buffer, data + sizeof(scan_comp), data_len - sizeof(scan_comp));
643 *_data = fdata;
644 comp_out:
645 g_free(data);
648 return result;
651 static const unsigned char verify_hdr[] = {
652 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0xc0, 0xd4, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
654 0x00
657 static int verify(struct fp_dev *dev, struct fp_print_data *print)
659 size_t data_len = sizeof(verify_hdr) + print->length;
660 unsigned char *data;
661 int r;
662 unsigned char status;
663 gboolean need_poll = FALSE;
664 gboolean done = FALSE;
666 if (data_len > 255) {
667 fp_err("file too long!\n");
668 return -EINVAL;
671 data = g_malloc(data_len);
672 memcpy(data, verify_hdr, sizeof(verify_hdr));
673 memcpy(data + sizeof(verify_hdr), print->buffer, print->length);
675 r = send_cmd28(dev, 0x03, data, data_len);
676 if (r < 0)
677 return r;
678 g_free(data);
680 while (!done) {
681 if (need_poll) {
682 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
683 sizeof(poll_data));
684 if (r < 0)
685 return r;
686 } else {
687 need_poll = TRUE;
689 if (read_msg28(dev, 0x00, &data, &data_len) < 0)
690 return -EPROTO;
692 if (data_len != 14) {
693 fp_err("received 3001 poll response of %d bytes?", data_len);
694 r = -EPROTO;
695 goto out;
698 status = data[5];
699 fp_dbg("poll result = %02x", status);
701 /* These codes indicate that we're waiting for a finger scan, so poll
702 * again */
703 switch (status) {
704 case 0x0c: /* no news, poll again */
705 break;
706 case 0x20:
707 fp_dbg("processing scan for verification");
708 break;
709 case 0x00:
710 fp_dbg("good image");
711 done = TRUE;
712 break;
713 case 0x1c: /* FIXME what does this one mean? */
714 r = FP_VERIFY_RETRY;
715 goto out;
716 case 0x0f: /* scan taking too long, remove finger and try again */
717 r = FP_VERIFY_RETRY_REMOVE_FINGER;
718 goto out;
719 case 0x1e: /* swipe too short */
720 r = FP_VERIFY_RETRY_TOO_SHORT;
721 goto out;
722 case 0x24: /* finger not centered */
723 r = FP_VERIFY_RETRY_CENTER_FINGER;
724 goto out;
725 default:
726 fp_err("unrecognised verify status code %02x", status);
727 r = -EPROTO;
728 goto out;
730 g_free(data);
733 if (status == 0x00) {
734 /* poll again for verify result */
735 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
736 sizeof(poll_data));
737 if (r < 0)
738 return r;
739 if (read_msg28(dev, 0x03, &data, &data_len) < 0)
740 return -EPROTO;
741 if (data_len < 2) {
742 fp_err("verify result abnormally short!");
743 r = -EPROTO;
744 goto out;
746 if (data[0] != 0x12) {
747 fp_err("unexpected verify header byte %02x", data[0]);
748 r = -EPROTO;
749 goto out;
751 if (data[1] == 0x00) {
752 r = FP_VERIFY_NO_MATCH;
753 } else if (data[1] == 0x01) {
754 r = FP_VERIFY_MATCH;
755 } else {
756 fp_err("unrecognised verify result %02x", data[1]);
757 r = -EPROTO;
758 goto out;
762 out:
763 g_free(data);
764 return r;
767 static const struct usb_id id_table[] = {
768 { .vendor = 0x0483, .product = 0x2016 },
769 { 0, 0, 0, }, /* terminating entry */
772 const struct fp_driver upekts_driver = {
773 .name = FP_COMPONENT,
774 .full_name = "UPEK TouchStrip",
775 .id_table = id_table,
776 .init = dev_init,
777 .exit = dev_exit,
778 .enroll = enroll,
779 .verify = verify,