summaryrefslogtreecommitdiff
path: root/libfprint
diff options
context:
space:
mode:
authorVasily Khoruzhick <anarsoul@gmail.com>2012-11-10 18:22:32 +0300
committerBastien Nocera <hadess@hadess.net>2012-11-16 17:56:51 +0100
commited2c75842a4542b0dbd9e4f188a40057bb537ea6 (patch)
tree9e56c1d2cbca161c20399723977cca2abca8fddf /libfprint
parentb307dd1a6abef8f87062d35dcbe2f2c22b959638 (diff)
upektc: Port to asynchronous model
https://bugs.freedesktop.org/show_bug.cgi?id=56955
Diffstat (limited to 'libfprint')
-rw-r--r--libfprint/Makefile.am6
-rw-r--r--libfprint/core.c4
-rw-r--r--libfprint/drivers/upektc.c662
-rw-r--r--libfprint/drivers/upektc.h737
4 files changed, 1097 insertions, 312 deletions
diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am
index 5ecf062..7c5f182 100644
--- a/libfprint/Makefile.am
+++ b/libfprint/Makefile.am
@@ -102,9 +102,9 @@ if ENABLE_UPEKSONLY
DRIVER_SRC += $(UPEKSONLY_SRC)
endif
-#if ENABLE_UPEKTC
-#DRIVER_SRC += $(UPEKTC_SRC)
-#endif
+if ENABLE_UPEKTC
+DRIVER_SRC += $(UPEKTC_SRC)
+endif
if ENABLE_URU4000
DRIVER_SRC += $(URU4000_SRC)
diff --git a/libfprint/core.c b/libfprint/core.c
index 9916faa..01a9cfa 100644
--- a/libfprint/core.c
+++ b/libfprint/core.c
@@ -377,10 +377,10 @@ static struct fp_img_driver * const img_drivers[] = {
#ifdef ENABLE_VFS301
&vfs301_driver,
#endif
-/*#ifdef ENABLE_UPEKTC
+#ifdef ENABLE_UPEKTC
&upektc_driver,
#endif
-#ifdef ENABLE_FDU2000
+/*#ifdef ENABLE_FDU2000
&fdu2000_driver,
#endif
*/
diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c
index e115537..f361051 100644
--- a/libfprint/drivers/upektc.c
+++ b/libfprint/drivers/upektc.c
@@ -1,6 +1,7 @@
/*
* UPEK TouchChip driver for libfprint
* Copyright (C) 2007 Jan-Michael Brummer <buzz2@gmx.de>
+ * Copyright (C) 2012 Vasily Khoruzhick <anarsoul@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,378 +18,425 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define FP_COMPONENT "upektc"
+#define FP_COMPONENT "upektc"
#include <errno.h>
#include <string.h>
-
-#include <glib.h>
#include <libusb.h>
-
#include <fp_internal.h>
+#include "upektc.h"
-#define SENSOR_FULL_IMAGE 59904
-#define WAIT_COUNT 5
-
-typedef char sint8;
-typedef unsigned char uint8;
-typedef int sint32;
-typedef unsigned int uint32;
-
-/** scan command */
-static const unsigned char anScanCommand[ 0x40 ] = {
- 0x0e, 0x00, 0x03, 0xa8, 0x00, 0xb6, 0xbb, 0xbb,
- 0xb8, 0xb7, 0xb8, 0xb5, 0xb8, 0xb9, 0xb8, 0xb9,
- 0xbb, 0xbb, 0xbe, 0xbb, 0x4e, 0x16, 0xf4, 0x77,
- 0xa8, 0x07, 0x32, 0x00, 0x6a, 0x16, 0xf4, 0x77,
- 0x78, 0x24, 0x61, 0x00, 0xc8, 0x00, 0xec, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x3c, 0xf3, 0x2f, 0x01,
- 0x05, 0x90, 0xf6, 0x77, 0x84, 0xf5, 0x2f, 0x01,
- 0x05, 0x90, 0xf6, 0x00, 0xc8, 0x00, 0xec, 0x00
+#define EP_IN (2 | LIBUSB_ENDPOINT_IN)
+#define EP_OUT (3 | LIBUSB_ENDPOINT_OUT)
+#define BULK_TIMEOUT 4000
+
+struct upektc_dev {
+ gboolean deactivating;
+ int init_idx;
};
-/** init command */
-static const unsigned char anInitCommand[ 0x40 ] = {
- 0x03, 0x00, 0x00, 0x00, 0x02, 0xfb, 0x0f, 0x00,
- 0xc4, 0xf9, 0x2f, 0x01, 0x6d, 0x4f, 0x01, 0x10,
- 0x44, 0xf9, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00,
- 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static void start_capture(struct fp_img_dev *dev);
+static void complete_deactivation(struct fp_img_dev *dev);
+static void start_finger_detection(struct fp_img_dev *dev);
+
+/****** INITIALIZATION/DEINITIALIZATION ******/
+
+enum activate_states {
+ WRITE_INIT,
+ READ_DATA,
+ ACTIVATE_NUM_STATES,
};
-/**
- * \brief Common interaktion routine for the sensor device
- * \param dev fingerprint image device pointer
- * \param pnRawString raw data string
- * \param nLen length we want to read, if 0 do not read at all
- * \param pnBuffer buffer pointer we want to store the read buffer
- * \return error code
- */
-static sint32 askScanner( struct fp_img_dev *dev, const unsigned char *pnRawString, sint32 nLen, sint8 *pnBuffer ) {
- sint8 anBuf[ 65535 ];
- sint32 nRet;
- int transferred;
- struct libusb_bulk_transfer msg1 = {
- .endpoint = 3,
- .data = pnRawString,
- .length = 0x40,
- };
- struct libusb_bulk_transfer msg2 = {
- .endpoint = 0x82,
- .data = anBuf,
- .length = nLen,
- };
+static void upektc_next_init_cmd(struct fpi_ssm *ssm)
+{
+ struct fp_img_dev *dev = ssm->priv;
+ struct upektc_dev *upekdev = dev->priv;
- nRet = libusb_bulk_transfer(dev->udev, &msg1, &transferred, 1003);
- if (transferred != 0x40) {
- return -1;
- }
+ upekdev->init_idx += 1;
+ if (upekdev->init_idx == array_n_elements(setup_commands))
+ fpi_ssm_mark_completed(ssm);
+ else
+ fpi_ssm_jump_to_state(ssm, WRITE_INIT);
+}
- if ( !nLen ) {
- return 0;
+static void write_init_cb(struct libusb_transfer *transfer)
+{
+ struct fpi_ssm *ssm = transfer->user_data;
+ struct fp_img_dev *dev = ssm->priv;
+ struct upektc_dev *upekdev = dev->priv;
+
+ if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
+ (transfer->length == transfer->actual_length)) {
+ if (setup_commands[upekdev->init_idx].response_len)
+ fpi_ssm_next_state(ssm);
+ else
+ upektc_next_init_cmd(ssm);
+ } else {
+ fpi_ssm_mark_aborted(ssm, -EIO);
}
+ libusb_free_transfer(transfer);
+}
- nRet = libusb_bulk_transfer(dev->udev, &msg2, &transferred, 1003);
- if ( ( transferred == nLen ) && ( pnBuffer != NULL ) ) {
- memcpy( pnBuffer, anBuf, nLen );
- return transferred;
- }
+static void read_init_data_cb(struct libusb_transfer *transfer)
+{
+ struct fpi_ssm *ssm = transfer->user_data;
- return nRet;
+ if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
+ upektc_next_init_cmd(ssm);
+ else
+ fpi_ssm_mark_aborted(ssm, -EIO);
+ g_free(transfer->buffer);
+ libusb_free_transfer(transfer);
}
-/**
- * \brief Quick test if finger is on sensor
- * \param pnImage image pointer
- * \return 1 on yes, 0 on no
- */
-static sint32 ValidScan( sint8 *pnImage ) {
- sint32 nIndex, nSum;
+static void activate_run_state(struct fpi_ssm *ssm)
+{
+ struct fp_img_dev *dev = ssm->priv;
+ struct upektc_dev *upekdev = dev->priv;
+ int r;
+
+ switch (ssm->cur_state) {
+ case WRITE_INIT:
+ {
+ struct libusb_transfer *transfer = libusb_alloc_transfer(0);
+ if (!transfer) {
+ fpi_ssm_mark_aborted(ssm, -ENOMEM);
+ return;
+ }
+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT,
+ (unsigned char*)setup_commands[upekdev->init_idx].cmd,
+ UPEKTC_CMD_LEN, write_init_cb, ssm, BULK_TIMEOUT);
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ libusb_free_transfer(transfer);
+ fpi_ssm_mark_aborted(ssm, -ENOMEM);
+ }
+ }
+ break;
+ case READ_DATA:
+ {
+ struct libusb_transfer *transfer = libusb_alloc_transfer(0);
+ unsigned char *data;
+
+ if (!transfer) {
+ fpi_ssm_mark_aborted(ssm, -ENOMEM);
+ break;
+ }
- nSum = 0;
+ data = g_malloc(setup_commands[upekdev->init_idx].response_len);
+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data,
+ setup_commands[upekdev->init_idx].response_len,
+ read_init_data_cb, ssm, BULK_TIMEOUT);
- for ( nIndex = 0; nIndex < SENSOR_FULL_IMAGE; nIndex++ ) {
- if ( ( uint8 ) pnImage[ nIndex ] < 160 ) {
- nSum++;
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ g_free(data);
+ libusb_free_transfer(transfer);
+ fpi_ssm_mark_aborted(ssm, r);
}
}
-
- return nSum < 500 ? 0 : 1;
+ break;
+ }
}
-/**
- * \brief Setup Sensor device
- * \param dev fingerprint image device pointer
- * \return error code
- */
-static sint32 SetupSensor( struct fp_img_dev *dev ) {
- libusb_claim_interface(dev->udev, 0);
-
- /* setup sensor */
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\xfe\x00\x01\xc0\xbd\xf0\xff\xff\xff\xff\xff\x00\xf0\xfd\x7f\x00\x60\xfd\x7f\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\xcc\xf8\x2f\x01\x09\x48\xe7\x77\xf0\xfa\x2f\x01\x09\x48\xe7\x77\xe0\x3a\xe6\x77", 0x00, NULL ) < 0 ) {
- return -1;
- }
+static void activate_sm_complete(struct fpi_ssm *ssm)
+{
+ struct fp_img_dev *dev = ssm->priv;
+ fp_dbg("status %d", ssm->error);
+ fpi_imgdev_activate_complete(dev, ssm->error);
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf7\x00\x00\xc8\x01\x00\x00\x40\x00\x00\x00\x01\x00\x00\x00\x58\xf9\x2f\x01\xe9\x4f\x01\x10\xd8\xf8\x2f\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x02\xfe\x00\x01\xc0\xbd\xf0\xff\xff\xff\xff\xff\x00\xf0\xfd\x7f", 0x40, NULL ) < 0 ) {
- return -2;
- };
+ if (!ssm->error)
+ start_finger_detection(dev);
+ fpi_ssm_free(ssm);
+}
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\xf7\xcd\x00\x2c\xf9\x2f\x01\x6d\x4f\x01\x10\xac\xf8\x2f\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x02\xfe\x16\x10\x03\xee\x00\x37\x01\x09\x02\x0e\x03\x18\x03\x1a\x03\x20\x10\x2f\x11\x3f\x12\x44\x01\x01\x07\x08\x0c\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -3;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf8\x00\x00\x02\xfe\x16\x10\x03\xee\x00\x37\x01\x09\x02\x0e\x03\x18\x03\x1a\x03\x20\x10\x2f\x11\x3f\x12\x44\x01\x01\x07\x08\x0c\x00\x6c\x6c\x00\xf9\x2f\x01\x97\x40\x01\x10\x03\x00\x00\x00\x00\x00\x00\x00\xfa\x45\x03\x10\x02\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -4;
- };
- if ( askScanner( dev, "\x8b\x00\x00\x00\x3a\x50\xf9\x2f\x01\x18\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x88\xf9\x2f\x01\x91\x99\x00\x10\xf8\x00\x00\x00\xbe\x99\x00\x10\xa0\xa6\x04\x10\x01\x9b\x00\x10\x18\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x00\x00", 0x40, NULL ) < 0 ) {
- return -5;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x3a\x00\x01\x02\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3d\x3f\xff\x00", 0x40, NULL ) < 0 ) {
- return -6;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x3a\x00\x01\x02\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3d\x3f\xff\x00", 0x40, NULL ) < 0 ) {
- return -7;
- };
+/****** FINGER PRESENCE DETECTION ******/
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\x0d\xff\x36\xdc\xf8\x2f\x01\xf1\x9d\x00\x10\xfc\xf8\x2f\x01\x9d\xf8\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x9e\xbf\x85\x85\x02\x05\x26\x25\x4d\x13\x10\x00\x00\x00\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -8;
- };
- if ( askScanner( dev, "\x03\x00\x00\x00\x0c\x37\x6a\x3d\x73\x3d\x71\x0e\x01\x0e\x81\x3d\x51\xf8\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x9e\xbf\x85\x85\x02\x05\x26\x25\x4d\x13\x10\x00\x00\x00\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\xf0\xf8\x2f\x01", 0x00, NULL ) < 0 ) {
- return -9;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x3a\x00\x01\x02\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3d\x3f\xff\x00", 0x40, NULL ) < 0 ) {
- return -10;
- };
+static int finger_present(unsigned char *img, size_t len)
+{
+ int i, sum;
- if ( askScanner( dev, "\x8b\x00\x01\x7c\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x14\xf5\x2f\x01\xa0\x20\x14\x00\x40\xf8\x2f\x01\x05\x90\xf6\x77\x04\x00\x00\x00\x08\x00\x00\x00\x50\xf8\x2f\x01\x40\x39\xf4\x77\xa8\x20\x14\x00\x1c\xf6\x2f\x01\x2c\x20\xf4\x77\x80\x4d\xfb\x77", 0x40, NULL ) < 0 ) {
- return -11;
- };
- if ( askScanner( dev, "\x8b\x00\x03\xc8\x3a\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\x6c\x6c\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x6c\x00\x00\x00\x00\x00\x60\x62\x62\x62\x62\x62\x51\x6c\x00\x00\x00\x00\x00\x00\x40\xf9\x2f\x01\x4f\x9d\x00\x10\x3a\x00\x00\x00\x04\xf9\x01", 0x40, NULL ) < 0 ) {
- return -12;
- };
- if ( askScanner( dev, "\x8b\x00\x04\x02\x06\x0b\x07\x13\x0e\x55\x56\x01\x44\xf8\x2f\x01\x00\x00\x00\x00\x40\x00\x00\x00\x40\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x01\x00\x00\xc8\x01\x00\x00\x40\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -13;
- };
+ sum = 0;
- if ( askScanner( dev, "\x07\x00\x20\x00\x3a\x0e\x13\x07\x0f\x14\x07\x10\x15\x07\x12\x16\x07\x13\x17\x07\x14\x18\x07\x15\x18\x07\x16\x19\x07\x17\x1a\x07\x19\x1b\x07\x1a\x1c\x07\x1b\x1d\x07\x1c\x1e\x07\x1d\x1f\x07\x1e\x20\x07\x1f\x21\x07\x20\x22\x07\x21\x23\x07\x23\x23\x07\x24\x55", 0x00, NULL ) < 0 ) {
- return -14;
- };
- if ( askScanner( dev, "\x07\x00\x20\x3a\x26\x24\x07\x25\x25\x07\x26\x25\x07\x27\x26\x07\x28\x27\x07\x29\x27\x07\x2a\x28\x07\x2b\x29\x07\x2d\x29\x07\x2e\x2a\x07\x2f\x2b\x07\x30\x2b\x07\x31\x2c\x07\x07\x1d\x1f\x07\x1e\x20\x07\x1f\x21\x07\x20\x22\x07\x21\x23\x07\x23\x23\x07\x24\x55", 0x00, NULL ) < 0 ) {
- return -15;
- };
+ for (i = 0; i < len; i++) {
+ if (img[i] < 160) {
+ sum++;
+ }
+ }
- if ( askScanner( dev, "\x03\x00\x00\x00\x06\x0e\x81\x0e\x81\x09\x4d\x00\x07\x00\x20\x3a\x26\x24\x07\x25\x25\x07\x26\x25\x07\x27\x26\x07\x28\x27\x07\x29\x27\x07\x2a\x28\x07\x2b\x29\x07\x2d\x29\x07\x2e\x2a\x07\x2f\x2b\x07\x30\x2b\x07\x31\x2c\x07\x07\x1d\x1f\x07\x1e\x20\x07\x1f\x21", 0x00, NULL ) < 0 ) {
- return -16;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x3a\x00\x01\x02\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3d\x3f\xff\x00", 0x40, NULL ) < 0 ) {
- return -17;
- };
+ fp_dbg("finger_present: sum is %d\n", sum);
+ return sum < SUM_THRESHOLD ? 0 : 1;
+}
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\x0e\x85\x36\xd8\xf8\x2f\x01\xf1\x9d\x00\x10\xf8\xf8\x2f\x01\x99\xf8\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x9e\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -18;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\x0d\x00\x00\x02\x9e\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\xec\xf8\x2f\x01\x97\x40\x01\x10\x03\x00\x00\x00\x00\x00\x00\x00\xfa\x45\x03\x10\x02\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -19;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf7\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\x6c\x6c\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x6c\x00\x00\x00\x00\x00\x60\x62\x62\x62\x62\x62\x51\x6c\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -20;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf7\x00\x00\x02\xf9\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\x6c\x6c\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x6c\x00\x00\x00\x00\x00\x60\x62\x62\x62\x62\x62", 0x40, NULL ) < 0 ) {
- return -21;
- };
+static void finger_det_data_cb(struct libusb_transfer *transfer)
+{
+ struct fp_img_dev *dev = transfer->user_data;
+ unsigned char *data = transfer->buffer;
+
+ if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
+ fp_dbg("data transfer status %d\n", transfer->status);
+ fpi_imgdev_session_error(dev, -EIO);
+ goto out;
+ } else if (transfer->length != transfer->actual_length) {
+ fp_dbg("expected %d, got %d bytes", transfer->length,
+ transfer->actual_length);
+ fpi_imgdev_session_error(dev, -EPROTO);
+ }
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\xf7\xf4\x00\x14\xf9\x2f\x01\x6d\x4f\x01\x10\x94\xf8\x2f\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x02\xf9\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -22;
- };
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\x20\x6c\x01\x6d\x4f\x01\x10\x94\xf8\x2f\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x02\xf9\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\xe8\xf8\x2f\x01", 0x00, NULL ) < 0 ) {
- return -23;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf9\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c\xe8\xf8\x2f\x01\xec\xf8\x2f\x01\x97\x40\x01\x10\x03\x00\x00\x00\x00\x00\x00\x00\xfa\x45\x03\x10\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -24;
- };
+ if (finger_present(data, IMAGE_SIZE)) {
+ /* finger present, start capturing */
+ fpi_imgdev_report_finger_status(dev, TRUE);
+ start_capture(dev);
+ } else {
+ /* no finger, poll for a new histogram */
+ start_finger_detection(dev);
+ }
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\xf9\x01\x00\x1c\xf9\x2f\x01\x6d\x4f\x01\x10\x9c\xf8\x2f\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x02\x6c\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09\x0f\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -25;
- };
- if ( askScanner( dev, "\x03\x00\x00\x00\x12\x1c\x0c\x1b\x08\x1a\x07\x30\x08\x09\x6d\x08\x27\x00\x9e\x00\x1e\x23\x47\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x02\x6c\xbf\x85\x85\x02\x05\x26\x25\x4d\x10\x10\x00\xff\x81\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x09\x09", 0x00, NULL ) < 0 ) {
- return -26;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x3a\x00\x01\x02\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3d\x3f\xff\x00", 0x40, NULL ) < 0 ) {
- return -27;
- };
+out:
+ g_free(data);
+ libusb_free_transfer(transfer);
+}
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\x0d\xff\x36\xdc\xf8\x2f\x01\xf1\x9d\x00\x10\xfc\xf8\x2f\x01\x9d\xf8\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x1e\x3f\x05\x05\x02\x05\x26\x27\x6d\x10\x10\x00\xff\x85\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x07\x08\x0c\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -28;
- };
+static void finger_det_cmd_cb(struct libusb_transfer *t)
+{
+ struct libusb_transfer *transfer;
+ unsigned char *data;
+ int r;
+ struct fp_img_dev *dev = t->user_data;
+
+ if (t->status != LIBUSB_TRANSFER_COMPLETED) {
+ fp_dbg("req transfer status %d\n", t->status);
+ fpi_imgdev_session_error(dev, -EIO);
+ goto exit_free_transfer;
+ } else if (t->length != t->actual_length) {
+ fp_dbg("expected %d, sent %d bytes", t->length, t->actual_length);
+ fpi_imgdev_session_error(dev, -EPROTO);
+ goto exit_free_transfer;
+ }
- if ( askScanner( dev, "\x08\x00\x00\x00\x0a\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x10\xfc\xf8\x2f\x01\x9d\xf8\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x1e\x3f\x05\x05\x02\x05\x26\x27\x6d\x10\x10\x00\xff\x85\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x07\x08\x0c\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -29;
- };
+ transfer = libusb_alloc_transfer(0);
+ if (!transfer) {
+ fpi_imgdev_session_error(dev, -ENOMEM);
+ goto exit_free_transfer;
+ }
- if ( askScanner( dev, "\x03\x00\x00\x00\x08\x0e\x85\x09\xed\x09\x6d\x09\xed\x1e\x3f\x05\x05\x02\x05\x26\x27\x6d\x10\x10\x00\xff\x85\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x07\x08\x0c\x00\x6c\x6c\xf0\xf8\x2f\x01\x97\x40\x01\x10\x08\x00\x00\x00\x00\x00\x00\x00\x3e\xf9\x2f\x01", 0x00, NULL ) < 0 ) {
- return -30;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf3\x6c\x6c\xf0\xf8\x2f\x01\x97\x40\x01\x10\x08\x00\x00\x00\x00\x00\x00\x00\x3e\xf9\x2f\x01\x04\xf9\x2f\x01\x97\x40\x01\x10\x03\x00\x00\x00\x00\x00\x00\x00\x00\x46\x03\x10\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -31;
- };
+ data = g_malloc(IMAGE_SIZE);
+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, IMAGE_SIZE,
+ finger_det_data_cb, dev, BULK_TIMEOUT);
- if ( askScanner( dev, "\x84\x00\x00\x00\x32\x02\xa3\x04\x10\x3b\xa3\x04\x10\x1a\xa3\x04\x10\xf9\xa2\x04\x10\xd8\xa2\x00\xb9\x19\xe2\x87\xba\x56\x78\x72\x68\x9e\x7a\xf4\x65\x6d\xd9\xde\xf6\x33\xa2\x04\x10\x12\xa2\x04\x10\xf1\xa1\x04\x10\x04\x00\x00\x00\x00\x00\x00\xb4\x2d\x6c\xe9", 0x40, NULL ) < 0 ) {
- return -32;
- };
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ g_free(data);
+ libusb_free_transfer(transfer);
+ fpi_imgdev_session_error(dev, r);
+ }
+exit_free_transfer:
+ libusb_free_transfer(t);
+}
- if ( askScanner( dev, "\x03\x00\x00\x00\x06\x1a\x07\x1b\x08\x1c\x0c\x77\x21\xac\xe5\x77\x00\x00\x00\x00\xaa\x4e\x01\x10\x3c\x01\x00\x00\xc4\xf8\x2f\x01\xdc\xf8\x2f\x01\x00\x00\x00\x00\x40\x00\x00\x00\xb9\x19\xe2\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00", 0x00, NULL ) < 0 ) {
- return -33;
- };
+static void start_finger_detection(struct fp_img_dev *dev)
+{
+ int r;
+ struct upektc_dev *upekdev = dev->priv;
+ struct libusb_transfer *transfer;
+ fp_dbg("");
- if ( askScanner( dev, "\x08\x00\x00\x00\x0a\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x00\x40\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x01\x00\x00\x40\x00\x00\x00\x01\x00\x00\x00\xcc\xf8\x2f\x01\x8b\x41\x01\x10\x8c\xf8\x2f\x01\x40\x00\x00\x00", 0x00, NULL ) < 0 ) {
- return -34;
- };
+ if (upekdev->deactivating) {
+ complete_deactivation(dev);
+ return;
+ }
- if ( askScanner( dev, "\x03\x00\x00\x00\x04\x3d\x51\x0a\x00\x01\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xfc\xf9\x2f\x01\x31\x10\x01\x10\xd0\xf9\x2f\x01\x00\x00\x00\x00\x1a\x07\x1b\x08\x1c\x0c\xc6\xf8\x66\xbc\xc4\xbe\x0b\x25\xc5\x4c\xf4\x03\x10\x2f\x11\x3f\x12\x44", 0x00, NULL ) < 0 ) {
- return -35;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x3a\x00\x01\x02\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3d\x3f\xff\x00", 0x40, NULL ) < 0 ) {
- return -36;
- };
+ transfer = libusb_alloc_transfer(0);
+ if (!transfer) {
+ fpi_imgdev_session_error(dev, -ENOMEM);
+ return;
+ }
+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT,
+ (unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
+ finger_det_cmd_cb, dev, BULK_TIMEOUT);
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ libusb_free_transfer(transfer);
+ fpi_imgdev_session_error(dev, r);
+ }
+}
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\x0a\x10\x36\x88\xf9\x2f\x01\xf1\x9d\x00\x10\xa8\xf9\x2f\x01\x49\xf9\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x1e\x3f\x05\x05\x02\x05\x26\x27\xed\x00\x10\x00\xff\x85\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x07\x08\x0c\x00\x6c\x6c", 0x00, NULL ) < 0 ) {
- return -37;
- };
- if ( askScanner( dev, "\x8b\x00\x00\xbc\x3a\x40\xd3\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xf4\x2f\x01\x80\x69\x67\xff\xff\xff\xff\xff\x00\xf0\xfd\x7f\x00\x60\xfd\x7f\x3c\x01\x00\x00\xa0\xf5\x2f\x01\x03\x01\x00\x00\x9a\x11\xf4\x77\x9f\x11\xf4\x77\x3c\x01\x00\x00\xa0\xf5\x01", 0x40, NULL ) < 0 ) {
- return -38;
- };
- if ( askScanner( dev, "\x8b\x00\x00\xf6\x3a\x0b\x07\xa5\x03\x2f\x63\x97\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -39;
- };
- if ( askScanner( dev, "\x8b\x00\x01\x30\x3a\x0b\x00\x00\x00\x00\x00\x00\x12\xcd\xa6\x3c\x36\xec\x6a\x73\x00\x64\x75\xdf\x2e\x13\xec\xca\x3c\x03\x00\x00\x06\xa5\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -40;
- };
- if ( askScanner( dev, "\x8b\x00\x01\x6a\x3a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -41;
- };
- if ( askScanner( dev, "\x8b\x00\x01\xa4\x3a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xa5\x83\x1b\x8e\xac\x00\x00\x0b\xa5\x08\x08\x03\x00\x00\x01\x02\x03\x06\x00\x00\x00\x00\x00\x8d\xa5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -42;
- };
- if ( askScanner( dev, "\x8b\x00\x01\xde\x3a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -43;
- };
- if ( askScanner( dev, "\x8b\x00\x02\x18\x3a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -44;
- };
- if ( askScanner( dev, "\x8b\x00\x02\x52\x3a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -45;
- };
- if ( askScanner( dev, "\x8b\x00\x02\x8c\x3a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -46;
- };
- if ( askScanner( dev, "\x8b\x00\x02\xc6\x2a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x01\x00\x00\xc8\x01\x00\x00\x40\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -47;
- };
+/****** CAPTURE ******/
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xf1\x2f\x01\x49\xf9\x2f\x01\x3a\x00\x00\x00\x00\x00\x00\x00\x02\x1e\x3f\x05\x05\x02\x05\x26\x27\xed\x00\x10\x00\xff\x85\x6c\x00\x00\xcf\x00\x01\x00\x00\x1f\x01\x01\x07\x08\x0c\x00\x6c\x6c\x9c\xf9\x2f\x01\x97\x40\x01\x10\x03\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -48;
- };
+enum capture_states {
+ CAPTURE_WRITE_CMD,
+ CAPTURE_READ_DATA,
+ CAPTURE_NUM_STATES,
+};
- if ( askScanner( dev, "\x03\x00\x00\x00\x02\xf1\x01\x00\xb4\xf9\x2f\x01\x6d\x4f\x01\x10\x34\xf9\x2f\x01\x40\x00\x00\x00\xe8\x03\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x00, NULL ) < 0 ) {
- return -49;
- };
- if ( askScanner( dev, "\x8b\x00\x01\x10\x3a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -50;
- };
- if ( askScanner( dev, "\x8b\x00\x01\x4a\x2e\x0b\x06\xa5\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x01\x00\x00\xc8\x01\x00\x00\x40\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -51;
- };
- if ( askScanner( dev, "\x82\x00\x00\x00\x01\xfb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf9\x2f\x01\x97\x40\x01\x10\x03\x00\x00\x00\x00\x00\x00\x00\xfa\x45\x03\x10\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x40, NULL ) < 0 ) {
- return -51;
- };
+static void capture_cmd_cb(struct libusb_transfer *transfer)
+{
+ struct fpi_ssm *ssm = transfer->user_data;
- /* enable sensor */
- if ( askScanner( dev, anInitCommand, 0x00, NULL ) < 0 ) {
- return -52;
+ if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
+ (transfer->length == transfer->actual_length)) {
+ fpi_ssm_next_state(ssm);
+ } else {
+ fpi_ssm_mark_aborted(ssm, -EIO);
}
-
- return 0;
+ libusb_free_transfer(transfer);
}
-static int DetectFinger( struct fp_img_dev *dev ) {
- sint32 nRet = 0;
- uint8 *pnData = NULL;
-
- pnData = g_malloc( SENSOR_FULL_IMAGE );
+static void capture_read_data_cb(struct libusb_transfer *transfer)
+{
+ struct fpi_ssm *ssm = transfer->user_data;
+ struct fp_img_dev *dev = ssm->priv;
+ unsigned char *data = transfer->buffer;
+ struct fp_img *img;
+
+ if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
+ fp_dbg("request is not completed, %d", transfer->status);
+ fpi_ssm_mark_aborted(ssm, -EIO);
+ goto out;
+ } else if (transfer->length != transfer->actual_length) {
+ fp_dbg("expected %d, sent %d bytes", transfer->length, transfer->actual_length);
+ fpi_ssm_mark_aborted(ssm, -EPROTO);
+ goto out;
+ }
- nRet = askScanner( dev, anScanCommand, SENSOR_FULL_IMAGE, pnData );
+ img = fpi_img_new(IMAGE_SIZE);
+ memcpy(img->data, data, IMAGE_SIZE);
+ fpi_imgdev_image_captured(dev, img);
+ fpi_imgdev_report_finger_status(dev, FALSE);
+ fpi_ssm_mark_completed(ssm);
+out:
+ g_free(transfer->buffer);
+ libusb_free_transfer(transfer);
+}
- if ( nRet != SENSOR_FULL_IMAGE ) {
- nRet = 0;
- goto end;
+static void capture_run_state(struct fpi_ssm *ssm)
+{
+ struct fp_img_dev *dev = ssm->priv;
+ int r;
+
+ switch (ssm->cur_state) {
+ case CAPTURE_WRITE_CMD:
+ {
+ struct libusb_transfer *transfer = libusb_alloc_transfer(0);
+ if (!transfer) {
+ fpi_ssm_mark_aborted(ssm, -ENOMEM);
+ return;
+ }
+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT,
+ (unsigned char *)scan_cmd, UPEKTC_CMD_LEN,
+ capture_cmd_cb, ssm, BULK_TIMEOUT);
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ libusb_free_transfer(transfer);
+ fpi_ssm_mark_aborted(ssm, -ENOMEM);
+ }
}
+ break;
+ case CAPTURE_READ_DATA:
+ {
+ struct libusb_transfer *transfer = libusb_alloc_transfer(0);
+ unsigned char *data;
+
+ if (!transfer) {
+ fpi_ssm_mark_aborted(ssm, -ENOMEM);
+ break;
+ }
- nRet = ValidScan( pnData );
-
-end:
- g_free( pnData );
+ data = g_malloc(IMAGE_SIZE);
+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, IMAGE_SIZE,
+ capture_read_data_cb, ssm, BULK_TIMEOUT);
- return nRet;
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ g_free(data);
+ libusb_free_transfer(transfer);
+ fpi_ssm_mark_aborted(ssm, r);
+ }
+ }
+ break;
+ };
}
-static int awaitFingerOn( struct fp_img_dev *dev ) {
- int nRet = 0;
- int nCount = WAIT_COUNT;
+static void capture_sm_complete(struct fpi_ssm *ssm)
+{
+ struct fp_img_dev *dev = ssm->priv;
+ struct upektc_dev *upekdev = dev->priv;
+
+ fp_dbg("Capture completed");
+ if (upekdev->deactivating)
+ complete_deactivation(dev);
+ else if (ssm->error)
+ fpi_imgdev_session_error(dev, ssm->error);
+ else
+ start_finger_detection(dev);
+ fpi_ssm_free(ssm);
+}
- /* wait until a finger is present */
- do {
- nRet = DetectFinger( dev );
- } while ( nRet == 0 );
+static void start_capture(struct fp_img_dev *dev)
+{
+ struct upektc_dev *upekdev = dev->priv;
+ struct fpi_ssm *ssm;
- /* give user time to scan his full finger */
- while ( nCount-- ) {
- nRet = DetectFinger( dev );
+ if (upekdev->deactivating) {
+ complete_deactivation(dev);
+ return;
}
- return nRet != 1 ? nRet : 0;
+ ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES);
+ fp_dbg("");
+ ssm->priv = dev;
+ fpi_ssm_start(ssm, capture_sm_complete);
}
-static int capture( struct fp_img_dev *dev, gboolean unconditional, struct fp_img **ppsRet ) {
- struct fp_img *psImg = NULL;
- uint8 *pnData = NULL;
- sint32 nRet = 0;
+static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
+{
+ struct upektc_dev *upekdev = dev->priv;
+ struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state,
+ ACTIVATE_NUM_STATES);
+ ssm->priv = dev;
+ upekdev->init_idx = 0;
+ fpi_ssm_start(ssm, activate_sm_complete);
+ return 0;
+}
- psImg = fpi_img_new_for_imgdev( dev );
- pnData = g_malloc( SENSOR_FULL_IMAGE );
+static void dev_deactivate(struct fp_img_dev *dev)
+{
+ struct upektc_dev *upekdev = dev->priv;
- nRet = askScanner( dev, anScanCommand, SENSOR_FULL_IMAGE, pnData );
- if ( nRet == SENSOR_FULL_IMAGE ) {
- memcpy( psImg -> data, pnData, SENSOR_FULL_IMAGE );
- *ppsRet = psImg;
- nRet = 0;
- } else {
- nRet = -1;
- }
+ upekdev->deactivating = TRUE;
+}
- g_free( pnData );
+static void complete_deactivation(struct fp_img_dev *dev)
+{
+ struct upektc_dev *upekdev = dev->priv;
+ fp_dbg("");
- return nRet;
+ upekdev->deactivating = FALSE;
+ fpi_imgdev_deactivate_complete(dev);
}
-static int dev_init( struct fp_img_dev *dev, unsigned long driver_data ) {
- int nResult;
+static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
+{
+ /* TODO check that device has endpoints we're using */
+ int r;
- nResult = libusb_claim_interface(dev->udev, 0);
- if ( nResult < 0 ) {
- fp_err( "could not claim interface 0" );
- return nResult;
+ r = libusb_claim_interface(dev->udev, 0);
+ if (r < 0) {
+ fp_err("could not claim interface 0");
+ return r;
}
- nResult = SetupSensor( dev );
-
- return nResult;
+ dev->priv = g_malloc0(sizeof(struct upektc_dev));
+ fpi_imgdev_open_complete(dev, 0);
+ return 0;
}
-static void dev_exit( struct fp_img_dev *dev ) {
+static void dev_deinit(struct fp_img_dev *dev)
+{
+ g_free(dev->priv);
libusb_release_interface(dev->udev, 0);
+ fpi_imgdev_close_complete(dev);
}
static const struct usb_id id_table[] = {
@@ -404,13 +452,13 @@ struct fp_img_driver upektc_driver = {
.id_table = id_table,
.scan_type = FP_SCAN_TYPE_PRESS,
},
- .flags = FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE,
- .img_height = 288,
- .img_width = 208,
+ .flags = 0,
+ .img_height = IMAGE_HEIGHT,
+ .img_width = IMAGE_WIDTH,
.bz3_threshold = 30,
- .init = dev_init,
- .exit = dev_exit,
- .await_finger_on = awaitFingerOn,
- .capture = capture,
+ .open = dev_init,
+ .close = dev_deinit,
+ .activate = dev_activate,
+ .deactivate = dev_deactivate,
};
diff --git a/libfprint/drivers/upektc.h b/libfprint/drivers/upektc.h
new file mode 100644
index 0000000..a198018
--- /dev/null
+++ b/libfprint/drivers/upektc.h
@@ -0,0 +1,737 @@
+/*
+ * UPEK TouchChip driver for libfprint
+ * Copyright (C) 2012 Vasily Khoruzhick <anarsoul@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __UPEKTC_H
+#define __UPEKTC_H
+
+#define UPEKTC_CMD_LEN 0x40
+#define IMAGE_WIDTH 208
+#define IMAGE_HEIGHT 288
+#define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT)
+#define SUM_THRESHOLD 10000
+
+struct setup_cmd {
+ unsigned char cmd[0x40];
+ int response_len;
+};
+
+static const struct setup_cmd setup_commands[] = {
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x00, 0x01,
+ 0xc0, 0xbd, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0xf0, 0xfd, 0x7f, 0x00, 0x60, 0xfd, 0x7f,
+ 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0xcc, 0xf8, 0x2f, 0x01,
+ 0x09, 0x48, 0xe7, 0x77, 0xf0, 0xfa, 0x2f, 0x01,
+ 0x09, 0x48, 0xe7, 0x77, 0xe0, 0x3a, 0xe6, 0x77
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf7, 0x00, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x58, 0xf9, 0x2f, 0x01,
+ 0xe9, 0x4f, 0x01, 0x10, 0xd8, 0xf8, 0x2f, 0x01,
+ 0x40, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x02, 0xfe, 0x00, 0x01, 0xc0, 0xbd, 0xf0, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfd, 0x7f
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0xf7, 0xcd, 0x00,
+ 0x2c, 0xf9, 0x2f, 0x01, 0x6d, 0x4f, 0x01, 0x10,
+ 0xac, 0xf8, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00,
+ 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0xfe, 0x16, 0x10, 0x03, 0xee, 0x00, 0x37,
+ 0x01, 0x09, 0x02, 0x0e, 0x03, 0x18, 0x03, 0x1a,
+ 0x03, 0x20, 0x10, 0x2f, 0x11, 0x3f, 0x12, 0x44,
+ 0x01, 0x01, 0x07, 0x08, 0x0c, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00,
+ 0x02, 0xfe, 0x16, 0x10, 0x03, 0xee, 0x00, 0x37,
+ 0x01, 0x09, 0x02, 0x0e, 0x03, 0x18, 0x03, 0x1a,
+ 0x03, 0x20, 0x10, 0x2f, 0x11, 0x3f, 0x12, 0x44,
+ 0x01, 0x01, 0x07, 0x08, 0x0c, 0x00, 0x6c, 0x6c,
+ 0x00, 0xf9, 0x2f, 0x01, 0x97, 0x40, 0x01, 0x10,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfa, 0x45, 0x03, 0x10, 0x02, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x00, 0x00, 0x3a, 0x50, 0xf9, 0x2f,
+ 0x01, 0x18, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x88, 0xf9, 0x2f,
+ 0x01, 0x91, 0x99, 0x00, 0x10, 0xf8, 0x00, 0x00,
+ 0x00, 0xbe, 0x99, 0x00, 0x10, 0xa0, 0xa6, 0x04,
+ 0x10, 0x01, 0x9b, 0x00, 0x10, 0x18, 0x00, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x01, 0x02,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, 0xff, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x01, 0x02,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, 0xff, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x0d, 0xff, 0x36,
+ 0xdc, 0xf8, 0x2f, 0x01, 0xf1, 0x9d, 0x00, 0x10,
+ 0xfc, 0xf8, 0x2f, 0x01, 0x9d, 0xf8, 0x2f, 0x01,
+ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x9e, 0xbf, 0x85, 0x85, 0x02, 0x05, 0x26,
+ 0x25, 0x4d, 0x13, 0x10, 0x00, 0x00, 0x00, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x0c, 0x37, 0x6a, 0x3d,
+ 0x73, 0x3d, 0x71, 0x0e, 0x01, 0x0e, 0x81, 0x3d,
+ 0x51, 0xf8, 0x2f, 0x01, 0x3a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x9e, 0xbf, 0x85,
+ 0x85, 0x02, 0x05, 0x26, 0x25, 0x4d, 0x13, 0x10,
+ 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0xcf, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x09, 0x09,
+ 0x0f, 0x00, 0x6c, 0x6c, 0xf0, 0xf8, 0x2f, 0x01
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x01, 0x02,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, 0xff, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0x7c, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
+ 0x14, 0xf5, 0x2f, 0x01, 0xa0, 0x20, 0x14, 0x00,
+ 0x40, 0xf8, 0x2f, 0x01, 0x05, 0x90, 0xf6, 0x77,
+ 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x50, 0xf8, 0x2f, 0x01, 0x40, 0x39, 0xf4, 0x77,
+ 0xa8, 0x20, 0x14, 0x00, 0x1c, 0xf6, 0x2f, 0x01,
+ 0x2c, 0x20, 0xf4, 0x77, 0x80, 0x4d, 0xfb, 0x77
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x03, 0xc8, 0x3a, 0x01, 0x00, 0x00,
+ 0x1f, 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x62, 0x62, 0x62, 0x62,
+ 0x62, 0x51, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0xf9, 0x2f, 0x01, 0x4f, 0x9d, 0x00,
+ 0x10, 0x3a, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x01
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x04, 0x02, 0x06, 0x0b, 0x07, 0x13,
+ 0x0e, 0x55, 0x56, 0x01, 0x44, 0xf8, 0x2f, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x07, 0x00, 0x20, 0x00, 0x3a, 0x0e, 0x13, 0x07,
+ 0x0f, 0x14, 0x07, 0x10, 0x15, 0x07, 0x12, 0x16,
+ 0x07, 0x13, 0x17, 0x07, 0x14, 0x18, 0x07, 0x15,
+ 0x18, 0x07, 0x16, 0x19, 0x07, 0x17, 0x1a, 0x07,
+ 0x19, 0x1b, 0x07, 0x1a, 0x1c, 0x07, 0x1b, 0x1d,
+ 0x07, 0x1c, 0x1e, 0x07, 0x1d, 0x1f, 0x07, 0x1e,
+ 0x20, 0x07, 0x1f, 0x21, 0x07, 0x20, 0x22, 0x07,
+ 0x21, 0x23, 0x07, 0x23, 0x23, 0x07, 0x24, 0x55
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x07, 0x00, 0x20, 0x3a, 0x26, 0x24, 0x07, 0x25,
+ 0x25, 0x07, 0x26, 0x25, 0x07, 0x27, 0x26, 0x07,
+ 0x28, 0x27, 0x07, 0x29, 0x27, 0x07, 0x2a, 0x28,
+ 0x07, 0x2b, 0x29, 0x07, 0x2d, 0x29, 0x07, 0x2e,
+ 0x2a, 0x07, 0x2f, 0x2b, 0x07, 0x30, 0x2b, 0x07,
+ 0x31, 0x2c, 0x07, 0x07, 0x1d, 0x1f, 0x07, 0x1e,
+ 0x20, 0x07, 0x1f, 0x21, 0x07, 0x20, 0x22, 0x07,
+ 0x21, 0x23, 0x07, 0x23, 0x23, 0x07, 0x24, 0x55
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x81, 0x0e,
+ 0x81, 0x09, 0x4d, 0x00, 0x07, 0x00, 0x20, 0x3a,
+ 0x26, 0x24, 0x07, 0x25, 0x25, 0x07, 0x26, 0x25,
+ 0x07, 0x27, 0x26, 0x07, 0x28, 0x27, 0x07, 0x29,
+ 0x27, 0x07, 0x2a, 0x28, 0x07, 0x2b, 0x29, 0x07,
+ 0x2d, 0x29, 0x07, 0x2e, 0x2a, 0x07, 0x2f, 0x2b,
+ 0x07, 0x30, 0x2b, 0x07, 0x31, 0x2c, 0x07, 0x07,
+ 0x1d, 0x1f, 0x07, 0x1e, 0x20, 0x07, 0x1f, 0x21
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x01, 0x02,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, 0xff, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x85, 0x36,
+ 0xd8, 0xf8, 0x2f, 0x01, 0xf1, 0x9d, 0x00, 0x10,
+ 0xf8, 0xf8, 0x2f, 0x01, 0x99, 0xf8, 0x2f, 0x01,
+ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x9e, 0xbf, 0x85, 0x85, 0x02, 0x05, 0x26,
+ 0x25, 0x4d, 0x10, 0x10, 0x00, 0xff, 0x81, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
+ 0x02, 0x9e, 0xbf, 0x85, 0x85, 0x02, 0x05, 0x26,
+ 0x25, 0x4d, 0x10, 0x10, 0x00, 0xff, 0x81, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c,
+ 0xec, 0xf8, 0x2f, 0x01, 0x97, 0x40, 0x01, 0x10,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfa, 0x45, 0x03, 0x10, 0x02, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf7, 0xcf, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x09, 0x09,
+ 0x0f, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x62,
+ 0x62, 0x62, 0x62, 0x62, 0x51, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf7, 0x00, 0x00,
+ 0x02, 0xf9, 0xbf, 0x85, 0x85, 0x02, 0x05, 0x26,
+ 0x25, 0x4d, 0x10, 0x10, 0x00, 0xff, 0x81, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x40, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x62, 0x62, 0x62, 0x62, 0x62
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0xf7, 0xf4, 0x00,
+ 0x14, 0xf9, 0x2f, 0x01, 0x6d, 0x4f, 0x01, 0x10,
+ 0x94, 0xf8, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00,
+ 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0xf9, 0xbf, 0x85, 0x85, 0x02, 0x05, 0x26,
+ 0x25, 0x4d, 0x10, 0x10, 0x00, 0xff, 0x81, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x20, 0x6c, 0x01,
+ 0x6d, 0x4f, 0x01, 0x10, 0x94, 0xf8, 0x2f, 0x01,
+ 0x40, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0xf9, 0xbf, 0x85,
+ 0x85, 0x02, 0x05, 0x26, 0x25, 0x4d, 0x10, 0x10,
+ 0x00, 0xff, 0x81, 0x6c, 0x00, 0x00, 0xcf, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x09, 0x09,
+ 0x0f, 0x00, 0x6c, 0x6c, 0xe8, 0xf8, 0x2f, 0x01
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf9, 0x81, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c,
+ 0xe8, 0xf8, 0x2f, 0x01, 0xec, 0xf8, 0x2f, 0x01,
+ 0x97, 0x40, 0x01, 0x10, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfa, 0x45, 0x03, 0x10,
+ 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0xf9, 0x01, 0x00,
+ 0x1c, 0xf9, 0x2f, 0x01, 0x6d, 0x4f, 0x01, 0x10,
+ 0x9c, 0xf8, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00,
+ 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x6c, 0xbf, 0x85, 0x85, 0x02, 0x05, 0x26,
+ 0x25, 0x4d, 0x10, 0x10, 0x00, 0xff, 0x81, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x09, 0x09, 0x0f, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x12, 0x1c, 0x0c, 0x1b,
+ 0x08, 0x1a, 0x07, 0x30, 0x08, 0x09, 0x6d, 0x08,
+ 0x27, 0x00, 0x9e, 0x00, 0x1e, 0x23, 0x47, 0x01,
+ 0x40, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x6c, 0xbf, 0x85,
+ 0x85, 0x02, 0x05, 0x26, 0x25, 0x4d, 0x10, 0x10,
+ 0x00, 0xff, 0x81, 0x6c, 0x00, 0x00, 0xcf, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x09, 0x09
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x01, 0x02,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, 0xff, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x0d, 0xff, 0x36,
+ 0xdc, 0xf8, 0x2f, 0x01, 0xf1, 0x9d, 0x00, 0x10,
+ 0xfc, 0xf8, 0x2f, 0x01, 0x9d, 0xf8, 0x2f, 0x01,
+ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x1e, 0x3f, 0x05, 0x05, 0x02, 0x05, 0x26,
+ 0x27, 0x6d, 0x10, 0x10, 0x00, 0xff, 0x85, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x07, 0x08, 0x0c, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0xcf,
+ 0x00, 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x10,
+ 0xfc, 0xf8, 0x2f, 0x01, 0x9d, 0xf8, 0x2f, 0x01,
+ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x1e, 0x3f, 0x05, 0x05, 0x02, 0x05, 0x26,
+ 0x27, 0x6d, 0x10, 0x10, 0x00, 0xff, 0x85, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x07, 0x08, 0x0c, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x08, 0x0e, 0x85, 0x09,
+ 0xed, 0x09, 0x6d, 0x09, 0xed, 0x1e, 0x3f, 0x05,
+ 0x05, 0x02, 0x05, 0x26, 0x27, 0x6d, 0x10, 0x10,
+ 0x00, 0xff, 0x85, 0x6c, 0x00, 0x00, 0xcf, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x08,
+ 0x0c, 0x00, 0x6c, 0x6c, 0xf0, 0xf8, 0x2f, 0x01,
+ 0x97, 0x40, 0x01, 0x10, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3e, 0xf9, 0x2f, 0x01
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf3, 0x6c, 0x6c,
+ 0xf0, 0xf8, 0x2f, 0x01, 0x97, 0x40, 0x01, 0x10,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3e, 0xf9, 0x2f, 0x01, 0x04, 0xf9, 0x2f, 0x01,
+ 0x97, 0x40, 0x01, 0x10, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0x10,
+ 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x84, 0x00, 0x00, 0x00, 0x32, 0x02, 0xa3, 0x04,
+ 0x10, 0x3b, 0xa3, 0x04, 0x10, 0x1a, 0xa3, 0x04,
+ 0x10, 0xf9, 0xa2, 0x04, 0x10, 0xd8, 0xa2, 0x00,
+ 0xb9, 0x19, 0xe2, 0x87, 0xba, 0x56, 0x78, 0x72,
+ 0x68, 0x9e, 0x7a, 0xf4, 0x65, 0x6d, 0xd9, 0xde,
+ 0xf6, 0x33, 0xa2, 0x04, 0x10, 0x12, 0xa2, 0x04,
+ 0x10, 0xf1, 0xa1, 0x04, 0x10, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xb4, 0x2d, 0x6c, 0xe9
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x06, 0x1a, 0x07, 0x1b,
+ 0x08, 0x1c, 0x0c, 0x77, 0x21, 0xac, 0xe5, 0x77,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x4e, 0x01, 0x10,
+ 0x3c, 0x01, 0x00, 0x00, 0xc4, 0xf8, 0x2f, 0x01,
+ 0xdc, 0xf8, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0xb9, 0x19, 0xe2, 0x87,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0xcf,
+ 0x00, 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xcc, 0xf8, 0x2f, 0x01, 0x8b, 0x41, 0x01, 0x10,
+ 0x8c, 0xf8, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x04, 0x3d, 0x51, 0x0a,
+ 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfc, 0xf9, 0x2f, 0x01, 0x31, 0x10, 0x01, 0x10,
+ 0xd0, 0xf9, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x1a, 0x07, 0x1b, 0x08, 0x1c, 0x0c, 0xc6, 0xf8,
+ 0x66, 0xbc, 0xc4, 0xbe, 0x0b, 0x25, 0xc5, 0x4c,
+ 0xf4, 0x03, 0x10, 0x2f, 0x11, 0x3f, 0x12, 0x44
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x01, 0x02,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, 0xff, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x10, 0x36,
+ 0x88, 0xf9, 0x2f, 0x01, 0xf1, 0x9d, 0x00, 0x10,
+ 0xa8, 0xf9, 0x2f, 0x01, 0x49, 0xf9, 0x2f, 0x01,
+ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x1e, 0x3f, 0x05, 0x05, 0x02, 0x05, 0x26,
+ 0x27, 0xed, 0x00, 0x10, 0x00, 0xff, 0x85, 0x6c,
+ 0x00, 0x00, 0xcf, 0x00, 0x01, 0x00, 0x00, 0x1f,
+ 0x01, 0x01, 0x07, 0x08, 0x0c, 0x00, 0x6c, 0x6c
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x00, 0xbc, 0x3a, 0x40, 0xd3, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0xf4, 0x2f, 0x01, 0x80, 0x69, 0x67,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xfd,
+ 0x7f, 0x00, 0x60, 0xfd, 0x7f, 0x3c, 0x01, 0x00,
+ 0x00, 0xa0, 0xf5, 0x2f, 0x01, 0x03, 0x01, 0x00,
+ 0x00, 0x9a, 0x11, 0xf4, 0x77, 0x9f, 0x11, 0xf4,
+ 0x77, 0x3c, 0x01, 0x00, 0x00, 0xa0, 0xf5, 0x01
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x00, 0xf6, 0x3a, 0x0b, 0x07, 0xa5,
+ 0x03, 0x2f, 0x63, 0x97, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0x30, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0xcd, 0xa6, 0x3c,
+ 0x36, 0xec, 0x6a, 0x73, 0x00, 0x64, 0x75, 0xdf,
+ 0x2e, 0x13, 0xec, 0xca, 0x3c, 0x03, 0x00, 0x00,
+ 0x06, 0xa5, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0x6a, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0xa4, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0xa5, 0x83, 0x1b, 0x8e, 0xac, 0x00, 0x00,
+ 0x0b, 0xa5, 0x08, 0x08, 0x03, 0x00, 0x00, 0x01,
+ 0x02, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x8d, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0xde, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x02, 0x18, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x02, 0x52, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x02, 0x8c, 0x3a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x02, 0xc6, 0x2a, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xf1, 0x2f, 0x01,
+ 0x49, 0xf9, 0x2f, 0x01, 0x3a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x1e, 0x3f, 0x05,
+ 0x05, 0x02, 0x05, 0x26, 0x27, 0xed, 0x00, 0x10,
+ 0x00, 0xff, 0x85, 0x6c, 0x00, 0x00, 0xcf, 0x00,
+ 0x01, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x07, 0x08,
+ 0x0c, 0x00, 0x6c, 0x6c, 0x9c, 0xf9, 0x2f, 0x01,
+ 0x97, 0x40, 0x01, 0x10, 0x03, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x01, 0x00,
+ 0xb4, 0xf9, 0x2f, 0x01, 0x6d, 0x4f, 0x01, 0x10,
+ 0x34, 0xf9, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00,
+ 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x00
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0x10, 0x3a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x8b, 0x00, 0x01, 0x4a, 0x2e, 0x0b, 0x06, 0xa5,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x82, 0x00, 0x00, 0x00, 0x01, 0xfb, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x88, 0xf9, 0x2f, 0x01, 0x97, 0x40, 0x01, 0x10,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfa, 0x45, 0x03, 0x10, 0x02, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x40
+ },
+ {
+ .cmd = {
+ 0x03, 0x00, 0x00, 0x00, 0x02, 0xfb, 0x0f, 0x00,
+ 0xc4, 0xf9, 0x2f, 0x01, 0x6d, 0x4f, 0x01, 0x10,
+ 0x44, 0xf9, 0x2f, 0x01, 0x40, 0x00, 0x00, 0x00,
+ 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ .response_len = 0x00
+ }
+};
+
+static const unsigned char scan_cmd[0x40] = {
+ 0x0e, 0x00, 0x03, 0xa8, 0x00, 0xb6, 0xbb, 0xbb,
+ 0xb8, 0xb7, 0xb8, 0xb5, 0xb8, 0xb9, 0xb8, 0xb9,
+ 0xbb, 0xbb, 0xbe, 0xbb, 0x4e, 0x16, 0xf4, 0x77,
+ 0xa8, 0x07, 0x32, 0x00, 0x6a, 0x16, 0xf4, 0x77,
+ 0x78, 0x24, 0x61, 0x00, 0xc8, 0x00, 0xec, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x3c, 0xf3, 0x2f, 0x01,
+ 0x05, 0x90, 0xf6, 0x77, 0x84, 0xf5, 0x2f, 0x01,
+ 0x05, 0x90, 0xf6, 0x00, 0xc8, 0x00, 0xec, 0x00
+};
+
+#endif