v0.0.1 release
[libfprint.git] / libfprint / drivers / upekts.c
blob8b8ce08f8169e98024fffe9d0743155599d4c1a9
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 library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; version
16 * 2.1 of the License.
18 * This library 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 GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #define FP_COMPONENT "upekts"
30 #include <errno.h>
31 #include <string.h>
33 #include <glib.h>
34 #include <usb.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. The rightmost 4 bits of B become the uppermost
99 * 4 bits of L, and when combined with the lower 8 bits listed as 'L', L is
100 * the length of the data, <DATA> is L bytes long. C1 and C2 are the
101 * UDF-CRC16 for the whole message minus the Ciao prefix.
103 * When the device wants to command the driver to do something, it sends
104 * a message where B=0 and A!=0. The A value indicates the type of command.
105 * If the system is expected to respond to the command, it sends a message back
106 * with B=0 and A incremented.
108 * When the driver sends a command to the device, A=0 and B is used as a
109 * sequence counter. It starts at 0, increments by 0x10 on each command, and
110 * wraps around.
111 * After each command is sent, the device responds with another message
112 * indicating completion of the command including any data that was requested.
113 * This message has the same A and B values.
115 * When the driver is sending commands as above, and when the device is
116 * responding, the <DATA> seems to follow this structure:
118 * 28 L1 L2 0 0 S <INNERDATA>
120 * Where the length of <INNERDATA> is L-3, and S is some kind of subcommand
121 * code. L1 is the least significant bits of L, L2 is the most significant. In
122 * the device's response to a command, the subcommand code will be unchanged.
124 * After deducing and documenting the above, I found a few places where the
125 * above doesn't hold true. Those are marked with FIXME's below.
128 #define CMD_SEQ_INCREMENT 0x10
130 static int send_cmd(struct fp_dev *dev, unsigned char seq_a,
131 unsigned char seq_b, unsigned char *data, uint16_t len)
133 int r;
134 uint16_t crc;
136 /* 9 bytes extra for: 4 byte 'Ciao', 1 byte A, 1 byte B | lenHI,
137 * 1 byte lenLO, 2 byte CRC */
138 size_t urblen = len + 9;
139 unsigned char *buf;
141 if (!data && len > 0) {
142 fp_err("len>0 but no data?");
143 return -EINVAL;
146 buf = g_malloc(urblen);
148 /* Write header */
149 strncpy(buf, "Ciao", 4);
150 len = GUINT16_TO_LE(len);
151 buf[4] = seq_a;
152 buf[5] = seq_b | ((len & 0xf00) >> 8);
153 buf[6] = len & 0x00ff;
155 /* Copy data */
156 if (data)
157 memcpy(buf + 7, data, len);
159 /* Append CRC */
160 crc = GUINT16_TO_BE(udf_crc(buf + 4, urblen - 6));
161 buf[urblen - 2] = crc >> 8;
162 buf[urblen - 1] = crc & 0xff;
164 r = usb_bulk_write(dev->udev, EP_OUT, buf, urblen, TIMEOUT);
165 g_free(buf);
166 if (r < 0) {
167 fp_err("cmd write failed, code %d", r);
168 return r;
169 } else if ((unsigned int) r < urblen) {
170 fp_err("cmd write too short (%d/%d)", r, urblen);
171 return -EIO;
174 return 0;
177 static int send_cmd28(struct fp_dev *dev, unsigned char subcmd,
178 unsigned char *data, uint16_t innerlen)
180 uint16_t _innerlen = innerlen;
181 size_t len = innerlen + 6;
182 unsigned char *buf = g_malloc0(len);
183 struct upekts_dev *upekdev = dev->priv;
184 uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT;
185 int r;
187 fp_dbg("seq=%02x subcmd=%02x with %d bytes of data", seq, subcmd, innerlen);
189 _innerlen = GUINT16_TO_LE(innerlen + 3);
190 buf[0] = 0x28;
191 buf[1] = _innerlen & 0x00ff;
192 buf[2] = (_innerlen & 0xff00) >> 8;
193 buf[5] = subcmd;
194 memcpy(buf + 6, data, innerlen);
196 r = send_cmd(dev, 0, seq, buf, len);
197 if (r == 0)
198 upekdev->seq = seq;
200 g_free(buf);
201 return r;
204 static int send_cmdresponse(struct fp_dev *dev, unsigned char seq,
205 unsigned char *data, uint8_t len)
207 fp_dbg("seq=%02x len=%d", seq, len);
208 return send_cmd(dev, seq, 0, data, len);
211 static unsigned char *__read_msg(struct fp_dev *dev, size_t *data_len)
213 #define MSG_READ_BUF_SIZE 0x40
214 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
215 unsigned char *buf = g_malloc(MSG_READ_BUF_SIZE);
216 size_t buf_size = MSG_READ_BUF_SIZE;
217 uint16_t computed_crc, msg_crc;
218 uint16_t len;
219 int r;
221 r = usb_bulk_read(dev->udev, EP_IN, buf, buf_size, TIMEOUT);
222 if (r < 0) {
223 fp_err("msg read failed, code %d", r);
224 goto err;
225 } else if (r < 9) {
226 fp_err("msg read too short (%d/%d)", r, buf_size);
227 goto err;
230 if (strncmp(buf, "Ciao", 4) != 0) {
231 fp_err("no Ciao for you!!");
232 goto err;
235 len = GUINT16_FROM_LE(((buf[5] & 0xf) << 8) | buf[6]);
237 if (r != MSG_READ_BUF_SIZE && (len + 9) < r) {
238 /* Check that the length claimed inside the message is in line with
239 * the amount of data that was transferred over USB. */
240 fp_err("msg didn't include enough data, expected=%d recv=%d",
241 len + 9, r);
242 goto err;
245 /* We use a 64 byte buffer for reading messages. However, sometimes
246 * messages are longer, in which case we have to do another USB bulk read
247 * to read the remainder. This is handled below. */
248 if (len > MAX_DATA_IN_READ_BUF) {
249 int needed = len - MAX_DATA_IN_READ_BUF;
250 fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed);
251 buf = g_realloc((gpointer) buf, MSG_READ_BUF_SIZE + needed);
252 r = usb_bulk_read(dev->udev, EP_IN, buf + MSG_READ_BUF_SIZE, needed,
253 TIMEOUT);
254 if (r < 0) {
255 fp_err("extended msg read failed, code %d", r);
256 goto err;
257 } else if (r < needed) {
258 fp_err("extended msg short read (%d/%d)", r, needed);
259 goto err;
261 buf_size += needed;
264 computed_crc = udf_crc(buf + 4, len + 3);
265 msg_crc = GUINT16_FROM_LE((buf[len + 8] << 8) | buf[len + 7]);
266 if (computed_crc != msg_crc) {
267 fp_err("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
268 goto err;
271 *data_len = buf_size;
272 return buf;
273 err:
274 g_free(buf);
275 return NULL;
278 enum read_msg_status {
279 READ_MSG_ERROR = -1,
280 READ_MSG_CMD = 1,
281 READ_MSG_RESPONSE = 2,
284 static enum read_msg_status read_msg(struct fp_dev *dev, uint8_t *seq,
285 unsigned char *subcmd, unsigned char **data, size_t *data_len)
287 #define MSG_READ_BUF_SIZE 0x40
288 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
289 unsigned char *buf;
290 size_t buf_size;
291 unsigned char code_a;
292 unsigned char code_b;
293 uint16_t len;
294 enum read_msg_status ret = READ_MSG_ERROR;
296 retry:
297 buf = __read_msg(dev, &buf_size);
298 if (!buf)
299 return READ_MSG_ERROR;
301 code_a = buf[4];
302 code_b = buf[5] & 0xf0;
303 len = GUINT16_FROM_LE(((buf[5] & 0xf) << 8) | buf[6]);
304 fp_dbg("A=%02x B=%02x len=%d", code_a, code_b, len);
306 if (code_a && !code_b) {
307 /* device sends command to driver */
308 fp_dbg("cmd %x from device to driver", code_a);
310 if (code_a == 0x08) {
311 fp_dbg("device busy, send busy-ack");
312 send_cmdresponse(dev, 0x09, NULL, 0);
313 g_free(buf);
314 goto retry;
317 if (seq)
318 *seq = code_a;
319 if (data) {
320 if (len > 0) {
321 unsigned char *tmp = g_malloc(len);
322 memcpy(tmp, buf + 7, len);
323 *data = tmp;
325 *data_len = len;
327 ret = READ_MSG_CMD;
328 } else if (!code_a) {
329 /* device sends response to a previously executed command */
330 unsigned char *innerbuf = buf + 7;
331 unsigned char _subcmd;
332 uint16_t innerlen;
334 if (len < 6) {
335 fp_err("cmd response too short (%d)", len);
336 goto out;
338 if (innerbuf[0] != 0x28) {
339 fp_err("cmd response without 28 byte?");
340 goto out;
342 if (innerbuf[3] || innerbuf[4]) {
343 fp_err("non-zero bytes in cmd response");
344 goto out;
347 innerlen = innerbuf[1] | (innerbuf[2] << 8);
348 innerlen = GUINT16_FROM_LE(innerlen) - 3;
349 _subcmd = innerbuf[5];
350 fp_dbg("device responds to subcmd %x with %d bytes", _subcmd, innerlen);
351 if (seq)
352 *seq = code_b;
353 if (subcmd)
354 *subcmd = _subcmd;
355 if (data) {
356 if (innerlen > 0) {
357 unsigned char *tmp = g_malloc(innerlen);
358 memcpy(tmp, innerbuf + 6, innerlen);
359 *data = tmp;
361 *data_len = innerlen;
363 ret = READ_MSG_RESPONSE;
364 } else {
365 fp_err("don't know how to handle this message");
368 out:
369 g_free(buf);
370 return ret;
373 static int read_msg28(struct fp_dev *dev, unsigned char subcmd,
374 unsigned char **data, size_t *data_len)
376 struct upekts_dev *upekdev = dev->priv;
377 uint8_t _seq;
378 unsigned char _subcmd;
379 enum read_msg_status msgstat;
381 msgstat = read_msg(dev, &_seq, &_subcmd, data, data_len);
382 if (msgstat != READ_MSG_RESPONSE) {
383 fp_err("expected response, got %d seq=%x", msgstat, _seq);
384 return -EPROTO;
386 if (_subcmd != subcmd) {
387 fp_warn("expected response to subcmd %02x, got response to %02x",
388 subcmd, _subcmd);
389 return -EPROTO;
391 if (_seq != upekdev->seq) {
392 fp_err("expected response to cmd seq=%02x, got response to %02x",
393 upekdev->seq, _seq);
394 return -EPROTO;
397 return 0;
400 static const unsigned char init_resp03[] = {
401 0x01, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xff, 0x07
403 static const unsigned char init28_08[] = {
404 0x04, 0x83, 0x00, 0x2c, 0x22, 0x23, 0x97, 0xc9, 0xa7, 0x15, 0xa0, 0x8a,
405 0xab, 0x3c, 0xd0, 0xbf, 0xdb, 0xf3, 0x92, 0x6f, 0xae, 0x3b, 0x1e, 0x44,
406 0xc4
408 static const unsigned char init28_0c[] = {
409 0x04, 0x03, 0x00, 0x00, 0x00
411 static const unsigned char init28_0b[] = {
412 0x04, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
414 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x64, 0x01, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
418 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a,
419 0x00, 0x64, 0x00, 0xf4, 0x01, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00
423 static int do_init(struct fp_dev *dev)
425 enum read_msg_status msgstat;
426 unsigned char dummy = 0x10;
427 uint8_t seq;
428 int r;
430 r = usb_control_msg(dev->udev, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
431 0x0c, 0x100, 0x400, &dummy, sizeof(dummy), TIMEOUT);
432 if (r < 0) {
433 fp_dbg("control write failed\n");
434 return r;
437 msgstat = read_msg(dev, &seq, NULL, NULL, NULL);
438 if (msgstat != READ_MSG_CMD) {
439 fp_err("expected command, got %d seq=%x", msgstat, seq);
440 return -EPROTO;
442 if (seq != 3) {
443 fp_err("expected seq=3, got %x", seq);
444 return -EPROTO;
447 r = send_cmdresponse(dev, ++seq, (unsigned char *) init_resp03,
448 sizeof(init_resp03));
449 if (r < 0)
450 return r;
452 msgstat = read_msg(dev, &seq, NULL, NULL, NULL);
453 if (msgstat != READ_MSG_CMD) {
454 fp_err("expected command, got %d seq=%x", msgstat, seq);
455 return -EPROTO;
457 if (seq != 5) {
458 fp_err("expected seq=5, got %x", seq);
459 return -EPROTO;
462 dummy = 0x04;
463 r = send_cmd28(dev, 0x06, &dummy, 1);
464 if (r < 0)
465 return r;
466 if (read_msg28(dev, 0x06, NULL, NULL) < 0)
467 return r;
469 dummy = 0x04;
470 r = send_cmd28(dev, 0x07, &dummy, 1);
471 if (r < 0)
472 return r;
473 if (read_msg28(dev, 0x07, NULL, NULL) < 0)
474 return r;
476 r = send_cmd28(dev, 0x08, (unsigned char *) init28_08,
477 sizeof(init28_08));
478 if (r < 0)
479 return r;
480 if (read_msg28(dev, 0x08, NULL, NULL) < 0)
481 return r;
483 r = send_cmd28(dev, 0x0c, (unsigned char *) init28_0c,
484 sizeof(init28_0c));
485 if (r < 0)
486 return r;
487 if (read_msg28(dev, 0x0c, NULL, NULL) < 0)
488 return r;
490 r = send_cmd28(dev, 0x0b, (unsigned char *) init28_0b,
491 sizeof(init28_0b));
492 if (r < 0)
493 return r;
494 if (read_msg28(dev, 0x0b, NULL, NULL) < 0)
495 return r;
497 return 0;
500 static int do_deinit(struct fp_dev *dev)
502 unsigned char dummy = 0;
503 enum read_msg_status msgstat;
504 uint8_t seq;
505 int r;
507 /* FIXME: either i've misunderstood the message system or this is illegal
508 * here, since we arent responding to anything. */
509 r = send_cmdresponse(dev, 0x07, &dummy, 1);
510 if (r < 0)
511 return r;
513 msgstat = read_msg(dev, &seq, NULL, NULL, NULL);
514 if (msgstat != READ_MSG_CMD) {
515 fp_err("expected command, got %d seq=%x", msgstat, seq);
516 return -EPROTO;
518 if (seq != 1) {
519 fp_err("expected seq=1, got %x", seq);
520 return -EPROTO;
523 return 0;
526 static int dev_init(struct fp_dev *dev, unsigned long driver_data)
528 struct upekts_dev *upekdev = NULL;
529 int r;
531 r = usb_claim_interface(dev->udev, 0);
532 if (r < 0)
533 return r;
535 upekdev = g_malloc(sizeof(*upekdev));
536 upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */
537 dev->priv = upekdev;
538 dev->nr_enroll_stages = 3;
540 return 0;
543 static void dev_exit(struct fp_dev *dev)
545 usb_release_interface(dev->udev, 0);
546 g_free(dev->priv);
549 static const unsigned char enroll_init[] = {
550 0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08
552 static const unsigned char scan_comp[] = {
553 0x12, 0xff, 0xff, 0xff, 0xff /* scan completion, prefixes print data */
556 /* used for enrollment and verification */
557 static const unsigned char poll_data[] = { 0x30, 0x01 };
559 static int enroll(struct fp_dev *dev, gboolean initial,
560 int stage, struct fp_print_data **_data, struct fp_img **img)
562 unsigned char *data;
563 size_t data_len;
564 int r;
565 int result = 0;
566 int passed = 0;
568 if (initial) {
569 r = do_init(dev);
570 if (r < 0)
571 return r;
573 r = send_cmd28(dev, 0x02, (unsigned char *) enroll_init,
574 sizeof(enroll_init));
575 if (r < 0)
576 return r;
577 /* FIXME: protocol misunderstanding here. device receives response
578 * to subcmd 0 after submitting subcmd 2? */
579 /* actually this is probably a poll response? does the above cmd
580 * include a 30 01 poll somewhere? */
581 if (read_msg28(dev, 0x00, NULL, NULL) < 0)
582 return -EPROTO;
585 while (!result) {
586 unsigned char status;
588 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
589 sizeof(poll_data));
590 if (r < 0)
591 return r;
592 if (read_msg28(dev, 0x00, &data, &data_len) < 0)
593 return -EPROTO;
595 if (data_len != 14) {
596 fp_err("received 3001 poll response of %d bytes?", data_len);
597 g_free(data);
598 return -EPROTO;
601 status = data[5];
602 fp_dbg("poll result = %02x", status);
604 /* These codes indicate that we're waiting for a finger scan, so poll
605 * again */
606 switch (status) {
607 case 0x0c:
608 case 0x0d:
609 case 0x0e:
610 /* no news, poll again */
611 if (passed)
612 result = FP_ENROLL_PASS;
613 break;
614 case 0x1c: /* FIXME what does this one mean? */
615 case 0x0b: /* FIXME what does this one mean? */
616 case 0x23: /* FIXME what does this one mean? */
617 result = FP_ENROLL_RETRY;
618 break;
619 case 0x0f: /* scan taking too long, remove finger and try again */
620 result = FP_ENROLL_RETRY_REMOVE_FINGER;
621 break;
622 case 0x1e: /* swipe too short */
623 result = FP_ENROLL_RETRY_TOO_SHORT;
624 break;
625 case 0x24: /* finger not centered */
626 result = FP_ENROLL_RETRY_CENTER_FINGER;
627 break;
628 case 0x20:
629 /* finger scanned successfully */
630 /* don't break out immediately, need to look at the next
631 * value to determine if enrollment is complete or not */
632 passed = 1;
633 break;
634 case 0x00:
635 if (passed)
636 result = FP_ENROLL_COMPLETE;
637 break;
638 default:
639 fp_err("unrecognised scan status code %02x", status);
640 result = -EPROTO;
641 break;
643 g_free(data);
646 /* FIXME: need to extend protocol research to handle the case when
647 * enrolment fails, e.g. you scan a different finger on each stage */
649 if (result == FP_ENROLL_COMPLETE) {
650 struct fp_print_data *fdata;
652 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
653 sizeof(poll_data));
654 if (r < 0)
655 return r;
656 /* FIXME: protocol misunderstanding here. device receives response
657 * to subcmd 0 after submitting subcmd 2? */
658 if (read_msg28(dev, 0x02, &data, &data_len) < 0)
659 return -EPROTO;
661 if (data_len < sizeof(scan_comp)) {
662 fp_err("fingerprint data too short (%d bytes)", data_len);
663 result = -EPROTO;
664 goto comp_out;
666 if (memcmp(data, scan_comp, sizeof(scan_comp)) != 0) {
667 fp_err("unrecognised data prefix %x %x %x %x %x",
668 data[0], data[1], data[2], data[3], data[4]);
669 result = -EPROTO;
670 goto comp_out;
672 if (!_data) {
673 fp_err("complete but no data storage!");
674 result = FP_ENROLL_COMPLETE;
675 goto comp_out;
678 fdata = fpi_print_data_new(dev, data_len - sizeof(scan_comp));
679 memcpy(fdata->data, data + sizeof(scan_comp), data_len - sizeof(scan_comp));
680 *_data = fdata;
681 comp_out:
682 do_deinit(dev);
683 g_free(data);
686 return result;
689 static const unsigned char verify_hdr[] = {
690 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0xc0, 0xd4, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
692 0x00
695 static int verify(struct fp_dev *dev, struct fp_print_data *print,
696 struct fp_img **img)
698 size_t data_len = sizeof(verify_hdr) + print->length;
699 unsigned char *data;
700 int r;
701 unsigned char status;
702 gboolean need_poll = FALSE;
703 gboolean done = FALSE;
705 r = do_init(dev);
706 if (r < 0)
707 return r;
709 data = g_malloc(data_len);
710 memcpy(data, verify_hdr, sizeof(verify_hdr));
711 memcpy(data + sizeof(verify_hdr), print->data, print->length);
713 r = send_cmd28(dev, 0x03, data, data_len);
714 if (r < 0)
715 return r;
716 g_free(data);
718 while (!done) {
719 if (need_poll) {
720 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
721 sizeof(poll_data));
722 if (r < 0)
723 return r;
724 } else {
725 need_poll = TRUE;
727 if (read_msg28(dev, 0x00, &data, &data_len) < 0)
728 return -EPROTO;
730 if (data_len != 14) {
731 fp_err("received 3001 poll response of %d bytes?", data_len);
732 r = -EPROTO;
733 goto out;
736 status = data[5];
737 fp_dbg("poll result = %02x", status);
739 /* These codes indicate that we're waiting for a finger scan, so poll
740 * again */
741 switch (status) {
742 case 0x0c: /* no news, poll again */
743 break;
744 case 0x20:
745 fp_dbg("processing scan for verification");
746 break;
747 case 0x00:
748 fp_dbg("good image");
749 done = TRUE;
750 break;
751 case 0x1c: /* FIXME what does this one mean? */
752 case 0x0b: /* FIXME what does this one mean? */
753 case 0x23: /* FIXME what does this one mean? */
754 r = FP_VERIFY_RETRY;
755 goto out;
756 case 0x0f: /* scan taking too long, remove finger and try again */
757 r = FP_VERIFY_RETRY_REMOVE_FINGER;
758 goto out;
759 case 0x1e: /* swipe too short */
760 r = FP_VERIFY_RETRY_TOO_SHORT;
761 goto out;
762 case 0x24: /* finger not centered */
763 r = FP_VERIFY_RETRY_CENTER_FINGER;
764 goto out;
765 default:
766 fp_err("unrecognised verify status code %02x", status);
767 r = -EPROTO;
768 goto out;
770 g_free(data);
773 if (status == 0x00) {
774 /* poll again for verify result */
775 r = send_cmd28(dev, 0x00, (unsigned char *) poll_data,
776 sizeof(poll_data));
777 if (r < 0)
778 return r;
779 if (read_msg28(dev, 0x03, &data, &data_len) < 0)
780 return -EPROTO;
781 if (data_len < 2) {
782 fp_err("verify result abnormally short!");
783 r = -EPROTO;
784 goto out;
786 if (data[0] != 0x12) {
787 fp_err("unexpected verify header byte %02x", data[0]);
788 r = -EPROTO;
789 goto out;
791 if (data[1] == 0x00) {
792 r = FP_VERIFY_NO_MATCH;
793 } else if (data[1] == 0x01) {
794 r = FP_VERIFY_MATCH;
795 } else {
796 fp_err("unrecognised verify result %02x", data[1]);
797 r = -EPROTO;
798 goto out;
802 out:
803 do_deinit(dev);
804 g_free(data);
805 return r;
808 static const struct usb_id id_table[] = {
809 { .vendor = 0x0483, .product = 0x2016 },
810 { 0, 0, 0, }, /* terminating entry */
813 struct fp_driver upekts_driver = {
814 .id = 1,
815 .name = FP_COMPONENT,
816 .full_name = "UPEK TouchStrip",
817 .id_table = id_table,
818 .init = dev_init,
819 .exit = dev_exit,
820 .enroll = enroll,
821 .verify = verify,