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
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"
36 #include <fp_internal.h>
38 #define EP_IN (1 | LIBUSB_ENDPOINT_IN)
39 #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT)
42 #define MSG_READ_BUF_SIZE 0x40
43 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
46 gboolean enroll_passed
;
47 gboolean first_verify_iteration
;
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
)
91 crc
= (uint16_t) ((crc
<< 8) ^
92 crc_table
[((crc
>> 8) & 0x00ff) ^ *buffer
++]);
99 * Messages to and from the device have the same format.
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
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);
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;
151 if (!data
&& len
> 0) {
152 fp_err("len>0 but no data?");
156 buf
= g_malloc(urblen
);
159 strncpy(buf
, "Ciao", 4);
160 len
= GUINT16_TO_LE(len
);
162 buf
[5] = seq_b
| ((len
& 0xf00) >> 8);
163 buf
[6] = len
& 0x00ff;
167 memcpy(buf
+ 7, data
, len
);
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
);
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);
194 buf
[1] = _innerlen
& 0x00ff;
195 buf
[2] = (_innerlen
& 0xff00) >> 8;
197 memcpy(buf
+ 6, data
, innerlen
);
199 ret
= alloc_send_cmd_transfer(dev
, 0, seq
, buf
, len
, callback
, user_data
);
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
{
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
,
224 struct read_msg_data
{
226 read_msg_cb_fn callback
;
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
);
244 int r
= __read_msg_async(udata
);
246 READ_MSG_DATA_CB_ERR(udata
);
250 libusb_free_transfer(transfer
);
253 static int busy_ack_retry_read(struct read_msg_data
*udata
)
255 struct libusb_transfer
*transfer
;
258 transfer
= alloc_send_cmdresponse_transfer(udata
->dev
, 0x09, NULL
, 0,
259 busy_ack_sent_cb
, udata
);
263 r
= libusb_submit_transfer(transfer
);
265 g_free(transfer
->buffer
);
266 libusb_free_transfer(transfer
);
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
,
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
);
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) {
298 fp_dbg("device busy, send busy-ack");
299 r
= busy_ack_retry_read(udata
);
300 return (r
< 0) ? r
: 1;
304 retdata
= g_malloc(len
);
305 memcpy(retdata
, buf
+ 7, len
);
307 udata
->callback(udata
->dev
, READ_MSG_CMD
, code_a
, 0, retdata
, len
,
310 } else if (!code_a
) {
311 /* device sends response to a previously executed command */
312 unsigned char *innerbuf
= buf
+ 7;
313 unsigned char _subcmd
;
317 fp_err("cmd response too short (%d)", len
);
320 if (innerbuf
[0] != 0x28) {
321 fp_err("cmd response without 28 byte?");
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
);
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
);
344 fp_err("don't know how to handle this message");
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
);
360 if (transfer
->actual_length
< transfer
->length
) {
361 fp_err("extended msg short read (%d/%d)", transfer
->actual_length
,
366 handle_result
= __handle_incoming_msg(udata
, buf
);
367 if (handle_result
< 0)
372 READ_MSG_DATA_CB_ERR(udata
);
374 if (handle_result
!= 1)
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
;
385 int handle_result
= 0;
387 if (transfer
->status
!= LIBUSB_TRANSFER_COMPLETED
) {
388 fp_err("async msg read failed, code %d", transfer
->status
);
391 if (transfer
->actual_length
< 9) {
392 fp_err("async msg read too short (%d)", transfer
->actual_length
);
396 if (strncmp(data
, "Ciao", 4) != 0) {
397 fp_err("no Ciao for you!!");
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
);
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);
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
,
429 r
= libusb_submit_transfer(etransfer
);
431 fp_err("extended read submission failed");
432 /* FIXME memory leak here? */
435 libusb_free_transfer(transfer
);
439 handle_result
= __handle_incoming_msg(udata
, data
);
440 if (handle_result
< 0)
445 READ_MSG_DATA_CB_ERR(udata
);
447 libusb_free_transfer(transfer
);
448 if (handle_result
!= 1)
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);
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
);
469 libusb_free_transfer(transfer
);
475 static int read_msg_async(struct fp_dev
*dev
, read_msg_cb_fn callback
,
478 struct read_msg_data
*udata
= g_malloc(sizeof(*udata
));
482 udata
->callback
= callback
;
483 udata
->user_data
= user_data
;
484 r
= __read_msg_async(udata
);
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,
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 */
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
,
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);
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
,
562 initsm_read_msg_response_cb((struct fpi_ssm
*) user_data
, status
, seq
,
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
,
570 initsm_read_msg_response_cb((struct fpi_ssm
*) user_data
, status
, seq
,
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
,
578 initsm_read_msg_response_cb((struct fpi_ssm
*) user_data
, status
, seq
,
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
,
586 initsm_read_msg_response_cb((struct fpi_ssm
*) user_data
, status
, seq
,
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
,
594 initsm_read_msg_response_cb((struct fpi_ssm
*) user_data
, status
, seq
,
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);
607 } else if (status
!= READ_MSG_CMD
) {
608 fp_err("expected command, got %d seq=%x in state %d", status
, seq
,
610 fpi_ssm_mark_aborted(ssm
, -1);
614 if (seq
!= expect_seq
) {
615 fp_err("expected seq=%x, got %x in state %d", expect_seq
, seq
,
617 fpi_ssm_mark_aborted(ssm
, -1);
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
,
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
,
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
);
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
);
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
);
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
;
682 transfer
= alloc_send_cmd28_transfer(dev
, subcmd
, data
, innerlen
,
683 initsm_send_msg_cb
, ssm
);
685 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
689 r
= libusb_submit_transfer(transfer
);
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
;
705 switch (ssm
->cur_state
) {
706 case WRITE_CTRL400
: ;
709 transfer
= libusb_alloc_transfer(0);
711 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
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
);
724 libusb_free_transfer(transfer
);
725 fpi_ssm_mark_aborted(ssm
, r
);
729 initsm_read_msg_handler(ssm
, read_msg03_cb
);
732 transfer
= alloc_send_cmdresponse_transfer(dev
, ++upekdev
->seq
,
733 init_resp03
, sizeof(init_resp03
), initsm_send_msg_cb
, ssm
);
735 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
739 r
= libusb_submit_transfer(transfer
);
741 g_free(transfer
->buffer
);
742 libusb_free_transfer(transfer
);
743 fpi_ssm_mark_aborted(ssm
, r
);
747 initsm_read_msg_handler(ssm
, read_msg05_cb
);
750 unsigned char dummy28_06
= 0x04;
752 initsm_send_msg28_handler(ssm
, 0x06, &dummy28_06
, 1);
755 initsm_read_msg_handler(ssm
, read28_06_cb
);
758 unsigned char dummy28_07
= 0x04;
759 initsm_send_msg28_handler(ssm
, 0x07, &dummy28_07
, 1);
762 initsm_read_msg_handler(ssm
, read28_07_cb
);
765 initsm_send_msg28_handler(ssm
, 0x08, init28_08
, sizeof(init28_08
));
768 initsm_read_msg_handler(ssm
, read28_08_cb
);
771 initsm_send_msg28_handler(ssm
, 0x0c, init28_0c
, sizeof(init28_0c
));
774 initsm_read_msg_handler(ssm
, read28_0c_cb
);
777 initsm_send_msg28_handler(ssm
, 0x0b, init28_0b
, sizeof(init28_0b
));
780 initsm_read_msg_handler(ssm
, read28_0b_cb
);
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
{
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
);
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
,
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);
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);
825 fp_err("expected seq=1, got %x", seq
);
826 fpi_ssm_mark_aborted(ssm
, -1);
830 fpi_ssm_next_state(ssm
);
833 static void deinitsm_state_handler(struct fpi_ssm
*ssm
)
835 struct fp_dev
*dev
= ssm
->dev
;
838 switch (ssm
->cur_state
) {
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
);
846 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
850 r
= libusb_submit_transfer(transfer
);
852 g_free(transfer
->buffer
);
853 libusb_free_transfer(transfer
);
854 fpi_ssm_mark_aborted(ssm
, r
);
858 r
= read_msg_async(dev
, read_msg01_cb
, ssm
);
860 fpi_ssm_mark_aborted(ssm
, r
);
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
;
875 r
= libusb_claim_interface(dev
->udev
, 0);
879 upekdev
= g_malloc(sizeof(*upekdev
));
880 upekdev
->seq
= 0xf0; /* incremented to 0x00 before first cmd */
882 dev
->nr_enroll_stages
= 3;
884 fpi_drvcb_open_complete(dev
, 0);
888 static void dev_exit(struct fp_dev
*dev
)
890 libusb_release_interface(dev
->udev
, 0);
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
{
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
);
920 fpi_ssm_mark_aborted(enroll_start_ssm
, error
);
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
);
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",
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",
955 fpi_ssm_mark_aborted(ssm
, -1);
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
;
966 switch (ssm
->cur_state
) {
968 struct fpi_ssm
*initsm
= initsm_new(dev
);
970 fpi_ssm_start(initsm
, enroll_start_sm_cb_initsm
);
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
);
977 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
981 r
= libusb_submit_transfer(transfer
);
983 g_free(transfer
->buffer
);
984 libusb_free_transfer(transfer
);
985 fpi_ssm_mark_aborted(ssm
, r
);
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
);
995 fpi_ssm_mark_aborted(ssm
, r
);
1000 static void enroll_iterate(struct fp_dev
*dev
);
1002 static void e_handle_resp00(struct fp_dev
*dev
, unsigned char *data
,
1005 struct upekts_dev
*upekdev
= dev
->priv
;
1006 unsigned char status
;
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
);
1016 fp_dbg("poll result = %02x", status
);
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 */
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
;
1035 case 0x0f: /* scan taking too long, remove finger and try again */
1036 result
= FP_ENROLL_RETRY_REMOVE_FINGER
;
1038 case 0x1e: /* swipe too short */
1039 result
= FP_ENROLL_RETRY_TOO_SHORT
;
1041 case 0x24: /* finger not centered */
1042 result
= FP_ENROLL_RETRY_CENTER_FINGER
;
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;
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 */
1055 fp_err("unrecognised scan status code %02x", status
);
1061 fpi_drvcb_enroll_stage_completed(dev
, result
, NULL
, NULL
);
1063 enroll_iterate(dev
);
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
,
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]);
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
);
1106 e_handle_resp00(dev
, data
, data_len
);
1107 } else if (subcmd
== 2) {
1108 e_handle_resp02(dev
, data
, data_len
);
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
);
1125 int r
= read_msg_async(dev
, enroll_iterate_msg_cb
, NULL
);
1127 fpi_drvcb_enroll_stage_completed(dev
, r
, NULL
, NULL
);
1129 libusb_free_transfer(transfer
);
1132 static void enroll_iterate(struct fp_dev
*dev
)
1135 struct libusb_transfer
*transfer
= alloc_send_cmd28_transfer(dev
, 0x00,
1136 poll_data
, sizeof(poll_data
), enroll_iterate_cmd_cb
, dev
);
1139 fpi_drvcb_enroll_stage_completed(dev
, -ENOMEM
, NULL
, NULL
);
1143 r
= libusb_submit_transfer(transfer
);
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
);
1157 enroll_iterate(dev
);
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
);
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
);
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
);
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
);
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,
1209 VERIFY_RUN_INITSM
= 0,
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
;
1219 fpi_ssm_mark_aborted(verify_start_ssm
, initsm
->error
);
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
);
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
;
1242 switch (ssm
->cur_state
) {
1243 case VERIFY_RUN_INITSM
: ;
1244 struct fpi_ssm
*initsm
= initsm_new(dev
);
1246 fpi_ssm_start(initsm
, verify_start_sm_cb_initsm
);
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
);
1260 fpi_ssm_mark_aborted(ssm
, -ENOMEM
);
1264 r
= libusb_submit_transfer(transfer
);
1266 g_free(transfer
->buffer
);
1267 libusb_free_transfer(transfer
);
1268 fpi_ssm_mark_aborted(ssm
, -EIO
);
1274 static void verify_iterate(struct fp_dev
*dev
);
1276 static void v_handle_resp00(struct fp_dev
*dev
, unsigned char *data
,
1279 unsigned char status
;
1282 if (data_len
!= 14) {
1283 fp_err("received 3001 poll response of %d bytes?", data_len
);
1289 fp_dbg("poll result = %02x", status
);
1291 /* These codes indicate that we're waiting for a finger scan, so poll
1294 case 0x0c: /* no news, poll again */
1297 fp_dbg("processing scan for verification");
1300 fp_dbg("good image");
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
;
1307 case 0x0f: /* scan taking too long, remove finger and try again */
1308 r
= FP_VERIFY_RETRY_REMOVE_FINGER
;
1310 case 0x1e: /* swipe too short */
1311 r
= FP_VERIFY_RETRY_TOO_SHORT
;
1313 case 0x24: /* finger not centered */
1314 r
= FP_VERIFY_RETRY_CENTER_FINGER
;
1317 fp_err("unrecognised verify status code %02x", status
);
1323 fpi_drvcb_report_verify_result(dev
, r
, NULL
);
1325 verify_iterate(dev
);
1328 static void v_handle_resp03(struct fp_dev
*dev
, unsigned char *data
,
1334 fp_err("verify result abnormally short!");
1336 } else if (data
[0] != 0x12) {
1337 fp_err("unexpected verify header byte %02x", data
[0]);
1339 } else if (data
[1] == 0x00) {
1340 r
= FP_VERIFY_NO_MATCH
;
1341 } else if (data
[1] == 0x01) {
1342 r
= FP_VERIFY_MATCH
;
1344 fp_err("unrecognised verify result %02x", data
[1]);
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
,
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
);
1360 } else if (seq
!= upekdev
->seq
) {
1361 fp_err("expected response to cmd seq=%02x, got response to %02x",
1363 fpi_drvcb_report_verify_result(dev
, -EPROTO
, NULL
);
1368 v_handle_resp00(dev
, data
, data_len
);
1369 else if (subcmd
== 3)
1370 v_handle_resp03(dev
, data
, data_len
);
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
);
1384 int r
= read_msg_async(dev
, verify_rd2800_cb
, NULL
);
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
);
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
;
1406 fpi_drvcb_report_verify_result(dev
, r
, NULL
);
1409 struct libusb_transfer
*transfer
= alloc_send_cmd28_transfer(dev
,
1410 0x00, poll_data
, sizeof(poll_data
), verify_wr2800_cb
, dev
);
1413 fpi_drvcb_report_verify_result(dev
, -ENOMEM
, NULL
);
1417 r
= libusb_submit_transfer(transfer
);
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
);
1433 upekdev
->first_verify_iteration
= TRUE
;
1434 verify_iterate(dev
);
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
,
1445 upekdev
->stop_verify
= FALSE
;
1446 fpi_ssm_start(ssm
, verify_started
);
1450 static int verify_stop(struct fp_dev
*dev
, gboolean iterating
)
1452 struct upekts_dev
*upekdev
= dev
->priv
;
1455 do_verify_stop(dev
);
1457 upekdev
->stop_verify
= TRUE
;
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
= {
1468 .name
= FP_COMPONENT
,
1469 .full_name
= "UPEK TouchStrip",
1470 .id_table
= id_table
,
1471 .scan_type
= FP_SCAN_TYPE_SWIPE
,
1474 .enroll_start
= enroll_start
,
1475 .enroll_stop
= enroll_stop
,
1476 .verify_start
= verify_start
,
1477 .verify_stop
= verify_stop
,