Fix fp_get_pollfds()
[libfprint.git] / libfprint / drivers / upekts.c
bloba67cd9430154b8939734d545af3dea774fb88a97
1 /*
2 * UPEK TouchStrip driver for libfprint
3 * Copyright (C) 2007-2008 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 <libusb.h>
36 #include <fp_internal.h>
38 #define EP_IN (1 | LIBUSB_ENDPOINT_IN)
39 #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
40 #define TIMEOUT 5000
42 #define MSG_READ_BUF_SIZE 0x40
43 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
45 struct upekts_dev {
46 gboolean enroll_passed;
47 gboolean first_verify_iteration;
48 gboolean stop_verify;
49 uint8_t seq; /* FIXME: improve/automate seq handling */
52 static const uint16_t crc_table[256] = {
53 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
54 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
55 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
56 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
57 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
58 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
59 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
60 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
61 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
62 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
63 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
64 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
65 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
66 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
67 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
68 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
69 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
70 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
71 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
72 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
73 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
74 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
75 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
76 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
77 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
78 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
79 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
80 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
81 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
82 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
83 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
84 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
87 static uint16_t udf_crc(unsigned char *buffer, size_t size)
89 uint16_t crc = 0;
90 while (size--)
91 crc = (uint16_t) ((crc << 8) ^
92 crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]);
93 return crc;
97 * MESSAGE FORMAT
99 * Messages to and from the device have the same format.
101 * Byte-wise:
102 * 'C' 'i' 'a' 'o' A B L <DATA> C1 C2
104 * Ciao prefixes all messages. The rightmost 4 bits of B become the uppermost
105 * 4 bits of L, and when combined with the lower 8 bits listed as 'L', L is
106 * the length of the data, <DATA> is L bytes long. C1 and C2 are the
107 * UDF-CRC16 for the whole message minus the Ciao prefix.
109 * When the device wants to command the driver to do something, it sends
110 * a message where B=0 and A!=0. The A value indicates the type of command.
111 * If the system is expected to respond to the command, it sends a message back
112 * with B=0 and A incremented.
114 * When the driver sends a command to the device, A=0 and B is used as a
115 * sequence counter. It starts at 0, increments by 0x10 on each command, and
116 * wraps around.
117 * After each command is sent, the device responds with another message
118 * indicating completion of the command including any data that was requested.
119 * This message has the same A and B values.
121 * When the driver is sending commands as above, and when the device is
122 * responding, the <DATA> seems to follow this structure:
124 * 28 L1 L2 0 0 S <INNERDATA>
126 * Where the length of <INNERDATA> is L-3, and S is some kind of subcommand
127 * code. L1 is the least significant bits of L, L2 is the most significant. In
128 * the device's response to a command, the subcommand code will be unchanged.
130 * After deducing and documenting the above, I found a few places where the
131 * above doesn't hold true. Those are marked with FIXME's below.
134 #define CMD_SEQ_INCREMENT 0x10
136 static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev,
137 unsigned char seq_a, unsigned char seq_b, const unsigned char *data,
138 uint16_t len, libusb_transfer_cb_fn callback, void *user_data)
140 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
141 uint16_t crc;
143 /* 9 bytes extra for: 4 byte 'Ciao', 1 byte A, 1 byte B | lenHI,
144 * 1 byte lenLO, 2 byte CRC */
145 size_t urblen = len + 9;
146 unsigned char *buf;
148 if (!transfer)
149 return NULL;
151 if (!data && len > 0) {
152 fp_err("len>0 but no data?");
153 return NULL;
156 buf = g_malloc(urblen);
158 /* Write header */
159 strncpy(buf, "Ciao", 4);
160 len = GUINT16_TO_LE(len);
161 buf[4] = seq_a;
162 buf[5] = seq_b | ((len & 0xf00) >> 8);
163 buf[6] = len & 0x00ff;
165 /* Copy data */
166 if (data)
167 memcpy(buf + 7, data, len);
169 /* Append CRC */
170 crc = GUINT16_TO_BE(udf_crc(buf + 4, urblen - 6));
171 buf[urblen - 2] = crc >> 8;
172 buf[urblen - 1] = crc & 0xff;
174 libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, buf, urblen,
175 callback, user_data, TIMEOUT);
176 return transfer;
179 static struct libusb_transfer *alloc_send_cmd28_transfer(struct fp_dev *dev,
180 unsigned char subcmd, const unsigned char *data, uint16_t innerlen,
181 libusb_transfer_cb_fn callback, void *user_data)
183 uint16_t _innerlen = innerlen;
184 size_t len = innerlen + 6;
185 unsigned char *buf = g_malloc0(len);
186 struct upekts_dev *upekdev = dev->priv;
187 uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT;
188 struct libusb_transfer *ret;
190 fp_dbg("seq=%02x subcmd=%02x with %d bytes of data", seq, subcmd, innerlen);
192 _innerlen = GUINT16_TO_LE(innerlen + 3);
193 buf[0] = 0x28;
194 buf[1] = _innerlen & 0x00ff;
195 buf[2] = (_innerlen & 0xff00) >> 8;
196 buf[5] = subcmd;
197 memcpy(buf + 6, data, innerlen);
199 ret = alloc_send_cmd_transfer(dev, 0, seq, buf, len, callback, user_data);
200 upekdev->seq = seq;
202 g_free(buf);
203 return ret;
206 static struct libusb_transfer *alloc_send_cmdresponse_transfer(
207 struct fp_dev *dev, unsigned char seq, const unsigned char *data,
208 uint8_t len, libusb_transfer_cb_fn callback, void *user_data)
210 fp_dbg("seq=%02x len=%d", seq, len);
211 return alloc_send_cmd_transfer(dev, seq, 0, data, len, callback, user_data);
214 enum read_msg_status {
215 READ_MSG_ERROR,
216 READ_MSG_CMD,
217 READ_MSG_RESPONSE,
220 typedef void (*read_msg_cb_fn)(struct fp_dev *dev, enum read_msg_status status,
221 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
222 void *user_data);
224 struct read_msg_data {
225 struct fp_dev *dev;
226 read_msg_cb_fn callback;
227 void *user_data;
230 static int __read_msg_async(struct read_msg_data *udata);
232 #define READ_MSG_DATA_CB_ERR(udata) (udata)->callback((udata)->dev, \
233 READ_MSG_ERROR, 0, 0, NULL, 0, (udata)->user_data)
235 static void busy_ack_sent_cb(struct libusb_transfer *transfer)
237 struct read_msg_data *udata = transfer->user_data;
239 if (transfer->status != LIBUSB_TRANSFER_COMPLETED ||
240 transfer->length != transfer->actual_length) {
241 READ_MSG_DATA_CB_ERR(udata);
242 g_free(udata);
243 } else {
244 int r = __read_msg_async(udata);
245 if (r < 0) {
246 READ_MSG_DATA_CB_ERR(udata);
247 g_free(udata);
250 libusb_free_transfer(transfer);
253 static int busy_ack_retry_read(struct read_msg_data *udata)
255 struct libusb_transfer *transfer;
256 int r;
258 transfer = alloc_send_cmdresponse_transfer(udata->dev, 0x09, NULL, 0,
259 busy_ack_sent_cb, udata);
260 if (!transfer)
261 return -ENOMEM;
263 r = libusb_submit_transfer(transfer);
264 if (r < 0) {
265 g_free(transfer->buffer);
266 libusb_free_transfer(transfer);
268 return r;
271 /* Returns 0 if message was handled, 1 if it was a device-busy message, and
272 * negative on error. */
273 static int __handle_incoming_msg(struct read_msg_data *udata,
274 unsigned char *buf)
276 uint16_t len = GUINT16_FROM_LE(((buf[5] & 0xf) << 8) | buf[6]);
277 uint16_t computed_crc = udf_crc(buf + 4, len + 3);
278 uint16_t msg_crc = GUINT16_FROM_LE((buf[len + 8] << 8) | buf[len + 7]);
279 unsigned char *retdata = NULL;
280 unsigned char code_a, code_b;
282 if (computed_crc != msg_crc) {
283 fp_err("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
284 return -1;
287 code_a = buf[4];
288 code_b = buf[5] & 0xf0;
289 len = GUINT16_FROM_LE(((buf[5] & 0xf) << 8) | buf[6]);
290 fp_dbg("A=%02x B=%02x len=%d", code_a, code_b, len);
292 if (code_a && !code_b) {
293 /* device sends command to driver */
294 fp_dbg("cmd %x from device to driver", code_a);
296 if (code_a == 0x08) {
297 int r;
298 fp_dbg("device busy, send busy-ack");
299 r = busy_ack_retry_read(udata);
300 return (r < 0) ? r : 1;
303 if (len > 0) {
304 retdata = g_malloc(len);
305 memcpy(retdata, buf + 7, len);
307 udata->callback(udata->dev, READ_MSG_CMD, code_a, 0, retdata, len,
308 udata->user_data);
309 g_free(retdata);
310 } else if (!code_a) {
311 /* device sends response to a previously executed command */
312 unsigned char *innerbuf = buf + 7;
313 unsigned char _subcmd;
314 uint16_t innerlen;
316 if (len < 6) {
317 fp_err("cmd response too short (%d)", len);
318 return -1;
320 if (innerbuf[0] != 0x28) {
321 fp_err("cmd response without 28 byte?");
322 return -1;
325 /* not really sure what these 2 bytes are. on most people's hardware,
326 * these bytes are always 0. However, Alon Bar-Lev's hardware gives
327 * 0xfb 0xff during the READ28_OB initsm stage. so don't error out
328 * if they are different... */
329 if (innerbuf[3] || innerbuf[4])
330 fp_dbg("non-zero bytes in cmd response");
332 innerlen = innerbuf[1] | (innerbuf[2] << 8);
333 innerlen = GUINT16_FROM_LE(innerlen) - 3;
334 _subcmd = innerbuf[5];
335 fp_dbg("device responds to subcmd %x with %d bytes", _subcmd, innerlen);
336 if (innerlen > 0) {
337 retdata = g_malloc(innerlen);
338 memcpy(retdata, innerbuf + 6, innerlen);
340 udata->callback(udata->dev, READ_MSG_RESPONSE, code_b, _subcmd,
341 retdata, innerlen, udata->user_data);
342 g_free(retdata);
343 } else {
344 fp_err("don't know how to handle this message");
345 return -1;
347 return 0;
350 static void read_msg_extend_cb(struct libusb_transfer *transfer)
352 struct read_msg_data *udata = transfer->user_data;
353 unsigned char *buf = transfer->buffer - MSG_READ_BUF_SIZE;
354 int handle_result = 0;
356 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
357 fp_err("extended msg read failed, code %d", transfer->status);
358 goto err;
360 if (transfer->actual_length < transfer->length) {
361 fp_err("extended msg short read (%d/%d)", transfer->actual_length,
362 transfer->length);
363 goto err;
366 handle_result = __handle_incoming_msg(udata, buf);
367 if (handle_result < 0)
368 goto err;
369 goto out;
371 err:
372 READ_MSG_DATA_CB_ERR(udata);
373 out:
374 if (handle_result != 1)
375 g_free(udata);
376 g_free(buf);
377 libusb_free_transfer(transfer);
380 static void read_msg_cb(struct libusb_transfer *transfer)
382 struct read_msg_data *udata = transfer->user_data;
383 unsigned char *data = transfer->buffer;
384 uint16_t len;
385 int handle_result = 0;
387 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
388 fp_err("async msg read failed, code %d", transfer->status);
389 goto err;
391 if (transfer->actual_length < 9) {
392 fp_err("async msg read too short (%d)", transfer->actual_length);
393 goto err;
396 if (strncmp(data, "Ciao", 4) != 0) {
397 fp_err("no Ciao for you!!");
398 goto err;
401 len = GUINT16_FROM_LE(((data[5] & 0xf) << 8) | data[6]);
402 if (transfer->actual_length != MSG_READ_BUF_SIZE
403 && (len + 9) > transfer->actual_length) {
404 /* Check that the length claimed inside the message is in line with
405 * the amount of data that was transferred over USB. */
406 fp_err("msg didn't include enough data, expected=%d recv=%d",
407 len + 9, transfer->actual_length);
408 goto err;
411 /* We use a 64 byte buffer for reading messages. However, sometimes
412 * messages are longer, in which case we have to do another USB bulk read
413 * to read the remainder. This is handled below. */
414 if (len > MAX_DATA_IN_READ_BUF) {
415 int needed = len - MAX_DATA_IN_READ_BUF;
416 struct libusb_transfer *etransfer = libusb_alloc_transfer(0);
417 int r;
419 if (!transfer)
420 goto err;
422 fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed);
423 data = g_realloc((gpointer) data, MSG_READ_BUF_SIZE + needed);
425 libusb_fill_bulk_transfer(etransfer, udata->dev->udev, EP_IN,
426 data + MSG_READ_BUF_SIZE, needed, read_msg_extend_cb, udata,
427 TIMEOUT);
429 r = libusb_submit_transfer(etransfer);
430 if (r < 0) {
431 fp_err("extended read submission failed");
432 /* FIXME memory leak here? */
433 goto err;
435 libusb_free_transfer(transfer);
436 return;
439 handle_result = __handle_incoming_msg(udata, data);
440 if (handle_result < 0)
441 goto err;
442 goto out;
444 err:
445 READ_MSG_DATA_CB_ERR(udata);
446 out:
447 libusb_free_transfer(transfer);
448 if (handle_result != 1)
449 g_free(udata);
450 g_free(data);
453 static int __read_msg_async(struct read_msg_data *udata)
455 unsigned char *buf = g_malloc(MSG_READ_BUF_SIZE);
456 struct libusb_transfer *transfer = libusb_alloc_transfer(0);
457 int r;
459 if (!transfer) {
460 g_free(buf);
461 return -ENOMEM;
464 libusb_fill_bulk_transfer(transfer, udata->dev->udev, EP_IN, buf,
465 MSG_READ_BUF_SIZE, read_msg_cb, udata, TIMEOUT);
466 r = libusb_submit_transfer(transfer);
467 if (r < 0) {
468 g_free(buf);
469 libusb_free_transfer(transfer);
472 return r;
475 static int read_msg_async(struct fp_dev *dev, read_msg_cb_fn callback,
476 void *user_data)
478 struct read_msg_data *udata = g_malloc(sizeof(*udata));
479 int r;
481 udata->dev = dev;
482 udata->callback = callback;
483 udata->user_data = user_data;
484 r = __read_msg_async(udata);
485 if (r)
486 g_free(udata);
487 return r;
490 static const unsigned char init_resp03[] = {
491 0x01, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xff, 0x07
493 static const unsigned char init28_08[] = {
494 0x04, 0x83, 0x00, 0x2c, 0x22, 0x23, 0x97, 0xc9, 0xa7, 0x15, 0xa0, 0x8a,
495 0xab, 0x3c, 0xd0, 0xbf, 0xdb, 0xf3, 0x92, 0x6f, 0xae, 0x3b, 0x1e, 0x44,
496 0xc4
498 static const unsigned char init28_0c[] = {
499 0x04, 0x03, 0x00, 0x00, 0x00
501 static const unsigned char init28_0b[] = {
502 0x04, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
504 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x64, 0x01, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
508 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a,
509 0x00, 0x64, 0x00, 0xf4, 0x01, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00
513 /* device initialisation state machine */
515 enum initsm_states {
516 WRITE_CTRL400 = 0,
517 READ_MSG03,
518 SEND_RESP03,
519 READ_MSG05,
520 SEND28_06,
521 READ28_06,
522 SEND28_07,
523 READ28_07,
524 SEND28_08,
525 READ28_08,
526 SEND28_0C,
527 READ28_0C,
528 SEND28_0B,
529 READ28_0B,
530 INITSM_NUM_STATES,
533 static void initsm_read_msg_response_cb(struct fpi_ssm *ssm,
534 enum read_msg_status status, uint8_t seq,
535 unsigned char expect_subcmd, unsigned char subcmd)
537 struct fp_dev *dev = ssm->dev;
538 struct upekts_dev *upekdev = dev->priv;
540 if (status != READ_MSG_RESPONSE) {
541 fp_err("expected response, got %d seq=%x in state %d", status, seq,
542 ssm->cur_state);
543 fpi_ssm_mark_aborted(ssm, -1);
544 } else if (subcmd != expect_subcmd) {
545 fp_warn("expected response to subcmd 0x%02x, got response to %02x in "
546 "state %d", expect_subcmd, subcmd, ssm->cur_state);
547 fpi_ssm_mark_aborted(ssm, -1);
548 } else if (seq != upekdev->seq) {
549 fp_err("expected response to cmd seq=%02x, got response to %02x "
550 "in state %d", upekdev->seq, seq, ssm->cur_state);
551 fpi_ssm_mark_aborted(ssm, -1);
552 } else {
553 fp_dbg("state %d completed", ssm->cur_state);
554 fpi_ssm_next_state(ssm);
558 static void read28_0b_cb(struct fp_dev *dev, enum read_msg_status status,
559 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
560 void *user_data)
562 initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
563 0x0b, subcmd);
566 static void read28_0c_cb(struct fp_dev *dev, enum read_msg_status status,
567 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
568 void *user_data)
570 initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
571 0x0c, subcmd);
574 static void read28_08_cb(struct fp_dev *dev, enum read_msg_status status,
575 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
576 void *user_data)
578 initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
579 0x08, subcmd);
582 static void read28_07_cb(struct fp_dev *dev, enum read_msg_status status,
583 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
584 void *user_data)
586 initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
587 0x07, subcmd);
590 static void read28_06_cb(struct fp_dev *dev, enum read_msg_status status,
591 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
592 void *user_data)
594 initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq,
595 0x06, subcmd);
598 static void initsm_read_msg_cmd_cb(struct fpi_ssm *ssm,
599 enum read_msg_status status, uint8_t expect_seq, uint8_t seq)
601 struct fp_dev *dev = ssm->dev;
602 struct upekts_dev *upekdev = dev->priv;
604 if (status == READ_MSG_ERROR) {
605 fpi_ssm_mark_aborted(ssm, -1);
606 return;
607 } else if (status != READ_MSG_CMD) {
608 fp_err("expected command, got %d seq=%x in state %d", status, seq,
609 ssm->cur_state);
610 fpi_ssm_mark_aborted(ssm, -1);
611 return;
613 upekdev->seq = seq;
614 if (seq != expect_seq) {
615 fp_err("expected seq=%x, got %x in state %d", expect_seq, seq,
616 ssm->cur_state);
617 fpi_ssm_mark_aborted(ssm, -1);
618 return;
621 fpi_ssm_next_state(ssm);
624 static void read_msg05_cb(struct fp_dev *dev, enum read_msg_status status,
625 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
626 void *user_data)
628 initsm_read_msg_cmd_cb((struct fpi_ssm *) user_data, status, 5, seq);
631 static void read_msg03_cb(struct fp_dev *dev, enum read_msg_status status,
632 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
633 void *user_data)
635 initsm_read_msg_cmd_cb((struct fpi_ssm *) user_data, status, 3, seq);
638 static void ctrl400_cb(struct libusb_transfer *transfer)
640 struct fpi_ssm *ssm = transfer->user_data;
641 /* FIXME check length? */
642 if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
643 fpi_ssm_next_state(ssm);
644 else
645 fpi_ssm_mark_aborted(ssm, -1);
646 g_free(transfer->buffer);
647 libusb_free_transfer(transfer);
650 static void initsm_read_msg_handler(struct fpi_ssm *ssm,
651 read_msg_cb_fn callback)
653 int r = read_msg_async(ssm->dev, callback, ssm);
654 if (r < 0) {
655 fp_err("async read msg failed in state %d", ssm->cur_state);
656 fpi_ssm_mark_aborted(ssm, r);
660 static void initsm_send_msg_cb(struct libusb_transfer *transfer)
662 struct fpi_ssm *ssm = transfer->user_data;
663 if (transfer->status == LIBUSB_TRANSFER_COMPLETED
664 && transfer->length == transfer->actual_length) {
665 fp_dbg("state %d completed", ssm->cur_state);
666 fpi_ssm_next_state(ssm);
667 } else {
668 fp_err("failed, state=%d rqlength=%d actual_length=%d", ssm->cur_state,
669 transfer->length, transfer->actual_length);
670 fpi_ssm_mark_aborted(ssm, -1);
672 libusb_free_transfer(transfer);
675 static void initsm_send_msg28_handler(struct fpi_ssm *ssm,
676 unsigned char subcmd, const unsigned char *data, uint16_t innerlen)
678 struct fp_dev *dev = ssm->dev;
679 struct libusb_transfer *transfer;
680 int r;
682 transfer = alloc_send_cmd28_transfer(dev, subcmd, data, innerlen,
683 initsm_send_msg_cb, ssm);
684 if (!transfer) {
685 fpi_ssm_mark_aborted(ssm, -ENOMEM);
686 return;
689 r = libusb_submit_transfer(transfer);
690 if (r < 0) {
691 fp_err("urb submission failed error %d in state %d", r, ssm->cur_state);
692 g_free(transfer->buffer);
693 libusb_free_transfer(transfer);
694 fpi_ssm_mark_aborted(ssm, -EIO);
698 static void initsm_run_state(struct fpi_ssm *ssm)
700 struct fp_dev *dev = ssm->dev;
701 struct upekts_dev *upekdev = dev->priv;
702 struct libusb_transfer *transfer;
703 int r;
705 switch (ssm->cur_state) {
706 case WRITE_CTRL400: ;
707 unsigned char *data;
709 transfer = libusb_alloc_transfer(0);
710 if (!transfer) {
711 fpi_ssm_mark_aborted(ssm, -ENOMEM);
712 break;
715 data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
716 libusb_fill_control_setup(data,
717 LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1);
718 libusb_fill_control_transfer(transfer, ssm->dev->udev, data,
719 ctrl400_cb, ssm, TIMEOUT);
721 r = libusb_submit_transfer(transfer);
722 if (r < 0) {
723 g_free(data);
724 libusb_free_transfer(transfer);
725 fpi_ssm_mark_aborted(ssm, r);
727 break;
728 case READ_MSG03:
729 initsm_read_msg_handler(ssm, read_msg03_cb);
730 break;
731 case SEND_RESP03: ;
732 transfer = alloc_send_cmdresponse_transfer(dev, ++upekdev->seq,
733 init_resp03, sizeof(init_resp03), initsm_send_msg_cb, ssm);
734 if (!transfer) {
735 fpi_ssm_mark_aborted(ssm, -ENOMEM);
736 break;
739 r = libusb_submit_transfer(transfer);
740 if (r < 0) {
741 g_free(transfer->buffer);
742 libusb_free_transfer(transfer);
743 fpi_ssm_mark_aborted(ssm, r);
745 break;
746 case READ_MSG05:
747 initsm_read_msg_handler(ssm, read_msg05_cb);
748 break;
749 case SEND28_06: ;
750 unsigned char dummy28_06 = 0x04;
751 upekdev->seq = 0xf0;
752 initsm_send_msg28_handler(ssm, 0x06, &dummy28_06, 1);
753 break;
754 case READ28_06:
755 initsm_read_msg_handler(ssm, read28_06_cb);
756 break;
757 case SEND28_07: ;
758 unsigned char dummy28_07 = 0x04;
759 initsm_send_msg28_handler(ssm, 0x07, &dummy28_07, 1);
760 break;
761 case READ28_07:
762 initsm_read_msg_handler(ssm, read28_07_cb);
763 break;
764 case SEND28_08:
765 initsm_send_msg28_handler(ssm, 0x08, init28_08, sizeof(init28_08));
766 break;
767 case READ28_08:
768 initsm_read_msg_handler(ssm, read28_08_cb);
769 break;
770 case SEND28_0C:
771 initsm_send_msg28_handler(ssm, 0x0c, init28_0c, sizeof(init28_0c));
772 break;
773 case READ28_0C:
774 initsm_read_msg_handler(ssm, read28_0c_cb);
775 break;
776 case SEND28_0B:
777 initsm_send_msg28_handler(ssm, 0x0b, init28_0b, sizeof(init28_0b));
778 break;
779 case READ28_0B:
780 initsm_read_msg_handler(ssm, read28_0b_cb);
781 break;
785 static struct fpi_ssm *initsm_new(struct fp_dev *dev)
787 return fpi_ssm_new(dev, initsm_run_state, INITSM_NUM_STATES);
790 enum deinitsm_states {
791 SEND_RESP07 = 0,
792 READ_MSG01,
793 DEINITSM_NUM_STATES,
796 static void send_resp07_cb(struct libusb_transfer *transfer)
798 struct fpi_ssm *ssm = transfer->user_data;
799 if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
800 fpi_ssm_mark_aborted(ssm, -EIO);
801 else if (transfer->length != transfer->actual_length)
802 fpi_ssm_mark_aborted(ssm, -EPROTO);
803 else
804 fpi_ssm_next_state(ssm);
805 libusb_free_transfer(transfer);
808 static void read_msg01_cb(struct fp_dev *dev, enum read_msg_status status,
809 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
810 void *user_data)
812 struct fpi_ssm *ssm = user_data;
813 struct upekts_dev *upekdev = dev->priv;
815 if (status == READ_MSG_ERROR) {
816 fpi_ssm_mark_aborted(ssm, -1);
817 return;
818 } else if (status != READ_MSG_CMD) {
819 fp_err("expected command, got %d seq=%x", status, seq);
820 fpi_ssm_mark_aborted(ssm, -1);
821 return;
823 upekdev->seq = seq;
824 if (seq != 1) {
825 fp_err("expected seq=1, got %x", seq);
826 fpi_ssm_mark_aborted(ssm, -1);
827 return;
830 fpi_ssm_next_state(ssm);
833 static void deinitsm_state_handler(struct fpi_ssm *ssm)
835 struct fp_dev *dev = ssm->dev;
836 int r;
838 switch (ssm->cur_state) {
839 case SEND_RESP07: ;
840 struct libusb_transfer *transfer;
841 unsigned char dummy = 0;
843 transfer = alloc_send_cmdresponse_transfer(dev, 0x07, &dummy, 1,
844 send_resp07_cb, ssm);
845 if (!transfer) {
846 fpi_ssm_mark_aborted(ssm, -ENOMEM);
847 break;
850 r = libusb_submit_transfer(transfer);
851 if (r < 0) {
852 g_free(transfer->buffer);
853 libusb_free_transfer(transfer);
854 fpi_ssm_mark_aborted(ssm, r);
856 break;
857 case READ_MSG01: ;
858 r = read_msg_async(dev, read_msg01_cb, ssm);
859 if (r < 0)
860 fpi_ssm_mark_aborted(ssm, r);
861 break;
865 static struct fpi_ssm *deinitsm_new(struct fp_dev *dev)
867 return fpi_ssm_new(dev, deinitsm_state_handler, DEINITSM_NUM_STATES);
870 static int dev_init(struct fp_dev *dev, unsigned long driver_data)
872 struct upekts_dev *upekdev = NULL;
873 int r;
875 r = libusb_claim_interface(dev->udev, 0);
876 if (r < 0)
877 return r;
879 upekdev = g_malloc(sizeof(*upekdev));
880 upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */
881 dev->priv = upekdev;
882 dev->nr_enroll_stages = 3;
884 fpi_drvcb_open_complete(dev, 0);
885 return 0;
888 static void dev_exit(struct fp_dev *dev)
890 libusb_release_interface(dev->udev, 0);
891 g_free(dev->priv);
892 fpi_drvcb_close_complete(dev);
895 static const unsigned char enroll_init[] = {
896 0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08
898 static const unsigned char scan_comp[] = {
899 0x12, 0xff, 0xff, 0xff, 0xff /* scan completion, prefixes print data */
902 /* used for enrollment and verification */
903 static const unsigned char poll_data[] = { 0x30, 0x01 };
905 enum enroll_start_sm_states {
906 RUN_INITSM = 0,
907 ENROLL_INIT,
908 READ_ENROLL_MSG28,
909 ENROLL_START_NUM_STATES,
912 /* Called when the device initialization state machine completes */
913 static void enroll_start_sm_cb_initsm(struct fpi_ssm *initsm)
915 struct fpi_ssm *enroll_start_ssm = initsm->priv;
916 int error = initsm->error;
918 fpi_ssm_free(initsm);
919 if (error)
920 fpi_ssm_mark_aborted(enroll_start_ssm, error);
921 else
922 fpi_ssm_next_state(enroll_start_ssm);
925 /* called when enroll init URB has completed */
926 static void enroll_start_sm_cb_init(struct libusb_transfer *transfer)
928 struct fpi_ssm *ssm = transfer->user_data;
929 if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
930 fpi_ssm_mark_aborted(ssm, -EIO);
931 else if (transfer->length != transfer->actual_length)
932 fpi_ssm_mark_aborted(ssm, -EPROTO);
933 else
934 fpi_ssm_next_state(ssm);
935 libusb_free_transfer(transfer);
938 static void enroll_start_sm_cb_msg28(struct fp_dev *dev,
939 enum read_msg_status status, uint8_t seq, unsigned char subcmd,
940 unsigned char *data, size_t data_len, void *user_data)
942 struct upekts_dev *upekdev = dev->priv;
943 struct fpi_ssm *ssm = user_data;
945 if (status != READ_MSG_RESPONSE) {
946 fp_err("expected response, got %d seq=%x", status, seq);
947 fpi_ssm_mark_aborted(ssm, -1);
948 } else if (subcmd != 0) {
949 fp_warn("expected response to subcmd 0, got response to %02x",
950 subcmd);
951 fpi_ssm_mark_aborted(ssm, -1);
952 } else if (seq != upekdev->seq) {
953 fp_err("expected response to cmd seq=%02x, got response to %02x",
954 upekdev->seq, seq);
955 fpi_ssm_mark_aborted(ssm, -1);
956 } else {
957 fpi_ssm_next_state(ssm);
961 static void enroll_start_sm_run_state(struct fpi_ssm *ssm)
963 struct fp_dev *dev = ssm->dev;
964 int r;
966 switch (ssm->cur_state) {
967 case RUN_INITSM: ;
968 struct fpi_ssm *initsm = initsm_new(dev);
969 initsm->priv = ssm;
970 fpi_ssm_start(initsm, enroll_start_sm_cb_initsm);
971 break;
972 case ENROLL_INIT: ;
973 struct libusb_transfer *transfer;
974 transfer = alloc_send_cmd28_transfer(dev, 0x02, enroll_init,
975 sizeof(enroll_init), enroll_start_sm_cb_init, ssm);
976 if (!transfer) {
977 fpi_ssm_mark_aborted(ssm, -ENOMEM);
978 break;
981 r = libusb_submit_transfer(transfer);
982 if (r < 0) {
983 g_free(transfer->buffer);
984 libusb_free_transfer(transfer);
985 fpi_ssm_mark_aborted(ssm, r);
987 break;
988 case READ_ENROLL_MSG28: ;
989 /* FIXME: protocol misunderstanding here. device receives response
990 * to subcmd 0 after submitting subcmd 2? */
991 /* actually this is probably a poll response? does the above cmd
992 * include a 30 01 poll somewhere? */
993 r = read_msg_async(dev, enroll_start_sm_cb_msg28, ssm);
994 if (r < 0)
995 fpi_ssm_mark_aborted(ssm, r);
996 break;
1000 static void enroll_iterate(struct fp_dev *dev);
1002 static void e_handle_resp00(struct fp_dev *dev, unsigned char *data,
1003 size_t data_len)
1005 struct upekts_dev *upekdev = dev->priv;
1006 unsigned char status;
1007 int result = 0;
1009 if (data_len != 14) {
1010 fp_err("received 3001 poll response of %d bytes?", data_len);
1011 fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL);
1012 return;
1015 status = data[5];
1016 fp_dbg("poll result = %02x", status);
1018 switch (status) {
1019 case 0x0c:
1020 case 0x0d:
1021 case 0x0e:
1022 /* if we previously completed a non-last enrollment stage, we'll
1023 * get this code to indicate successful stage completion */
1024 if (upekdev->enroll_passed) {
1025 result = FP_ENROLL_PASS;
1026 upekdev->enroll_passed = FALSE;
1028 /* otherwise it just means "no news" so we poll again */
1029 break;
1030 case 0x1c: /* FIXME what does this one mean? */
1031 case 0x0b: /* FIXME what does this one mean? */
1032 case 0x23: /* FIXME what does this one mean? */
1033 result = FP_ENROLL_RETRY;
1034 break;
1035 case 0x0f: /* scan taking too long, remove finger and try again */
1036 result = FP_ENROLL_RETRY_REMOVE_FINGER;
1037 break;
1038 case 0x1e: /* swipe too short */
1039 result = FP_ENROLL_RETRY_TOO_SHORT;
1040 break;
1041 case 0x24: /* finger not centered */
1042 result = FP_ENROLL_RETRY_CENTER_FINGER;
1043 break;
1044 case 0x20:
1045 /* finger scanned successfully */
1046 /* need to look at the next poll result to determine if enrollment is
1047 * complete or not */
1048 upekdev->enroll_passed = 1;
1049 break;
1050 case 0x00: /* enrollment complete */
1051 /* we can now expect the enrollment data on the next poll, so we
1052 * have nothing to do here */
1053 break;
1054 default:
1055 fp_err("unrecognised scan status code %02x", status);
1056 result = -EPROTO;
1057 break;
1060 if (result) {
1061 fpi_drvcb_enroll_stage_completed(dev, result, NULL, NULL);
1062 if (result > 0)
1063 enroll_iterate(dev);
1064 } else {
1065 enroll_iterate(dev);
1068 /* FIXME: need to extend protocol research to handle the case when
1069 * enrolment fails, e.g. you scan a different finger on each stage */
1070 /* FIXME: should do proper tracking of when we expect cmd0 results and
1071 * cmd2 results and enforce it */
1074 static void e_handle_resp02(struct fp_dev *dev, unsigned char *data,
1075 size_t data_len)
1077 struct fp_print_data *fdata = NULL;
1078 int result = -EPROTO;
1080 if (data_len < sizeof(scan_comp)) {
1081 fp_err("fingerprint data too short (%d bytes)", data_len);
1082 } else if (memcmp(data, scan_comp, sizeof(scan_comp)) != 0) {
1083 fp_err("unrecognised data prefix %x %x %x %x %x",
1084 data[0], data[1], data[2], data[3], data[4]);
1085 } else {
1086 fdata = fpi_print_data_new(dev, data_len - sizeof(scan_comp));
1087 memcpy(fdata->data, data + sizeof(scan_comp),
1088 data_len - sizeof(scan_comp));
1090 result = FP_ENROLL_COMPLETE;
1093 fpi_drvcb_enroll_stage_completed(dev, result, fdata, NULL);
1096 static void enroll_iterate_msg_cb(struct fp_dev *dev,
1097 enum read_msg_status msgstat, uint8_t seq, unsigned char subcmd,
1098 unsigned char *data, size_t data_len, void *user_data)
1100 if (msgstat != READ_MSG_RESPONSE) {
1101 fp_err("expected response, got %d seq=%x", msgstat, seq);
1102 fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL);
1103 return;
1105 if (subcmd == 0) {
1106 e_handle_resp00(dev, data, data_len);
1107 } else if (subcmd == 2) {
1108 e_handle_resp02(dev, data, data_len);
1109 } else {
1110 fp_err("unexpected subcmd %d", subcmd);
1111 fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL);
1116 static void enroll_iterate_cmd_cb(struct libusb_transfer *transfer)
1118 struct fp_dev *dev = transfer->user_data;
1120 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
1121 fpi_drvcb_enroll_stage_completed(dev, -EIO, NULL, NULL);
1122 } else if (transfer->length != transfer->actual_length) {
1123 fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL);
1124 } else {
1125 int r = read_msg_async(dev, enroll_iterate_msg_cb, NULL);
1126 if (r < 0)
1127 fpi_drvcb_enroll_stage_completed(dev, r, NULL, NULL);
1129 libusb_free_transfer(transfer);
1132 static void enroll_iterate(struct fp_dev *dev)
1134 int r;
1135 struct libusb_transfer *transfer = alloc_send_cmd28_transfer(dev, 0x00,
1136 poll_data, sizeof(poll_data), enroll_iterate_cmd_cb, dev);
1138 if (!transfer) {
1139 fpi_drvcb_enroll_stage_completed(dev, -ENOMEM, NULL, NULL);
1140 return;
1143 r = libusb_submit_transfer(transfer);
1144 if (r < 0) {
1145 g_free(transfer->buffer);
1146 libusb_free_transfer(transfer);
1147 fpi_drvcb_enroll_stage_completed(dev, -EIO, NULL, NULL);
1151 static void enroll_started(struct fpi_ssm *ssm)
1153 struct fp_dev *dev = ssm->dev;
1154 fpi_drvcb_enroll_started(dev, ssm->error);
1156 if (!ssm->error)
1157 enroll_iterate(dev);
1159 fpi_ssm_free(ssm);
1162 static int enroll_start(struct fp_dev *dev)
1164 struct upekts_dev *upekdev = dev->priv;
1166 /* do_init state machine first */
1167 struct fpi_ssm *ssm = fpi_ssm_new(dev, enroll_start_sm_run_state,
1168 ENROLL_START_NUM_STATES);
1170 upekdev->enroll_passed = FALSE;
1171 fpi_ssm_start(ssm, enroll_started);
1172 return 0;
1175 static void enroll_stop_deinit_cb(struct fpi_ssm *ssm)
1177 /* don't really care about errors */
1178 fpi_drvcb_enroll_stopped(ssm->dev);
1179 fpi_ssm_free(ssm);
1182 static int enroll_stop(struct fp_dev *dev)
1184 struct fpi_ssm *ssm = deinitsm_new(dev);
1185 fpi_ssm_start(ssm, enroll_stop_deinit_cb);
1186 return 0;
1189 static void verify_stop_deinit_cb(struct fpi_ssm *ssm)
1191 /* don't really care about errors */
1192 fpi_drvcb_verify_stopped(ssm->dev);
1193 fpi_ssm_free(ssm);
1196 static void do_verify_stop(struct fp_dev *dev)
1198 struct fpi_ssm *ssm = deinitsm_new(dev);
1199 fpi_ssm_start(ssm, verify_stop_deinit_cb);
1202 static const unsigned char verify_hdr[] = {
1203 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1204 0x00, 0xc0, 0xd4, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
1205 0x00
1208 enum {
1209 VERIFY_RUN_INITSM = 0,
1210 VERIFY_INIT,
1211 VERIFY_NUM_STATES,
1214 /* Called when the device initialization state machine completes */
1215 static void verify_start_sm_cb_initsm(struct fpi_ssm *initsm)
1217 struct fpi_ssm *verify_start_ssm = initsm->priv;
1218 if (initsm->error)
1219 fpi_ssm_mark_aborted(verify_start_ssm, initsm->error);
1220 else
1221 fpi_ssm_next_state(verify_start_ssm);
1222 fpi_ssm_free(initsm);
1225 static void verify_init_2803_cb(struct libusb_transfer *transfer)
1227 struct fpi_ssm *ssm = transfer->user_data;
1228 if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
1229 fpi_ssm_mark_aborted(ssm, -EIO);
1230 else if (transfer->length != transfer->actual_length)
1231 fpi_ssm_mark_aborted(ssm, -EPROTO);
1232 else
1233 fpi_ssm_next_state(ssm);
1234 libusb_free_transfer(transfer);
1237 static void verify_start_sm_run_state(struct fpi_ssm *ssm)
1239 struct fp_dev *dev = ssm->dev;
1240 int r;
1242 switch (ssm->cur_state) {
1243 case VERIFY_RUN_INITSM: ;
1244 struct fpi_ssm *initsm = initsm_new(dev);
1245 initsm->priv = ssm;
1246 fpi_ssm_start(initsm, verify_start_sm_cb_initsm);
1247 break;
1248 case VERIFY_INIT: ;
1249 struct fp_print_data *print = dev->verify_data;
1250 size_t data_len = sizeof(verify_hdr) + print->length;
1251 unsigned char *data = g_malloc(data_len);
1252 struct libusb_transfer *transfer;
1254 memcpy(data, verify_hdr, sizeof(verify_hdr));
1255 memcpy(data + sizeof(verify_hdr), print->data, print->length);
1256 transfer = alloc_send_cmd28_transfer(dev, 0x03, data, data_len,
1257 verify_init_2803_cb, ssm);
1258 g_free(data);
1259 if (!transfer) {
1260 fpi_ssm_mark_aborted(ssm, -ENOMEM);
1261 break;
1264 r = libusb_submit_transfer(transfer);
1265 if (r < 0) {
1266 g_free(transfer->buffer);
1267 libusb_free_transfer(transfer);
1268 fpi_ssm_mark_aborted(ssm, -EIO);
1270 break;
1274 static void verify_iterate(struct fp_dev *dev);
1276 static void v_handle_resp00(struct fp_dev *dev, unsigned char *data,
1277 size_t data_len)
1279 unsigned char status;
1280 int r = 0;
1282 if (data_len != 14) {
1283 fp_err("received 3001 poll response of %d bytes?", data_len);
1284 r = -EPROTO;
1285 goto out;
1288 status = data[5];
1289 fp_dbg("poll result = %02x", status);
1291 /* These codes indicate that we're waiting for a finger scan, so poll
1292 * again */
1293 switch (status) {
1294 case 0x0c: /* no news, poll again */
1295 break;
1296 case 0x20:
1297 fp_dbg("processing scan for verification");
1298 break;
1299 case 0x00:
1300 fp_dbg("good image");
1301 break;
1302 case 0x1c: /* FIXME what does this one mean? */
1303 case 0x0b: /* FIXME what does this one mean? */
1304 case 0x23: /* FIXME what does this one mean? */
1305 r = FP_VERIFY_RETRY;
1306 break;
1307 case 0x0f: /* scan taking too long, remove finger and try again */
1308 r = FP_VERIFY_RETRY_REMOVE_FINGER;
1309 break;
1310 case 0x1e: /* swipe too short */
1311 r = FP_VERIFY_RETRY_TOO_SHORT;
1312 break;
1313 case 0x24: /* finger not centered */
1314 r = FP_VERIFY_RETRY_CENTER_FINGER;
1315 break;
1316 default:
1317 fp_err("unrecognised verify status code %02x", status);
1318 r = -EPROTO;
1321 out:
1322 if (r)
1323 fpi_drvcb_report_verify_result(dev, r, NULL);
1324 if (r >= 0)
1325 verify_iterate(dev);
1328 static void v_handle_resp03(struct fp_dev *dev, unsigned char *data,
1329 size_t data_len)
1331 int r;
1333 if (data_len < 2) {
1334 fp_err("verify result abnormally short!");
1335 r = -EPROTO;
1336 } else if (data[0] != 0x12) {
1337 fp_err("unexpected verify header byte %02x", data[0]);
1338 r = -EPROTO;
1339 } else if (data[1] == 0x00) {
1340 r = FP_VERIFY_NO_MATCH;
1341 } else if (data[1] == 0x01) {
1342 r = FP_VERIFY_MATCH;
1343 } else {
1344 fp_err("unrecognised verify result %02x", data[1]);
1345 r = -EPROTO;
1347 fpi_drvcb_report_verify_result(dev, r, NULL);
1350 static void verify_rd2800_cb(struct fp_dev *dev, enum read_msg_status msgstat,
1351 uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len,
1352 void *user_data)
1354 struct upekts_dev *upekdev = dev->priv;
1356 if (msgstat != READ_MSG_RESPONSE) {
1357 fp_err("expected response, got %d seq=%x", msgstat, seq);
1358 fpi_drvcb_report_verify_result(dev, -EPROTO, NULL);
1359 return;
1360 } else if (seq != upekdev->seq) {
1361 fp_err("expected response to cmd seq=%02x, got response to %02x",
1362 upekdev->seq, seq);
1363 fpi_drvcb_report_verify_result(dev, -EPROTO, NULL);
1364 return;
1367 if (subcmd == 0)
1368 v_handle_resp00(dev, data, data_len);
1369 else if (subcmd == 3)
1370 v_handle_resp03(dev, data, data_len);
1371 else
1372 fpi_drvcb_report_verify_result(dev, -EPROTO, NULL);
1375 static void verify_wr2800_cb(struct libusb_transfer *transfer)
1377 struct fp_dev *dev = transfer->user_data;
1379 if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
1380 fpi_drvcb_report_verify_result(dev, -EIO, NULL);
1381 } else if (transfer->length != transfer->actual_length) {
1382 fpi_drvcb_report_verify_result(dev, -EIO, NULL);
1383 } else {
1384 int r = read_msg_async(dev, verify_rd2800_cb, NULL);
1385 if (r < 0)
1386 fpi_drvcb_report_verify_result(dev, r, NULL);
1388 libusb_free_transfer(transfer);
1391 static void verify_iterate(struct fp_dev *dev)
1393 struct upekts_dev *upekdev = dev->priv;
1395 if (upekdev->stop_verify) {
1396 do_verify_stop(dev);
1397 return;
1400 /* FIXME: this doesn't flow well, should the first cmd be moved from
1401 * verify init to here? */
1402 if (upekdev->first_verify_iteration) {
1403 int r = read_msg_async(dev, verify_rd2800_cb, NULL);
1404 upekdev->first_verify_iteration = FALSE;
1405 if (r < 0)
1406 fpi_drvcb_report_verify_result(dev, r, NULL);
1407 } else {
1408 int r;
1409 struct libusb_transfer *transfer = alloc_send_cmd28_transfer(dev,
1410 0x00, poll_data, sizeof(poll_data), verify_wr2800_cb, dev);
1412 if (!transfer) {
1413 fpi_drvcb_report_verify_result(dev, -ENOMEM, NULL);
1414 return;
1417 r = libusb_submit_transfer(transfer);
1418 if (r < 0) {
1419 g_free(transfer->buffer);
1420 libusb_free_transfer(transfer);
1421 fpi_drvcb_report_verify_result(dev, -EIO, NULL);
1426 static void verify_started(struct fpi_ssm *ssm)
1428 struct fp_dev *dev = ssm->dev;
1429 struct upekts_dev *upekdev = dev->priv;
1431 fpi_drvcb_verify_started(dev, ssm->error);
1432 if (!ssm->error) {
1433 upekdev->first_verify_iteration = TRUE;
1434 verify_iterate(dev);
1437 fpi_ssm_free(ssm);
1440 static int verify_start(struct fp_dev *dev)
1442 struct upekts_dev *upekdev = dev->priv;
1443 struct fpi_ssm *ssm = fpi_ssm_new(dev, verify_start_sm_run_state,
1444 VERIFY_NUM_STATES);
1445 upekdev->stop_verify = FALSE;
1446 fpi_ssm_start(ssm, verify_started);
1447 return 0;
1450 static int verify_stop(struct fp_dev *dev, gboolean iterating)
1452 struct upekts_dev *upekdev = dev->priv;
1454 if (!iterating)
1455 do_verify_stop(dev);
1456 else
1457 upekdev->stop_verify = TRUE;
1458 return 0;
1461 static const struct usb_id id_table[] = {
1462 { .vendor = 0x0483, .product = 0x2016 },
1463 { 0, 0, 0, }, /* terminating entry */
1466 struct fp_driver upekts_driver = {
1467 .id = 1,
1468 .name = FP_COMPONENT,
1469 .full_name = "UPEK TouchStrip",
1470 .id_table = id_table,
1471 .scan_type = FP_SCAN_TYPE_SWIPE,
1472 .open = dev_init,
1473 .close = dev_exit,
1474 .enroll_start = enroll_start,
1475 .enroll_stop = enroll_stop,
1476 .verify_start = verify_start,
1477 .verify_stop = verify_stop,