From 0f4a75ff61cc156b6cabdb1f6c1e22ea314a9aff Mon Sep 17 00:00:00 2001 From: Benedikt Morbach Date: Mon, 28 May 2012 14:13:03 +0200 Subject: [PATCH 01/49] update udev rules dir location again Instead of hardcoding whatever the new fashion is every few months, which might even differ between distributions, just put the rules where udev says we should. https://bugs.freedesktop.org/show_bug.cgi?id=50426 --- configure.ac | 2 ++ libfprint/Makefile.am | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f5c26f90..1d57e4e9 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,8 @@ AC_SUBST(GLIB_LIBS) imagemagick_found=no gdkpixbuf_found=no +AC_SUBST([udev_rulesdir], [$($PKG_CONFIG --variable=udevdir udev)/rules.d]) + if test "$require_imaging" = "yes"; then PKG_CHECK_MODULES(IMAGING, gthread-2.0 gdk-pixbuf-2.0, [gdkpixbuf_found=yes], [gdkpixbuf_found=no]) if test "$gdkpixbuf_found" != "yes"; then diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 656a2f43..79535260 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -79,7 +79,6 @@ fprint_list_udev_rules_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(L fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la udev_rules_DATA = 60-fprint-autosuspend.rules -udev_rulesdir = $(libdir)/udev/rules.d/ $(udev_rules_DATA): fprint-list-udev-rules $(builddir)/fprint-list-udev-rules > $@ From 96e7224a236d0a7d515fde5593c77cf6eb8fd942 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 14 Aug 2012 14:48:43 +0100 Subject: [PATCH 02/49] build: Fix distchecking of examples directory --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index aff8410c..6beb0e7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,6 +9,8 @@ if BUILD_EXAMPLES SUBDIRS += examples endif +DIST_SUBDIRS = libfprint doc examples + pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA=libfprint.pc From bc03d5618619c3236cd61df77342ede97186622a Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 14 Aug 2012 14:51:23 +0100 Subject: [PATCH 03/49] build: Add list of drivers to include when distchecking --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index 6beb0e7e..38b8868c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,6 +11,8 @@ endif DIST_SUBDIRS = libfprint doc examples +DISTCHECK_CONFIGURE_FLAGS = --with-drivers=upekts,upeke2,upeksonly,uru4000,vcom5s,aes2501,aes1610,aes4000,vfs101 --enable-examples-build --enable-x11-examples-build + pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA=libfprint.pc From 2d09b10a2795528134fb0699903160545e153188 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 14 Aug 2012 14:52:58 +0100 Subject: [PATCH 04/49] build: Include udev rules in tarball --- libfprint/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 79535260..cd0a5740 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -28,7 +28,8 @@ EXTRA_DIST = \ $(VFS101_SRC) \ aeslib.c aeslib.h \ imagemagick.c \ - gdkpixbuf.c + gdkpixbuf.c \ + 60-fprint-autosuspend.rules DRIVER_SRC = OTHER_SRC = From d05c69698c6eb1aadcd5a7cbdb883b7accb35eb2 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 14 Aug 2012 15:12:20 +0100 Subject: [PATCH 05/49] build: Fix distcheck'ing not working We need to be able to override the udev rules directory for distchecking to work. --- Makefile.am | 2 +- configure.ac | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 38b8868c..f14189d4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ endif DIST_SUBDIRS = libfprint doc examples -DISTCHECK_CONFIGURE_FLAGS = --with-drivers=upekts,upeke2,upeksonly,uru4000,vcom5s,aes2501,aes1610,aes4000,vfs101 --enable-examples-build --enable-x11-examples-build +DISTCHECK_CONFIGURE_FLAGS = --with-drivers=upekts,upeke2,upeksonly,uru4000,vcom5s,aes2501,aes1610,aes4000,vfs101 --enable-examples-build --enable-x11-examples-build --with-udev-rules-dir='$${libdir}/udev/rules.d-distcheck' pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA=libfprint.pc diff --git a/configure.ac b/configure.ac index 1d57e4e9..6a2886cd 100644 --- a/configure.ac +++ b/configure.ac @@ -129,7 +129,16 @@ AC_SUBST(GLIB_LIBS) imagemagick_found=no gdkpixbuf_found=no -AC_SUBST([udev_rulesdir], [$($PKG_CONFIG --variable=udevdir udev)/rules.d]) +AC_ARG_WITH(udev-rules-dir, + AS_HELP_STRING([--with-udev-rules-dir=DIR],[Installation path for udev rules @<:@auto@:>@]), + [ac_with_udev_rules_dir=$withval], + [ac_with_udev_rules_dir=""]) + +if test "${ac_with_udev_rules_dir}" = ""; then + ac_with_udev_rules_dir=`$PKG_CONFIG --variable=udevdir udev`/rules.d +fi +AC_MSG_NOTICE([installing udev rules in ${ac_with_udev_rules_dir}]) +AC_SUBST([udev_rulesdir],[${ac_with_udev_rules_dir}]) if test "$require_imaging" = "yes"; then PKG_CHECK_MODULES(IMAGING, gthread-2.0 gdk-pixbuf-2.0, [gdkpixbuf_found=yes], [gdkpixbuf_found=no]) From 3b409c767cb5c0c27229994ac47edf47c1c59804 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 14 Aug 2012 15:19:35 +0100 Subject: [PATCH 06/49] build: Allow disabling the update of udev rules We can only create the udev rules file when we're not cross-compiling, so allow people to disable updating the file when building from tarballs. If you run with --enable-udev-rules=no and the 60-fprint-autosuspend.rules doesn't exist, you're on your own. --- configure.ac | 10 ++++++++++ libfprint/Makefile.am | 2 ++ 2 files changed, 12 insertions(+) diff --git a/configure.ac b/configure.ac index 6a2886cd..4b8a7654 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,16 @@ AC_SUBST(GLIB_LIBS) imagemagick_found=no gdkpixbuf_found=no +AC_ARG_ENABLE(udev-rules, + AC_HELP_STRING([--enable-udev-rules],[Update the udev rules]), + [case "${enableval}" in + yes) ENABLE_UDEV_RULES=yes ;; + no) ENABLE_UDEV_RULES=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-udev-rules) ;; + esac], + [ENABLE_UDEV_RULES=yes]) dnl Default value +AM_CONDITIONAL(ENABLE_UDEV_RULES, test x$ENABLE_UDEV_RULES = "xyes") + AC_ARG_WITH(udev-rules-dir, AS_HELP_STRING([--with-udev-rules-dir=DIR],[Installation path for udev rules @<:@auto@:>@]), [ac_with_udev_rules_dir=$withval], diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index cd0a5740..fa0b54dd 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -81,8 +81,10 @@ fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la udev_rules_DATA = 60-fprint-autosuspend.rules +if ENABLE_UDEV_RULES $(udev_rules_DATA): fprint-list-udev-rules $(builddir)/fprint-list-udev-rules > $@ +endif if ENABLE_UPEKE2 DRIVER_SRC += $(UPEKE2_SRC) From ff02115b0fa8b72a1d8c07b8e2c9ad7e90459427 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 13 Aug 2012 20:41:42 +0300 Subject: [PATCH 07/49] lib: Fix global variables collision with libusb --- libfprint/core.c | 12 ++++++------ libfprint/fp_internal.h | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index 401c491d..80cd4da1 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -291,25 +291,25 @@ void fpi_log(enum fpi_log_level level, const char *component, #ifndef ENABLE_DEBUG_LOGGING if (!log_level) return; - if (level == LOG_LEVEL_WARNING && log_level < 2) + if (level == FPRINT_LOG_LEVEL_WARNING && log_level < 2) return; - if (level == LOG_LEVEL_INFO && log_level < 3) + if (level == FPRINT_LOG_LEVEL_INFO && log_level < 3) return; #endif switch (level) { - case LOG_LEVEL_INFO: + case FPRINT_LOG_LEVEL_INFO: prefix = "info"; break; - case LOG_LEVEL_WARNING: + case FPRINT_LOG_LEVEL_WARNING: stream = stderr; prefix = "warning"; break; - case LOG_LEVEL_ERROR: + case FPRINT_LOG_LEVEL_ERROR: stream = stderr; prefix = "error"; break; - case LOG_LEVEL_DEBUG: + case FPRINT_LOG_LEVEL_DEBUG: stream = stderr; prefix = "debug"; break; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index e6134d4d..c829a4d6 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -33,10 +33,10 @@ (type *)( (char *)__mptr - offsetof(type,member) );}) enum fpi_log_level { - LOG_LEVEL_DEBUG, - LOG_LEVEL_INFO, - LOG_LEVEL_WARNING, - LOG_LEVEL_ERROR, + FPRINT_LOG_LEVEL_DEBUG, + FPRINT_LOG_LEVEL_INFO, + FPRINT_LOG_LEVEL_WARNING, + FPRINT_LOG_LEVEL_ERROR, }; void fpi_log(enum fpi_log_level, const char *component, const char *function, @@ -53,14 +53,14 @@ void fpi_log(enum fpi_log_level, const char *component, const char *function, #endif #ifdef ENABLE_DEBUG_LOGGING -#define fp_dbg(fmt...) _fpi_log(LOG_LEVEL_DEBUG, fmt) +#define fp_dbg(fmt...) _fpi_log(FPRINT_LOG_LEVEL_DEBUG, fmt) #else #define fp_dbg(fmt...) #endif -#define fp_info(fmt...) _fpi_log(LOG_LEVEL_INFO, fmt) -#define fp_warn(fmt...) _fpi_log(LOG_LEVEL_WARNING, fmt) -#define fp_err(fmt...) _fpi_log(LOG_LEVEL_ERROR, fmt) +#define fp_info(fmt...) _fpi_log(FPRINT_LOG_LEVEL_INFO, fmt) +#define fp_warn(fmt...) _fpi_log(FPRINT_LOG_LEVEL_WARNING, fmt) +#define fp_err(fmt...) _fpi_log(FPRINT_LOG_LEVEL_ERROR, fmt) #ifndef NDEBUG #define BUG_ON(condition) \ From 080c414ce9586d7b4b92e786705e9b716b91aa33 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Aug 2012 19:41:41 +0100 Subject: [PATCH 08/49] build: Whitespace fixes in configure.ac --- configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 4b8a7654..a375ef2a 100644 --- a/configure.ac +++ b/configure.ac @@ -192,17 +192,17 @@ if test "x$build_x11_examples" != "xno"; then AC_MSG_CHECKING(for Xv extensions) AC_TRY_COMPILE([ #include - #include ],[ + #include ],[ int main(void) { (void) XvGetPortAttribute(0, 0, 0, 0); return 0; } ],xv=yes,xv=no); AC_MSG_RESULT($xv) - if test x$xv = xyes; then - XV_LIBS="-lXv -lXext" - XV_CFLAGS="" + if test x$xv = xyes; then + XV_LIBS="-lXv -lXext" + XV_CFLAGS="" AC_DEFINE(HAVE_XV,1,[defined if XV video overlay is available]) else AC_MSG_ERROR([XV is required for X11 examples]) - fi + fi ]) AC_CHECK_XV fi From 3d222ddda7f6acfadd40fcd06b3ab40192829d5a Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Aug 2012 19:42:05 +0100 Subject: [PATCH 09/49] lib: Fix whitespace errors --- libfprint/fp_internal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index c829a4d6..5bd46279 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -158,7 +158,7 @@ enum fp_imgdev_enroll_state { enum fp_imgdev_verify_state { IMG_VERIFY_STATE_NONE = 0, - IMG_VERIFY_STATE_ACTIVATING + IMG_VERIFY_STATE_ACTIVATING }; struct fp_img_dev { @@ -325,8 +325,8 @@ struct fp_minutiae { }; /* bit values for fp_img.flags */ -#define FP_IMG_V_FLIPPED (1<<0) -#define FP_IMG_H_FLIPPED (1<<1) +#define FP_IMG_V_FLIPPED (1<<0) +#define FP_IMG_H_FLIPPED (1<<1) #define FP_IMG_COLORS_INVERTED (1<<2) #define FP_IMG_BINARIZED_FORM (1<<3) From c3689665dbf3cd2126f3729792aa71efe13aab8d Mon Sep 17 00:00:00 2001 From: Andrej Krutak Date: Sun, 22 Jul 2012 21:44:34 +0200 Subject: [PATCH 10/49] lib: Add VFS300/VFS301 driver https://bugs.freedesktop.org/show_bug.cgi?id=37574 --- configure.ac | 13 +- libfprint/Makefile.am | 6 + libfprint/core.c | 3 + libfprint/drivers/vfs301.c | 306 +++ libfprint/drivers/vfs301_proto.c | 639 +++++ libfprint/drivers/vfs301_proto.h | 137 + libfprint/drivers/vfs301_proto_fragments.h | 2631 ++++++++++++++++++++ libfprint/fp_internal.h | 3 + 8 files changed, 3737 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/vfs301.c create mode 100644 libfprint/drivers/vfs301_proto.c create mode 100644 libfprint/drivers/vfs301_proto.h create mode 100644 libfprint/drivers/vfs301_proto_fragments.h diff --git a/configure.ac b/configure.ac index a375ef2a..a2bd3c25 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) AC_SUBST(lt_age) -all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000 vfs101" +all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000 vfs101 vfs301" require_imaging='no' require_aeslib='no' @@ -38,6 +38,7 @@ enable_aes1610='no' enable_aes2501='no' enable_aes4000='no' enable_vfs101='no' +enable_vfs301='no' AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [List of drivers to enable])], @@ -96,6 +97,10 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do AC_DEFINE([ENABLE_VFS101], [], [Build Validity VFS101 driver]) enable_vfs101="yes" ;; + vfs301) + AC_DEFINE([ENABLE_VFS301], [], [Build Validity VFS301/VFS300 driver]) + enable_vfs301="yes" + ;; esac done @@ -111,6 +116,7 @@ AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"]) AM_CONDITIONAL([ENABLE_VFS101], [test "$enable_vfs101" = "yes"]) +AM_CONDITIONAL([ENABLE_VFS301], [test "$enable_vfs301" = "yes"]) PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) @@ -298,6 +304,11 @@ if test x$enable_vfs101 != xno ; then else AC_MSG_NOTICE([ vfs101 driver disabled]) fi +if test x$enable_vfs301 != xno ; then + AC_MSG_NOTICE([** vfs301 driver enabled]) +else + AC_MSG_NOTICE([ vfs301 driver disabled]) +fi if test x$require_aeslib != xno ; then AC_MSG_NOTICE([** aeslib helper functions enabled]) else diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index fa0b54dd..96489e6d 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -13,6 +13,7 @@ AES4000_SRC = drivers/aes4000.c FDU2000_SRC = drivers/fdu2000.c VCOM5S_SRC = drivers/vcom5s.c VFS101_SRC = drivers/vfs101.c +VFS301_SRC = drivers/vfs301.c drivers/vfs301_proto.c drivers/vfs301_proto.h drivers/vfs301_proto_fragments.h EXTRA_DIST = \ $(UPEKE2_SRC) \ @@ -26,6 +27,7 @@ EXTRA_DIST = \ $(FDU2000_SRC) \ $(VCOM5S_SRC) \ $(VFS101_SRC) \ + $(VFS301_SRC) \ aeslib.c aeslib.h \ imagemagick.c \ gdkpixbuf.c \ @@ -130,6 +132,10 @@ if ENABLE_VFS101 DRIVER_SRC += $(VFS101_SRC) endif +if ENABLE_VFS301 +DRIVER_SRC += $(VFS301_SRC) +endif + if REQUIRE_IMAGEMAGICK OTHER_SRC += imagemagick.c libfprint_la_CFLAGS += $(IMAGING_CFLAGS) diff --git a/libfprint/core.c b/libfprint/core.c index 80cd4da1..3a430b7a 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -371,6 +371,9 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_VFS101 &vfs101_driver, #endif +#ifdef ENABLE_VFS301 + &vfs301_driver, +#endif /*#ifdef ENABLE_UPEKTC &upektc_driver, #endif diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c new file mode 100644 index 00000000..a27a945b --- /dev/null +++ b/libfprint/drivers/vfs301.c @@ -0,0 +1,306 @@ +/* + * vfs301/vfs300 fingerprint reader driver + * https://github.com/andree182/vfs301 + * + * Copyright (c) 2011-2012 Andrej Krutak + * + * 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 + */ + +#define FP_COMPONENT "vfs301" + +#include +#include +#include +#include +#include +#include +#include + +#include "vfs301_proto.h" +#include + +#include + +/************************** GENERIC STUFF *************************************/ + +/* Callback of asynchronous sleep */ +static void async_sleep_cb(void *data) +{ + struct fpi_ssm *ssm = data; + + fpi_ssm_next_state(ssm); +} + +/* Submit asynchronous sleep */ +static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct fpi_timeout *timeout; + + /* Add timeout */ + timeout = fpi_timeout_add(msec, async_sleep_cb, ssm); + + if (timeout == NULL) { + /* Failed to add timeout */ + fp_err("failed to add timeout"); + fpi_imgdev_session_error(dev, -ETIME); + fpi_ssm_mark_aborted(ssm, -ETIME); + } +} + +static int submit_image(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + vfs301_dev_t *vdev = dev->priv; + int height; + struct fp_img *img; + +#if 0 + /* XXX: This is probably handled by libfprint automagically? */ + if (vdev->scanline_count < 20) { + fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT); + return 0; + } +#endif + + img = fpi_img_new(VFS301_FP_OUTPUT_WIDTH * vdev->scanline_count); + if (img == NULL) + return 0; + + vfs301_extract_image(vdev, img->data, &height); + + /* TODO: how to detect flip? should the resulting image be + * oriented so that it is equal e.g. to a fingerprint on a paper, + * or to the finger when I look at it?) */ + img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED; + + img->width = VFS301_FP_OUTPUT_WIDTH; + img->height = height; + + img = fpi_img_resize(img, img->height * img->width); + fpi_imgdev_image_captured(dev, img); + + return 1; +} + +/* Loop ssm states */ +enum +{ + /* Step 0 - Scan finger */ + M_REQUEST_PRINT, + M_WAIT_PRINT, + M_CHECK_PRINT, + M_READ_PRINT_START, + M_READ_PRINT_WAIT, + M_READ_PRINT_POLL, + M_SUBMIT_PRINT, + + /* Number of states */ + M_LOOP_NUM_STATES, +}; + +/* Exec loop sequential state machine */ +static void m_loop_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + vfs301_dev_t *vdev = dev->priv; + + switch (ssm->cur_state) { + case M_REQUEST_PRINT: + vfs301_proto_request_fingerprint(dev->udev, vdev); + fpi_ssm_next_state(ssm); + break; + + case M_WAIT_PRINT: + /* Wait fingerprint scanning */ + async_sleep(200, ssm); + break; + + case M_CHECK_PRINT: + if (!vfs301_proto_peek_event(dev->udev, vdev)) + fpi_ssm_jump_to_state(ssm, M_WAIT_PRINT); + else + fpi_ssm_next_state(ssm); + break; + + case M_READ_PRINT_START: + fpi_imgdev_report_finger_status(dev, TRUE); + vfs301_proto_process_event_start(dev->udev, vdev); + fpi_ssm_next_state(ssm); + break; + + case M_READ_PRINT_WAIT: + /* Wait fingerprint scanning */ + async_sleep(200, ssm); + break; + + case M_READ_PRINT_POLL: + { + int rv = vfs301_proto_process_event_poll(dev->udev, vdev); + assert(rv != VFS301_FAILURE); + if (rv == VFS301_ONGOING) + fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT); + else + fpi_ssm_next_state(ssm); + } + break; + + case M_SUBMIT_PRINT: + if (submit_image(ssm)) { + fpi_ssm_mark_completed(ssm); + /* NOTE: finger off is expected only after submitting image... */ + fpi_imgdev_report_finger_status(dev, FALSE); + } else { + fpi_ssm_jump_to_state(ssm, M_REQUEST_PRINT); + } + break; + } +} + +/* Complete loop sequential state machine */ +static void m_loop_complete(struct fpi_ssm *ssm) +{ + /* Free sequential state machine */ + fpi_ssm_free(ssm); +} + +/* Exec init sequential state machine */ +static void m_init_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + vfs301_dev_t *vdev = dev->priv; + + assert(ssm->cur_state == 0); + + vfs301_proto_init(dev->udev, vdev); + + fpi_ssm_mark_completed(ssm); +} + +/* Complete init sequential state machine */ +static void m_init_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct fpi_ssm *ssm_loop; + + if (!ssm->error) { + /* Notify activate complete */ + fpi_imgdev_activate_complete(dev, 0); + + /* Start loop ssm */ + ssm_loop = fpi_ssm_new(dev->dev, m_loop_state, M_LOOP_NUM_STATES); + ssm_loop->priv = dev; + fpi_ssm_start(ssm_loop, m_loop_complete); + } + + /* Free sequential state machine */ + fpi_ssm_free(ssm); +} + +/* Activate device */ +static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +{ + struct fpi_ssm *ssm; + + /* Start init ssm */ + ssm = fpi_ssm_new(dev->dev, m_init_state, 1); + ssm->priv = dev; + fpi_ssm_start(ssm, m_init_complete); + + return 0; +} + +/* Deactivate device */ +static void dev_deactivate(struct fp_img_dev *dev) +{ + fpi_imgdev_deactivate_complete(dev); +} + +static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) +{ + vfs301_dev_t *vdev = NULL; + int r; + + /* Claim usb interface */ + r = libusb_claim_interface(dev->udev, 0); + if (r < 0) { + /* Interface not claimed, return error */ + fp_err("could not claim interface 0"); + return r; + } + + /* Set enroll stage number */ + dev->dev->nr_enroll_stages = 1; + + /* Initialize private structure */ + vdev = g_malloc0(sizeof(vfs301_dev_t)); + dev->priv = vdev; + + vdev->scanline_buf = malloc(0); + vdev->scanline_count = 0; + + /* Notify open complete */ + fpi_imgdev_open_complete(dev, 0); + + return 0; +} + +static void dev_close(struct fp_img_dev *dev) +{ + /* Release private structure */ + free(((vfs301_dev_t*)dev->priv)->scanline_buf); + g_free(dev->priv); + + /* Release usb interface */ + libusb_release_interface(dev->udev, 0); + + /* Notify close complete */ + fpi_imgdev_close_complete(dev); +} + +/* Usb id table of device */ +static const struct usb_id id_table[] = +{ + { .vendor = 0x138a, .product = 0x0005 /* vfs301 */ }, + { .vendor = 0x138a, .product = 0x0008 /* vfs300 */ }, + { 0, 0, 0, }, +}; + +/* Device driver definition */ +struct fp_img_driver vfs301_driver = +{ + /* Driver specification */ + .driver = + { + .id = 11, + .name = FP_COMPONENT, + .full_name = "Validity VFS301", + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + + /* Image specification */ + .flags = 0, + .img_width = VFS301_FP_WIDTH, + .img_height = -1, + .bz3_threshold = 24, + + /* Routine specification */ + .open = dev_open, + .close = dev_close, + .activate = dev_activate, + .deactivate = dev_deactivate, +}; diff --git a/libfprint/drivers/vfs301_proto.c b/libfprint/drivers/vfs301_proto.c new file mode 100644 index 00000000..238752c5 --- /dev/null +++ b/libfprint/drivers/vfs301_proto.c @@ -0,0 +1,639 @@ +/* + * vfs301/vfs300 fingerprint reader driver + * https://github.com/andree182/vfs301 + * + * Copyright (c) 2011-2012 Andrej Krutak + * + * 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 + */ + +/* + * TODO: + * - async communication everywhere :) + * - protocol decyphering + * - what is needed and what is redundant + * - is some part of the initial data the firmware? + * - describe some interesting structures better + */ +#include +#include +#include +#include +#include +#include +#include + +#include "vfs301_proto.h" +#include "vfs301_proto_fragments.h" +#include + +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +/************************** USB STUFF *****************************************/ + +#ifdef DEBUG +static void usb_print_packet(int dir, int rv, const unsigned char *data, int length) +{ + fprintf(stderr, "%s, rv %d, len %d\n", dir ? "send" : "recv", rv, length); + +#ifdef PRINT_VERBOSE + int i; + + for (i = 0; i < min(length, 128); i++) { + fprintf(stderr, "%.2X ", data[i]); + if (i % 8 == 7) + fprintf(stderr, " "); + if (i % 32 == 31) + fprintf(stderr, "\n"); + } +#endif + + fprintf(stderr, "\n"); +} +#endif + +static int usb_recv( + vfs301_dev_t *dev, + struct libusb_device_handle *devh, unsigned char endpoint, int max_bytes) +{ + assert(max_bytes <= sizeof(dev->recv_buf)); + + int r = libusb_bulk_transfer( + devh, endpoint, + dev->recv_buf, max_bytes, + &dev->recv_len, VFS301_DEFAULT_WAIT_TIMEOUT + ); + +#ifdef DEBUG + usb_print_packet(0, r, dev->recv_buf, dev->recv_len); +#endif + + if (r < 0) + return r; + return 0; +} + +static int usb_send( + struct libusb_device_handle *devh, const unsigned char *data, int length) +{ + int transferred = 0; + + int r = libusb_bulk_transfer( + devh, VFS301_SEND_ENDPOINT, + (unsigned char *)data, length, &transferred, VFS301_DEFAULT_WAIT_TIMEOUT + ); + +#ifdef DEBUG + usb_print_packet(1, r, data, length); +#endif + + assert(r == 0); + + if (r < 0) + return r; + if (transferred < length) + return r; + + return 0; +} + +/************************** OUT MESSAGES GENERATION ***************************/ + +static void vfs301_proto_generate_0B(int subtype, unsigned char *data, int *len) +{ + *data = 0x0B; + *len = 1; + data++; + + memset(data, 0, 39); + *len += 38; + + data[20] = subtype; + + switch (subtype) { + case 0x04: + data[34] = 0x9F; + break; + case 0x05: + data[34] = 0xAB; + len++; + break; + default: + assert(!"unsupported"); + break; + } +} + +#define HEX_TO_INT(c) \ + (((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10)) + +static void translate_str(const char **srcL, unsigned char *data, int *len) +{ + const char *src; + unsigned char *dataOrig = data; + + while (*srcL != NULL) { + src = *srcL; + while (*src != '\0') { + assert(*src != '\0'); + assert(*(src +1) != '\0'); + *data = (unsigned char)((HEX_TO_INT(*src) << 4) | (HEX_TO_INT(*(src + 1)))); + + data++; + src += 2; + } + + srcL++; + } + + *len = data - dataOrig; +} + +static void vfs301_proto_generate(int type, int subtype, unsigned char *data, int *len) +{ + switch (type) { + case 0x01: + case 0x04: + /* After cmd 0x04 is sent, a data is received on VALIDITY_RECEIVE_ENDPOINT_CTRL. + * If it is 0x0000: + * additional 64B and 224B are read from _DATA, then vfs301_next_scan_FA00 is + * sent, 0000 received from _CTRL, and then continue with wait loop + * If it is 0x1204: + * => reinit? + */ + case 0x17: + case 0x19: + case 0x1A: + *data = type; + *len = 1; + break; + case 0x0B: + vfs301_proto_generate_0B(subtype, data, len); + break; + case 0x02D0: + { + const char **dataLs[] = { + vfs301_02D0_01, + vfs301_02D0_02, + vfs301_02D0_03, + vfs301_02D0_04, + vfs301_02D0_05, + vfs301_02D0_06, + vfs301_02D0_07, + }; + assert((int)subtype <= (int)(sizeof(dataLs) / sizeof(dataLs[0]))); + translate_str(dataLs[subtype - 1], data, len); + } + break; + case 0x0220: + switch (subtype) { + case 1: + translate_str(vfs301_0220_01, data, len); + break; + case 2: + translate_str(vfs301_0220_02, data, len); + break; + case 3: + translate_str(vfs301_0220_03, data, len); + break; + case 0xFA00: + case 0x2C01: + case 0x5E01: + translate_str(vfs301_next_scan_template, data, len); + unsigned char *field = data + *len - (sizeof(S4_TAIL) - 1) / 2 - 4; + + assert(*field == 0xDE); + assert(*(field + 1) == 0xAD); + assert(*(field + 2) == 0xDE); + assert(*(field + 3) == 0xAD); + + *field = (unsigned char)((subtype >> 8) & 0xFF); + *(field + 1) = (unsigned char)(subtype & 0xFF); + *(field + 2) = *field; + *(field + 3) = *(field + 1); + break; + default: + assert(0); + break; + } + break; + case 0x06: + assert(!"Not generated"); + break; + default: + assert(!"Unknown message type"); + break; + } +} + +/************************** SCAN IMAGE PROCESSING *****************************/ + +#ifdef SCAN_FINISH_DETECTION +static int img_is_finished_scan(fp_line_t *lines, int no_lines) +{ + int i; + int j; + int rv = 1; + + for (i = no_lines - VFS301_FP_SUM_LINES; i < no_lines; i++) { + /* check the line for fingerprint data */ + for (j = 0; j < sizeof(lines[i].sum2); j++) { + if (lines[i].sum2[j] > (VFS301_FP_SUM_MEDIAN + VFS301_FP_SUM_EMPTY_RANGE)) + rv = 0; + } + } + + return rv; +} +#endif + +static int scanline_diff(const unsigned char *scanlines, int prev, int cur) +{ + const unsigned char *line1 = scanlines + prev * VFS301_FP_OUTPUT_WIDTH; + const unsigned char *line2 = scanlines + cur * VFS301_FP_OUTPUT_WIDTH; + int i; + int diff; + +#ifdef OUTPUT_RAW + /* We only need the image, not the surrounding stuff. */ + line1 = ((vfs301_line_t*)line1)->scan; + line2 = ((vfs301_line_t*)line2)->scan; +#endif + + /* TODO: This doesn't work too well when there are parallel lines in the + * fingerprint. */ + for (diff = 0, i = 0; i < VFS301_FP_WIDTH; i++) { + if (*line1 > *line2) + diff += *line1 - *line2; + else + diff += *line2 - *line1; + + line1++; + line2++; + } + + return ((diff / VFS301_FP_WIDTH) > VFS301_FP_LINE_DIFF_THRESHOLD); +} + +/** Transform the input data to a normalized fingerprint scan */ +void vfs301_extract_image( + vfs301_dev_t *vfs, unsigned char *output, int *output_height +) +{ + const unsigned char *scanlines = vfs->scanline_buf; + int last_line; + int i; + + assert(vfs->scanline_count >= 1); + + *output_height = 1; + memcpy(output, scanlines, VFS301_FP_OUTPUT_WIDTH); + last_line = 0; + + /* The following algorithm is quite trivial - it just picks lines that + * differ more than VFS301_FP_LINE_DIFF_THRESHOLD. + * TODO: A nicer approach would be to pick those lines and then do some kind + * of bi/tri-linear resampling to get the output (so that we don't get so + * many false edges etc.). + */ + for (i = 1; i < vfs->scanline_count; i++) { + if (scanline_diff(scanlines, last_line, i)) { + memcpy( + output + VFS301_FP_OUTPUT_WIDTH * (*output_height), + scanlines + VFS301_FP_OUTPUT_WIDTH * i, + VFS301_FP_OUTPUT_WIDTH + ); + last_line = i; + (*output_height)++; + } + } +} + +static int img_process_data( + int first_block, vfs301_dev_t *dev, const unsigned char *buf, int len +) +{ + vfs301_line_t *lines = (vfs301_line_t*)buf; + int no_lines = len / sizeof(vfs301_line_t); + int i; + /*int no_nonempty;*/ + unsigned char *cur_line; + int last_img_height; +#ifdef SCAN_FINISH_DETECTION + int finished_scan; +#endif + + if (first_block) { + last_img_height = 0; + dev->scanline_count = no_lines; + } else { + last_img_height = dev->scanline_count; + dev->scanline_count += no_lines; + } + + dev->scanline_buf = realloc(dev->scanline_buf, dev->scanline_count * VFS301_FP_OUTPUT_WIDTH); + assert(dev->scanline_buf != NULL); + + for (cur_line = dev->scanline_buf + last_img_height * VFS301_FP_OUTPUT_WIDTH, i = 0; + i < no_lines; + i++, cur_line += VFS301_FP_OUTPUT_WIDTH + ) { +#ifndef OUTPUT_RAW + memcpy(cur_line, lines[i].scan, VFS301_FP_OUTPUT_WIDTH); +#else + memcpy(cur_line, &lines[i], VFS301_FP_OUTPUT_WIDTH); +#endif + } + +#ifdef SCAN_FINISH_DETECTION + finished_scan = img_is_finished_scan(lines, no_lines); + + return !finished_scan; +#else /* SCAN_FINISH_DETECTION */ + return 1; /* Just continue until data is coming */ +#endif +} + +/************************** PROTOCOL STUFF ************************************/ + +static unsigned char usb_send_buf[0x2000]; + +#define USB_RECV(from, len) \ + usb_recv(dev, devh, from, len) + +#define USB_SEND(type, subtype) \ + { \ + int len; \ + vfs301_proto_generate(type, subtype, usb_send_buf, &len); \ + usb_send(devh, usb_send_buf, len); \ + } + +#define RAW_DATA(x) x, sizeof(x) + +#define IS_VFS301_FP_SEQ_START(b) ((b[0] == 0x01) && (b[1] == 0xfe)) + +static int vfs301_proto_process_data(int first_block, vfs301_dev_t *dev) +{ + int i; + const unsigned char *buf = dev->recv_buf; + int len = dev->recv_len; + + if (first_block) { + assert(len >= VFS301_FP_FRAME_SIZE); + + /* Skip bytes until start_sequence is found */ + for (i = 0; i < VFS301_FP_FRAME_SIZE; i++, buf++, len--) { + if (IS_VFS301_FP_SEQ_START(buf)) + break; + } + } + + return img_process_data(first_block, dev, buf, len); +} + +void vfs301_proto_request_fingerprint( + struct libusb_device_handle *devh, vfs301_dev_t *dev) +{ + USB_SEND(0x0220, 0xFA00); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 000000000000 */ +} + +int vfs301_proto_peek_event( + struct libusb_device_handle *devh, vfs301_dev_t *dev) +{ + const char no_event[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + const char got_event[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00}; + + USB_SEND(0x17, -1); + assert(USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 7) == 0); + + if (memcmp(dev->recv_buf, no_event, sizeof(no_event)) == 0) { + return 0; + } else if (memcmp(dev->recv_buf, got_event, sizeof(no_event)) == 0) { + return 1; + } else { + assert(!"unexpected reply to wait"); + } +} + +#define VARIABLE_ORDER(a, b) \ + { \ + int _rv = a;\ + b; \ + if (_rv == -7) \ + a; \ + } + +static void vfs301_proto_process_event_cb(struct libusb_transfer *transfer) +{ + vfs301_dev_t *dev = transfer->user_data; + struct libusb_device_handle *devh = transfer->dev_handle; + + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + dev->recv_progress = VFS301_FAILURE; + goto end; + } else if (transfer->actual_length < dev->recv_exp_amt) { + /* TODO: process the data anyway? */ + dev->recv_progress = VFS301_ENDED; + goto end; + } else { + dev->recv_len = transfer->actual_length; + if (!vfs301_proto_process_data(dev->recv_exp_amt == VFS301_FP_RECV_LEN_1, dev)) { + dev->recv_progress = VFS301_ENDED; + goto end; + } + + dev->recv_exp_amt = VFS301_FP_RECV_LEN_2; + libusb_fill_bulk_transfer( + transfer, devh, VFS301_RECEIVE_ENDPOINT_DATA, + dev->recv_buf, dev->recv_exp_amt, + vfs301_proto_process_event_cb, dev, VFS301_FP_RECV_TIMEOUT); + + if (libusb_submit_transfer(transfer) < 0) { + printf("cb::continue fail\n"); + dev->recv_progress = VFS301_FAILURE; + goto end; + } + return; + } + +end: + libusb_free_transfer(transfer); +} + +void vfs301_proto_process_event_start( + struct libusb_device_handle *devh, vfs301_dev_t *dev) +{ + struct libusb_transfer *transfer; + + /* + * Notes: + * + * seen next_scan order: + * o FA00 + * o FA00 + * o 2C01 + * o FA00 + * o FA00 + * o 2C01 + * o FA00 + * o FA00 + * o 2C01 + * o 5E01 !? + * o FA00 + * o FA00 + * o 2C01 + * o FA00 + * o FA00 + * o 2C01 + */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 64); + + /* now read the fingerprint data, while there are some */ + transfer = libusb_alloc_transfer(0); + if (!transfer) { + dev->recv_progress = VFS301_FAILURE; + return; + } + + dev->recv_progress = VFS301_ONGOING; + dev->recv_exp_amt = VFS301_FP_RECV_LEN_1; + + libusb_fill_bulk_transfer( + transfer, devh, VFS301_RECEIVE_ENDPOINT_DATA, + dev->recv_buf, dev->recv_exp_amt, + vfs301_proto_process_event_cb, dev, VFS301_FP_RECV_TIMEOUT); + + if (libusb_submit_transfer(transfer) < 0) { + libusb_free_transfer(transfer); + dev->recv_progress = VFS301_FAILURE; + return; + } +} + +int /* vfs301_dev_t::recv_progress */ vfs301_proto_process_event_poll( + struct libusb_device_handle *devh, vfs301_dev_t *dev) +{ + if (dev->recv_progress != VFS301_ENDED) + return dev->recv_progress; + + /* Finish the scan process... */ + + USB_SEND(0x04, -1); + /* the following may come in random order, data may not come at all, don't + * try for too long... */ + VARIABLE_ORDER( + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2), /* 1204 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 16384) + ); + + USB_SEND(0x0220, 2); + VARIABLE_ORDER( + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5760), /* seems to always come */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2) /* 0000 */ + ); + + return dev->recv_progress; +} + +void vfs301_proto_init(struct libusb_device_handle *devh, vfs301_dev_t *dev) +{ + USB_SEND(0x01, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38); + USB_SEND(0x0B, 0x04); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 6); /* 000000000000 */ + USB_SEND(0x0B, 0x05); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 7); /* 00000000000000 */ + USB_SEND(0x19, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 64); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 4); /* 6BB4D0BC */ + usb_send(devh, RAW_DATA(vfs301_06_1)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + + USB_SEND(0x01, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38); + USB_SEND(0x1A, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + usb_send(devh, RAW_DATA(vfs301_06_2)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_SEND(0x0220, 1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 256); + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 32); + + USB_SEND(0x1A, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + usb_send(devh, RAW_DATA(vfs301_06_3)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + + USB_SEND(0x01, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38); + USB_SEND(0x02D0, 1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 11648); /* 56 * vfs301_init_line_t[] */ + USB_SEND(0x02D0, 2); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 53248); /* 2 * 128 * vfs301_init_line_t[] */ + USB_SEND(0x02D0, 3); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 19968); /* 96 * vfs301_init_line_t[] */ + USB_SEND(0x02D0, 4); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5824); /* 28 * vfs301_init_line_t[] */ + USB_SEND(0x02D0, 5); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */ + USB_SEND(0x02D0, 6); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 6656); /* 32 * vfs301_init_line_t[] */ + USB_SEND(0x02D0, 7); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 832); + usb_send(devh, RAW_DATA(vfs301_12)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + + USB_SEND(0x1A, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + usb_send(devh, RAW_DATA(vfs301_06_2)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + USB_SEND(0x0220, 2); + VARIABLE_ORDER( + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2), /* 0000 */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5760) + ); + + USB_SEND(0x1A, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + usb_send(devh, RAW_DATA(vfs301_06_1)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + + USB_SEND(0x1A, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + usb_send(devh, RAW_DATA(vfs301_06_4)); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + usb_send(devh, RAW_DATA(vfs301_24)); /* turns on white */ + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2); /* 0000 */ + + USB_SEND(0x01, -1); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 38); + USB_SEND(0x0220, 3); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 2368); + USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 36); + USB_RECV(VFS301_RECEIVE_ENDPOINT_DATA, 5760); +} + +void vfs301_proto_deinit(struct libusb_device_handle *devh, vfs301_dev_t *dev) +{ +} diff --git a/libfprint/drivers/vfs301_proto.h b/libfprint/drivers/vfs301_proto.h new file mode 100644 index 00000000..daa629aa --- /dev/null +++ b/libfprint/drivers/vfs301_proto.h @@ -0,0 +1,137 @@ +/* + * vfs301/vfs300 fingerprint reader driver + * https://github.com/andree182/vfs301 + * + * Copyright (c) 2011-2012 Andrej Krutak + * + * 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 + */ +#include + +enum { + VFS301_DEFAULT_WAIT_TIMEOUT = 300, + + VFS301_SEND_ENDPOINT = 0x01, + VFS301_RECEIVE_ENDPOINT_CTRL = 0x81, + VFS301_RECEIVE_ENDPOINT_DATA = 0x82 +}; + +#define VFS301_FP_RECV_LEN_1 (84032) +#define VFS301_FP_RECV_LEN_2 (84096) + +typedef struct { + /* buffer for received data */ + unsigned char recv_buf[0x20000]; + int recv_len; + + /* buffer to hold raw scanlines */ + unsigned char *scanline_buf; + int scanline_count; + + enum { + VFS301_ONGOING = 0, + VFS301_ENDED = 1, + VFS301_FAILURE = -1 + } recv_progress; + int recv_exp_amt; +} vfs301_dev_t; + +enum { + /* Width of the scanned data in px */ + VFS301_FP_WIDTH = 200, + + /* sizeof(fp_line_t) */ + VFS301_FP_FRAME_SIZE = 288, + /* Width of output line */ +#ifndef OUTPUT_RAW + VFS301_FP_OUTPUT_WIDTH = VFS301_FP_WIDTH, +#else + VFS301_FP_OUTPUT_WIDTH = VFS301_FP_FRAME_SIZE, +#endif + + VFS301_FP_SUM_LINES = 3, + +#ifdef SCAN_FINISH_DETECTION + /* TODO: The following changes (seen ~60 and ~80) In that + * case we'll need to calibrate this from empty data somehow... */ + VFS301_FP_SUM_MEDIAN = 60, + VFS301_FP_SUM_EMPTY_RANGE = 5, +#endif + + /* Minimum average difference between returned lines */ + VFS301_FP_LINE_DIFF_THRESHOLD = 15, + + /* Maximum waiting time for a single fingerprint frame */ + VFS301_FP_RECV_TIMEOUT = 2000 +}; + +/* Arrays of this structure is returned during the initialization as a response + * to the 0x02D0 messages. + * It seems to be always the same - what is it for? Some kind of confirmation? + */ +typedef struct { + unsigned char sync_0x01; + unsigned char sync_0xfe; + + unsigned char counter_lo; + unsigned char counter_hi; /* FIXME ? */ + + unsigned char flags[3]; + + unsigned char sync_0x00; + + unsigned char scan[VFS301_FP_WIDTH]; +} vfs301_init_line_t; + +typedef struct { + unsigned char sync_0x01; + unsigned char sync_0xfe; + + unsigned char counter_lo; + unsigned char counter_hi; + + unsigned char sync_0x08[2]; /* XXX: always? 0x08 0x08 */ + /* 0x08 | 0x18 - Looks like 0x08 marks good quality lines */ + unsigned char flag_1; + unsigned char sync_0x00; + + unsigned char scan[VFS301_FP_WIDTH]; + + /* A offseted, stretched, inverted copy of scan... probably could + * serve finger motion speed detection? + * Seems to be subdivided to some 10B + 53B + 1B blocks */ + unsigned char mirror[64]; + + /* Some kind of sum of the scan, very low contrast */ + unsigned char sum1[2]; + unsigned char sum2[11]; + unsigned char sum3[3]; +} vfs301_line_t; + +void vfs301_proto_init(struct libusb_device_handle *devh, vfs301_dev_t *dev); +void vfs301_proto_deinit(struct libusb_device_handle *devh, vfs301_dev_t *dev); + +void vfs301_proto_request_fingerprint( + struct libusb_device_handle *devh, vfs301_dev_t *dev); + +/** returns 0 if no event is ready, or 1 if there is one... */ +int vfs301_proto_peek_event( + struct libusb_device_handle *devh, vfs301_dev_t *dev); +void vfs301_proto_process_event_start( + struct libusb_device_handle *devh, vfs301_dev_t *dev); +int vfs301_proto_process_event_poll( + struct libusb_device_handle *devh, vfs301_dev_t *dev); + +void vfs301_extract_image(vfs301_dev_t *vfs, unsigned char *output, int *output_height); diff --git a/libfprint/drivers/vfs301_proto_fragments.h b/libfprint/drivers/vfs301_proto_fragments.h new file mode 100644 index 00000000..c000441c --- /dev/null +++ b/libfprint/drivers/vfs301_proto_fragments.h @@ -0,0 +1,2631 @@ +/* + * vfs301/vfs300 fingerprint reader driver + * https://github.com/andree182/vfs301 + * + * Copyright (c) 2011-2012 Andrej Krutak + * + * 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 + */ + +/* There are many similar blocks in the data below, also the data are + * self-similar (looks like some config blocks? pokes like in vfs101?) */ + +/* Don't take the grouping below for granted - it's quite possible + * I missed some block start, or split data that should be together. + * It's quite challenging, this reverse engineering... :-) */ + +#define __01 0x88 /* sometimes also 0x87? depending on what? */ + +static const unsigned char vfs301_06_1[] = { /* 2401 B */ + 0x06, 0x00, 0x00, 0x54, 0x09, 0x00, 0x0F, 0x00, 0x60, + 0xD8, 0x0C, 0x00, 0x60, + 0xD4, 0x0C, 0x00, 0x60, + 0x18, 0x17, 0x00, 0x60, + 0x28, 0x17, 0x00, 0x60, + 0xC8, 0x0D, 0x00, 0x60, + 0x9C, 0x0B, 0x00, 0x60, + 0xD8, 0x16, 0x00, 0x60, + 0xDC, 0x16, 0x00, 0x60, + 0x00, 0x0E, 0x04, 0x30, 0xE0, 0x0C, 0x00, 0x60, + 0x07, 0x09, 0x00, 0x00, 0xFF, 0xF7, 0xFF, 0xFF, 0xCC, 0x08, 0x00, 0x60, + 0x02, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x48, 0x0D, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0xE0, 0x16, 0x00, 0x60, + 0x00, 0x12, 0x04, 0x30, 0xA5, 0xC2, 0x00, 0x00, 0xE4, 0x16, 0x00, 0x60, + 0xF0, 0x16, 0x00, 0x60, + 0x00, 0x0F, 0x04, 0x30, 0xB0, 0x0A, 0x00, 0x60, + 0x58, 0xB3, 0x04, 0x60, + 0x84, 0x05, 0x00, 0x60, + 0xA4, 0xED, 0x04, 0x60, + 0x8C, 0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x60, + 0x40, 0x08, 0x00, 0x00, 0x10, 0x03, 0x02, 0x28, 0x1C, 0x0E, 0x00, 0x60, + 0x30, 0x17, 0x00, 0x60, + 0x70, 0x0E, 0x00, 0x60, + + 0xFF, 0xFF, 0xFF, 0xBF, 0xFD, 0x0C, 0x00, + 0x60, 0xF8, 0x16, 0x00, 0x60, 0xA8, 0x0B, 0x00, + 0x60, 0x08, 0x17, 0x00, 0x60, 0x18, 0x0D, 0x00, + 0x60, 0x00, 0x9E, 0x00, 0x38, 0xDC, 0x0C, 0x00, + 0x60, 0x04, 0x17, 0x00, 0x60, 0x36, 0x41, 0x00, + 0xE5, 0x59, 0x00, 0xA5, 0x65, 0x00, 0xE5, 0x5C, + 0x00, 0x25, 0x66, 0x00, 0x25, 0x58, 0x00, 0x91, + 0xC0, 0x03, 0xA1, 0xC1, 0x03, 0x0C, 0x08, 0x89, + 0x0A, 0x82, 0x49, 0x00, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x61, 0x00, 0x0C, 0x96, 0x91, 0xC2, + 0x03, 0xB1, 0xC3, 0x03, 0x71, 0xC4, 0x03, 0xD8, + 0x1B, 0x16, 0x84, 0x07, 0xC2, 0x0D, 0x4E, 0xC0, + 0xC0, 0x74, 0xE2, 0xA0, 0x71, 0x47, 0x3E, 0x05, + 0x16, 0xDC, 0x0F, 0x47, 0xBE, 0x02, 0x16, 0x4C, + 0x13, 0xF2, 0xA4, 0x6B, 0x26, 0x1C, 0x6E, 0x82, + 0xCC, 0xFE, 0x16, 0x88, 0x07, 0x16, 0x25, 0x05, + 0xC2, 0x0D, 0x4E, 0x16, 0x2C, 0x08, 0x92, 0xCC, + 0xFE, 0x16, 0x59, 0x08, 0x60, 0xAC, 0xC0, 0x16, + 0xAA, 0x10, 0xC2, 0x2D, 0x10, 0xC2, 0x0C, 0x00, + 0xA2, 0xA4, 0x6D, 0x66, 0x6C, 0x02, 0x06, 0x03, + 0x00, 0xAD, 0x0D, 0x65, 0x3B, 0x00, 0xD1, 0xC3, + 0x03, 0xD8, 0x1D, 0x16, 0xAA, 0x07, 0x0C, 0x9C, + 0xE8, 0x07, 0x62, 0x4D, 0x4E, 0xA2, 0x5E, 0x00, + 0xC0, 0xF0, 0x74, 0x60, 0xFF, 0xC0, 0x16, 0xBF, + 0x0D, 0x0C, 0x38, 0xA1, 0xC5, 0x03, 0x91, 0xC6, + 0x03, 0x99, 0x2A, 0x82, 0x4D, 0x4E, 0x0C, 0x2A, + 0xA5, 0xC6, 0x29, 0x1D, 0xF0, 0x16, 0xCD, 0x13, + 0xE8, 0x07, 0xC2, 0xA4, 0x70, 0xC2, 0x5E, 0x00, + 0xC2, 0x0D, 0x4E, 0x06, 0xDE, 0xFF, 0x16, 0xD3, + 0xF8, 0x0C, 0x9C, 0x88, 0x07, 0x62, 0x4D, 0x4E, + 0xF2, 0x58, 0x00, 0x06, 0xE0, 0xFF, 0xC2, 0x1D, + 0x24, 0x37, 0xBC, 0x34, 0x98, 0x07, 0x62, 0x4D, + 0x4E, 0xF2, 0x59, 0x00, 0x46, 0xDD, 0xFF, 0x00, + 0x00, 0x47, 0xBE, 0x02, 0x86, 0xDD, 0xFF, 0x46, + 0x01, 0x00, 0xA2, 0x1D, 0x24, 0x16, 0x3A, 0xF7, + 0xE8, 0x07, 0xC2, 0xA4, 0x6C, 0xC2, 0x5E, 0x00, + 0x62, 0x4D, 0x4E, 0x0C, 0x9C, 0xC6, 0xD8, 0xFF, + 0x00, 0xC2, 0x0D, 0x4E, 0x06, 0xE2, 0xFF, 0x00, + 0x00, 0x16, 0x83, 0xF4, 0xFD, 0x0C, 0xF9, 0x01, + 0xC7, 0xB3, 0x03, 0x8D, 0x03, 0x89, 0x01, 0xA8, + 0xFD, 0xBD, 0x02, 0xC2, 0x21, 0x00, 0xA5, 0x80, + 0x2D, 0xB1, 0xC3, 0x03, 0xD8, 0x1B, 0xA8, 0x01, + 0xC8, 0xFD, 0xAA, 0xCC, 0xC9, 0xFD, 0xD8, 0x1B, + 0x92, 0x1D, 0x24, 0xE2, 0xA0, 0x71, 0xA0, 0x99, + 0xC0, 0x92, 0x5D, 0x24, 0x46, 0xC5, 0xFF, 0x00, + 0x00, 0xF2, 0xA0, 0x72, 0x8D, 0x03, 0x89, 0x01, + 0x40, 0xFF, 0xC0, 0x37, 0xBF, 0x03, 0x8D, 0x0F, + 0x89, 0x01, 0xBD, 0x02, 0xA2, 0x2D, 0x11, 0xC8, + 0x01, 0x4A, 0xAA, 0xE5, 0x7C, 0x2D, 0xE2, 0xA0, + 0x71, 0xC8, 0x01, 0xB1, 0xC3, 0x03, 0xCA, 0x22, + 0xC0, 0x33, 0xC0, 0xD8, 0x1B, 0xCA, 0x44, 0xC2, + 0x0D, 0x4E, 0x46, 0xB3, 0xFF, 0xA1, 0xC2, 0x03, + 0xE5, 0x70, 0x2D, 0xC6, 0xC9, 0xFF, 0xA2, 0x2D, + 0x11, 0x0C, 0x1E, 0xE2, 0x4D, 0x4E, 0x25, 0x5E, + 0x2D, 0xC1, 0xC3, 0x03, 0xC8, 0x1C, 0xBD, 0x0A, + 0xA2, 0x2C, 0x11, 0xB9, 0xBC, 0x4B, 0xAA, 0x25, + 0x5D, 0x2D, 0xD1, 0xC3, 0x03, 0xD2, 0x2D, 0x01, + 0xA2, 0x6D, 0x0C, 0xA2, 0x2D, 0x11, 0x65, 0x2E, + 0x2D, 0xB1, 0xC3, 0x03, 0xD8, 0x1B, 0x0C, 0x0E, + 0xA8, 0xBD, 0xE2, 0x6D, 0x11, 0xAC, 0xCA, 0xE5, + 0x22, 0x2D, 0xB1, 0xC3, 0x03, 0xF8, 0x1B, 0xA2, + 0x6F, 0x10, 0xD8, 0x1B, 0x92, 0x2D, 0x10, 0x16, + 0xE9, 0x04, 0x0C, 0x2C, 0x99, 0xFD, 0xD8, 0x1B, + 0x0C, 0x2A, 0xA2, 0x4D, 0x4E, 0x88, 0xBD, 0x82, + 0x5D, 0x24, 0xE2, 0xA0, 0x71, 0xC0, 0xC0, 0x74, + 0x46, 0x99, 0xFF, 0x00, 0x00, 0xC2, 0x0D, 0x4E, + 0x86, 0xFB, 0xFF, 0x00, 0x00, 0xAD, 0x09, 0x25, + 0x65, 0x2D, 0xA2, 0xA0, 0x72, 0xE5, 0x1E, 0x2D, + 0xB1, 0xC3, 0x03, 0xD8, 0x1B, 0xA2, 0x6D, 0x11, + 0xCC, 0xEA, 0x0C, 0x9C, 0x62, 0x4D, 0x4E, 0x88, + 0x07, 0xF2, 0xA4, 0x6A, 0xF2, 0x58, 0x00, 0x06, + 0x89, 0xFF, 0xC2, 0x0D, 0x4E, 0x86, 0x87, 0xFF, + 0x00, 0x0C, 0x9C, 0x62, 0x4D, 0x4E, 0xA8, 0x07, + 0x92, 0xA4, 0x6F, 0x92, 0x5A, 0x00, 0x06, 0xEC, + 0xFF, 0x36, 0x41, 0x00, 0x42, 0xC2, 0x20, 0x82, + 0xC2, 0x14, 0x91, 0xC7, 0x03, 0x8B, 0xB2, 0x7C, + 0xF3, 0x39, 0xD2, 0x49, 0x92, 0x49, 0x82, 0x89, + 0x62, 0x89, 0x52, 0x99, 0x42, 0xB9, 0x32, 0xB9, + 0x22, 0xA2, 0xC9, 0xFC, 0xA9, 0x72, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0xA2, 0x22, 0x10, 0x16, + 0x2A, 0x00, 0x25, 0x23, 0x2D, 0xA2, 0x22, 0x11, + 0x8C, 0x1A, 0xA5, 0x22, 0x2D, 0xA8, 0xD2, 0x26, + 0x0A, 0x02, 0xE5, 0x56, 0x21, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x20, 0xA2, 0x20, 0x65, + 0xA5, 0x2A, 0xA1, 0xC3, 0x03, 0xA2, 0x2A, 0x01, + 0xA2, 0xCA, 0x14, 0x65, 0x0E, 0x2D, 0xE5, 0x95, + 0x2A, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xC3, 0x03, 0xC8, 0x13, 0x0C, 0x05, 0x92, + 0x0C, 0x4E, 0x41, 0xC8, 0x03, 0x82, 0xC9, 0xFD, + 0x16, 0x68, 0x0B, 0x26, 0x49, 0x14, 0x21, 0xC9, + 0x03, 0x26, 0x59, 0x10, 0xA2, 0xC9, 0xFA, 0x16, + 0xFA, 0x07, 0xB2, 0xC9, 0xF9, 0x16, 0x4B, 0x0D, + 0x26, 0x89, 0x49, 0x1D, 0xF0, 0xA2, 0x2C, 0x10, + 0xE8, 0x12, 0xD8, 0x22, 0xD9, 0x03, 0xE2, 0x62, + 0x02, 0x16, 0x9A, 0x00, 0x25, 0x1C, 0x2D, 0xF8, + 0x13, 0x52, 0x6F, 0x10, 0xC8, 0x13, 0xC0, 0x20, + 0x00, 0xB2, 0xA2, 0x00, 0x81, 0xCA, 0x03, 0x82, + 0x64, 0x83, 0xA8, 0xCC, 0xA9, 0xEC, 0xE5, 0xA5, + 0x24, 0xA8, 0x13, 0x0C, 0x69, 0x92, 0x4A, 0x4E, + 0xA2, 0xA2, 0x00, 0xE5, 0x86, 0x2A, 0xA8, 0x13, + 0x8B, 0xAA, 0xA5, 0x0A, 0x00, 0xC0, 0x20, 0x00, + 0x52, 0x64, 0x80, 0x1D, 0xF0, 0xC0, 0x20, 0x00, + 0xC1, 0xCB, 0x03, 0xB2, 0x24, 0x83, 0xC0, 0x20, + 0x00, 0xC0, 0xBB, 0x10, 0xB2, 0x64, 0x83, 0x65, + 0xD5, 0x2A, 0xA8, 0x13, 0x8B, 0xAA, 0xE5, 0x06, + 0x2D, 0xA1, 0xC2, 0x03, 0x25, 0x56, 0x2D, 0x98, + 0x03, 0x16, 0xE9, 0xF8, 0x99, 0x22, 0x59, 0x03, + 0x1D, 0xF0, 0xA2, 0xCC, 0x20, 0xA5, 0x92, 0x2A, + 0x16, 0xFA, 0xF7, 0x22, 0xA0, 0x07, 0xB2, 0x0A, + 0x2C, 0xC2, 0x23, 0x01, 0x07, 0x6B, 0x02, 0x22, + 0x4C, 0x4E, 0x65, 0xA4, 0x24, 0xA8, 0x13, 0xA2, + 0xCA, 0x20, 0xE5, 0x90, 0x2A, 0x56, 0x5A, 0xFE, + 0x1D, 0xF0, 0x52, 0x63, 0x00, 0xA1, 0xCD, 0x03, + 0xB1, 0xCC, 0x03, 0xB2, 0x62, 0x02, 0x65, 0xB5, + 0x2A, 0xC0, 0x20, 0x00, 0x0C, 0x4C, 0xE1, 0xCE, + 0x03, 0xD2, 0x24, 0x83, 0xC0, 0x20, 0x00, 0xA8, + 0x13, 0xE0, 0xDD, 0x20, 0xD2, 0x64, 0x83, 0xC2, + 0x4A, 0x4E, 0xE5, 0x0C, 0x00, 0xAD, 0x02, 0xA5, + 0x9A, 0x29, 0x1D, 0xF0, 0x00, 0xA1, 0xCF, 0x03, + 0x25, 0x52, 0x2D, 0xC0, 0x20, 0x00, 0xA8, 0x13, + 0xF1, 0xD0, 0x03, 0xF2, 0x64, 0x83, 0x65, 0x1B, + 0x00, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xC3, 0x03, 0x82, 0x23, 0x01, 0x71, 0xD1, + 0x03, 0x82, 0x28, 0x0E, 0x62, 0xA0, 0x00, 0x16, + 0x68, 0x05, 0xE5, 0x76, 0x2A, 0x4D, 0x0A, 0x16, + 0x2A, 0x05, 0xA8, 0x13, 0x52, 0x14, 0x15, 0xA8, + 0xEA, 0x57, 0xBA, 0x01, 0x5D, 0x0A, 0xB1, 0xD2, + 0x03, 0xC8, 0x24, 0x0C, 0x0D, 0xF1, 0xD3, 0x03, + 0x50, 0xE0, 0xF4, 0xE2, 0x54, 0x14, 0x52, 0xC4, + 0x10, 0xAD, 0x05, 0xE5, 0x81, 0x21, 0x62, 0x44, + 0x2C, 0xD8, 0x13, 0xC2, 0x14, 0x14, 0xB8, 0xED, + 0xC0, 0xBB, 0xC0, 0xB9, 0xED, 0xCC, 0x8B, 0x79, + 0x34, 0x0C, 0x1D, 0xD2, 0x44, 0x2C, 0xD2, 0x23, + 0x01, 0xAD, 0x05, 0xB8, 0xDD, 0x0C, 0x1C, 0x25, + 0xAD, 0x21, 0xE8, 0x13, 0xE8, 0xEE, 0x56, 0x8E, + 0xFA, 0x1D, 0xF0, 0x00, 0x00, 0xAD, 0x02, 0x65, + 0x72, 0x2A, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0xB2, 0xC2, 0xF0, 0xA2, 0xC3, 0x20, 0xA5, 0x7F, + 0x2A, 0xA2, 0xC3, 0x14, 0xE5, 0xF3, 0x2C, 0x1D, + 0xF0, 0x36, 0x41, 0x00, 0x0C, 0x0A, 0xBD, 0x02, + 0xC1, 0xD4, 0x03, 0x65, 0x9B, 0x21, 0xA9, 0xD2, + 0x26, 0x0A, 0x05, 0x0C, 0x02, 0x1D, 0xF0, 0x00, + 0x00, 0x22, 0xA4, 0x6E, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xA2, 0xA0, 0x03, 0xB1, + 0xD5, 0x03, 0xE5, 0xEA, 0x2C, 0x92, 0xA0, 0x60, + 0x81, 0xC8, 0x03, 0xB8, 0xB2, 0xA2, 0x22, 0x10, + 0xA9, 0xF2, 0xB2, 0x52, 0x26, 0xB2, 0x52, 0x25, + 0x0C, 0x8B, 0xC0, 0x20, 0x00, 0xF2, 0x28, 0x81, + 0xC0, 0x20, 0x00, 0xE8, 0xF2, 0x90, 0xFF, 0x20, + 0xF2, 0x68, 0x81, 0xE2, 0x0E, 0x00, 0xC0, 0x20, + 0x00, 0xC8, 0xF2, 0xF1, 0xD6, 0x03, 0x1B, 0xCC, + 0xE2, 0x5F, 0x80, 0xD2, 0x12, 0x25, 0xC9, 0xF2, + 0x0B, 0xDD, 0xD2, 0x52, 0x25, 0x80, 0x61, 0x00, + 0x9D, 0x08, 0xA0, 0xE4, 0x03, 0xB0, 0xAA, 0x20, + 0xA0, 0xE4, 0x13, 0x80, 0xE6, 0x13, 0x10, 0x20, + 0x00, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x61, 0x00, + 0xC0, 0x20, 0x00, 0xC1, 0xD6, 0x03, 0xF1, 0xC8, + 0x03, 0xE1, 0xC3, 0x03, 0xA2, 0x2F, 0x82, 0xB8, + 0x1E, 0x17, 0x6A, 0x14, 0x92, 0x1B, 0x26, 0x16, + 0xE9, 0x00, 0x82, 0xC9, 0xFF, 0xC0, 0x20, 0x00, + 0xD2, 0x1C, 0x80, 0xD2, 0x51, 0x00, 0x82, 0x5B, + 0x26, 0x92, 0x1B, 0x25, 0x07, 0xEA, 0x07, 0x8C, + 0xA9, 0x82, 0x0B, 0x4E, 0x26, 0x48, 0x41, 0x8C, + 0x29, 0x1D, 0xF0, 0x00, 0x00, 0x92, 0x1B, 0x26, + 0x56, 0x59, 0xFF, 0xC0, 0x20, 0x00, 0x0C, 0x5D, + 0x92, 0xAF, 0x9F, 0x82, 0x2F, 0x81, 0xC0, 0x20, + 0x00, 0x90, 0x88, 0x10, 0x82, 0x6F, 0x81, 0x7C, + 0x7F, 0xA0, 0x61, 0x00, 0xCD, 0x0A, 0xE0, 0xE4, + 0x03, 0xF0, 0xEE, 0x10, 0xE0, 0xE4, 0x13, 0xA0, + 0xE6, 0x13, 0x10, 0x20, 0x00, 0xD2, 0x4B, 0x4E, + 0xA2, 0xCB, 0x14, 0xE5, 0xE3, 0x2C, 0x1D, 0xF0, + 0x00, 0xD8, 0xFB, 0xD2, 0x0D, 0x00, 0xC0, 0x20, + 0x00, 0xA8, 0xFB, 0xD2, 0x5C, 0x80, 0x1B, 0xAA, + 0xA9, 0xFB, 0xB8, 0x1E, 0x92, 0x1B, 0x25, 0x0B, + 0x99, 0x90, 0x90, 0xF4, 0x92, 0x5B, 0x25, 0x06, + 0xE7, 0xFF, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x92, 0xA0, 0x06, 0xB1, 0xC8, 0x03, 0xC0, 0x20, + 0x00, 0x82, 0x2B, 0x82, 0x0C, 0x0A, 0x17, 0x68, + 0x0B, 0x92, 0xC9, 0xFF, 0xC0, 0x20, 0x00, 0xC2, + 0x2B, 0x80, 0x56, 0x89, 0xFE, 0xC0, 0x20, 0x00, + 0xA2, 0xC2, 0x14, 0x0C, 0x8D, 0xE2, 0xA0, 0x04, + 0xE2, 0x6B, 0x84, 0xD2, 0x42, 0x4E, 0x25, 0xDE, + 0x2C, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xD7, 0x03, 0x21, 0xD8, 0x03, 0x22, 0x63, + 0x75, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xA1, 0xD9, 0x03, 0xB1, 0xDA, 0x03, 0xC1, 0xDB, + 0x03, 0xE5, 0x37, 0x2D, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x16, 0xA5, 0x01, 0x20, + 0x61, 0x00, 0x25, 0xA4, 0xFF, 0x20, 0xE6, 0x13, + 0x10, 0x20, 0x00, 0xA2, 0xA0, 0x00, 0x65, 0x72, + 0x29, 0xA1, 0xDC, 0x03, 0xB1, 0xDD, 0x03, 0xE5, + 0xFF, 0x2C, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0xA1, 0xDE, 0x03, 0xB1, 0xDE, 0x03, 0x65, 0xFC, + 0x20, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xCD, 0x04, 0x81, 0xDF, 0x03, 0xBD, 0x03, 0x88, + 0x08, 0xAD, 0x02, 0xCC, 0xF8, 0x8C, 0xD3, 0xD1, + 0xC9, 0x03, 0xF1, 0xE0, 0x03, 0x98, 0x1D, 0xE8, + 0x2D, 0xE9, 0x0F, 0x92, 0x6D, 0x02, 0xE5, 0x65, + 0x29, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xC1, 0xE0, 0x03, 0xAD, 0x02, 0x98, 0x0C, 0x0C, + 0x0B, 0x8C, 0x59, 0x81, 0xC9, 0x03, 0xB9, 0x0C, + 0x99, 0x28, 0xE5, 0x70, 0x29, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xD1, 0xE2, 0x03, 0x91, + 0xE3, 0x03, 0xB0, 0x82, 0x11, 0xA1, 0xE1, 0x03, + 0xB2, 0xAE, 0xF0, 0xBA, 0xAA, 0xAA, 0xA8, 0x9A, + 0x88, 0xC8, 0x0A, 0xC0, 0x20, 0x00, 0xB8, 0x7C, + 0xC0, 0x20, 0x00, 0xD0, 0xBB, 0x10, 0xB9, 0x7C, + 0x82, 0x08, 0x7F, 0x0C, 0x09, 0x8C, 0x18, 0xE5, + 0x5B, 0x21, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0x21, 0xE4, 0x03, 0x31, 0xE5, 0x03, 0x28, 0x22, + 0x29, 0x03, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0x21, 0xE6, 0x03, 0x88, 0x02, 0x27, 0x98, 0x02, + 0x1D, 0xF0, 0x00, 0x20, 0xA2, 0x20, 0x25, 0x08, + 0x00, 0xAD, 0x02, 0xE5, 0xC5, 0x20, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x20, 0x61, 0x00, 0xA1, + 0xE6, 0x03, 0xE5, 0xC4, 0x20, 0xA5, 0x0B, 0x24, + 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x41, 0xE7, 0x03, 0x21, + 0xE8, 0x03, 0xC0, 0x20, 0x00, 0x32, 0x22, 0x81, + 0x98, 0x54, 0x88, 0x34, 0x30, 0x99, 0x20, 0x99, + 0x54, 0x87, 0x83, 0x39, 0x0C, 0x1C, 0xB2, 0xA0, + 0x38, 0xA2, 0x24, 0x04, 0xC0, 0x20, 0x00, 0xB0, + 0xAA, 0x10, 0xA2, 0x62, 0x80, 0xC0, 0x20, 0x00, + 0xD2, 0x22, 0x81, 0xD0, 0xE0, 0x04, 0x07, 0xED, + 0xF3, 0xC0, 0x20, 0x00, 0xB1, 0xE9, 0x03, 0x32, + 0x62, 0x81, 0xC0, 0x20, 0x00, 0xB8, 0x0B, 0xA1, + 0xEA, 0x03, 0x1B, 0xBB, 0xB9, 0x4A, 0x4B, 0xAA, + 0xA5, 0xBD, 0x20, 0x1D, 0xF0, 0x00, 0x0C, 0x0C, + 0xC9, 0x34, 0xE5, 0xC4, 0x21, 0xC6, 0xEE, 0xFF, + 0x00, 0x36, 0x41, 0x00, 0x20, 0x61, 0x00, 0x3C, + 0x8A, 0x0C, 0x0B, 0x65, 0x08, 0x24, 0x20, 0xE6, + 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x1F, 0x00, 0x00, 0x00, 0xD0, 0x0F, 0x02, + 0x60, 0xD8, 0x11, 0x02, 0x60, 0x00, 0x12, 0x02, + 0x60, 0x3C, 0x12, 0x02, 0x60, 0x54, 0x13, 0x02, + 0x60, 0x20, 0x12, 0x02, 0x60, 0xCC, 0x13, 0x02, + 0x60, 0xE0, 0x13, 0x02, 0x60, 0x00, 0x14, 0x02, + 0x60, 0x64, 0x14, 0x02, 0x60, 0x04, 0x15, 0x02, + 0x60, 0xC8, 0x16, 0x00, 0x60, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x16, 0x02, + 0x60, 0x08, 0x17, 0x00, 0x60, 0x08, 0x17, 0x00, + 0x60, 0x04, 0x17, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xD0, 0x16, 0x00, 0x60, 0xD4, 0x16, 0x00, + 0x60, 0x2C, 0x17, 0x00, 0x60, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x0C, 0x00, + 0x60, 0xD4, 0x0C, 0x00, 0x60, 0x19, 0x30, 0x00, + 0x00, 0x40, 0x17, 0x00, 0x60, 0x10, 0x01, 0x00, + 0x00, 0xB0, 0x0A, 0x00, 0x60, 0x60, 0x15, 0x02, + 0x60, 0x34, 0x0D, 0x00, 0x60, 0x10, 0x03, 0x02, + 0x28, 0x18, 0x00, 0x02, 0x28, 0x14, 0x03, 0x02, + 0x28, 0xBC, 0x08, 0x00, 0x60, 0x94, 0x15, 0x02, + 0x60, 0xBC, 0x15, 0x02, 0x60, 0xA4, 0x05, 0x00, + 0x60, 0xD8, 0x15, 0x02, 0x60, 0xA8, 0x0B, 0x00, + 0x60, 0xF8, 0x16, 0x00, 0x60, 0xAC, 0x06, 0x00, + 0x60, 0x38, 0x16, 0x02, 0x60, 0x50, 0x16, 0x02, + 0x60, 0xD8, 0x56, 0x04, 0x60, 0x36, 0x41, 0x00, + 0x81, 0xCF, 0x05, 0xB1, 0xCD, 0x05, 0xA2, 0xA0, + 0x03, 0x91, 0xCE, 0x05, 0xA2, 0x4B, 0x00, 0x82, + 0x69, 0x00, 0xE5, 0x01, 0x00, 0xA5, 0x08, 0x00, + 0x25, 0x05, 0x00, 0x25, 0x06, 0x00, 0x25, 0x02, + 0x00, 0xA5, 0x06, 0x00, 0xA1, 0xD0, 0x05, 0xB1, + 0xD1, 0x05, 0x25, 0xDC, 0x2C, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xD2, 0x05, 0x21, + 0xD3, 0x05, 0x22, 0x63, 0x75, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x91, 0xD4, 0x05, 0x92, + 0x09, 0x47, 0x26, 0x19, 0x04, 0x26, 0x29, 0x0C, + 0x1D, 0xF0, 0xA1, 0xD5, 0x05, 0xB1, 0xD6, 0x05, + 0xE5, 0xD6, 0x20, 0x1D, 0xF0, 0xA1, 0xD5, 0x05, + 0xB1, 0xD7, 0x05, 0x25, 0xD6, 0x20, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x81, 0xD9, 0x05, 0x31, + 0xD8, 0x05, 0x21, 0xDA, 0x05, 0x29, 0x43, 0x89, + 0x03, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xDB, 0x05, 0x21, 0xDC, 0x05, 0x22, 0x63, + 0x13, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xDD, 0x05, 0x21, 0xDE, 0x05, 0x48, 0x03, + 0x49, 0x22, 0x29, 0x03, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x91, 0xE0, 0x05, 0x21, + 0xE2, 0x05, 0x31, 0xDF, 0x05, 0x81, 0xE1, 0x05, + 0x89, 0xC3, 0x29, 0xA3, 0x99, 0xB3, 0x1D, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x04, 0x00, 0x8C, 0x17, 0x02, + 0x60, +}; + +static const unsigned char vfs301_06_2[] = { /* 1905 B */ + 0x06, 0x00, 0x00, 0x64, 0x07, 0x00, 0x0F, 0x00, + 0x60, 0xD8, 0x0C, 0x00, 0x60, 0xD4, 0x0C, 0x00, + 0x60, 0x50, 0x15, 0x00, 0x60, 0x20, 0x0E, 0x00, + 0x60, 0xFC, 0xFF, 0x00, 0x00, 0x30, 0x15, 0x00, + 0x60, 0xB0, 0x0A, 0x00, 0x60, 0x58, 0xB3, 0x04, + 0x60, 0x84, 0x05, 0x00, 0x60, 0xA4, 0xED, 0x04, + 0x60, 0x8C, 0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x60, 0x60, 0x06, 0x00, 0x00, 0xA0, 0x0A, 0x00, + 0x60, 0xD0, 0x38, 0x04, 0x60, 0xB4, 0x39, 0x04, + 0x60, 0x58, 0xB4, 0x04, 0x60, 0xFC, 0x0C, 0x00, + 0x60, 0x20, 0x15, 0x00, 0x60, 0xC8, 0x0D, 0x00, + 0x60, 0x9C, 0x0B, 0x00, 0x60, 0xFC, 0x14, 0x00, + 0x60, 0xCC, 0x08, 0x00, 0x60, 0x68, 0x0A, 0x00, + 0x60, 0x4C, 0x3F, 0x04, 0x60, 0xC0, 0x0D, 0x00, + 0x60, 0x04, 0x15, 0x00, 0x60, 0x18, 0x0D, 0x00, + 0x60, 0x00, 0x9E, 0x00, 0x38, 0xDC, 0x0C, 0x00, + 0x60, 0x00, 0x15, 0x00, 0x60, 0x36, 0x41, 0x00, + 0x25, 0x37, 0x00, 0x65, 0x3A, 0x00, 0xA5, 0x4C, + 0x00, 0xE5, 0x48, 0x00, 0x65, 0x35, 0x00, 0x91, + 0xC0, 0x03, 0xA1, 0xC1, 0x03, 0x0C, 0x08, 0x89, + 0x0A, 0x82, 0x49, 0x00, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xC2, 0x03, 0x38, + 0x03, 0x8C, 0x73, 0x88, 0x23, 0x66, 0x28, 0x03, + 0x0C, 0x39, 0x99, 0x23, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xC3, 0x03, 0x0C, + 0x02, 0x22, 0x43, 0x00, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xBD, 0x02, 0x21, 0xC2, + 0x03, 0x28, 0x02, 0x1C, 0x8C, 0xCB, 0xA2, 0xA5, + 0x8F, 0x2D, 0xD1, 0xC4, 0x03, 0x2C, 0x0B, 0x92, + 0x12, 0x11, 0x0C, 0x1C, 0xDC, 0x79, 0xA2, 0x12, + 0x0F, 0x92, 0x12, 0x0E, 0xA0, 0xA0, 0xE4, 0x90, + 0xAA, 0xC0, 0xA2, 0xCA, 0xC2, 0xA0, 0xA1, 0x21, + 0xAA, 0x99, 0x8B, 0x99, 0x92, 0x52, 0x11, 0xB2, + 0x52, 0x13, 0xC9, 0x22, 0xD0, 0xD9, 0x10, 0xD2, + 0x52, 0x11, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0xD8, 0x22, 0x31, 0xC2, 0x03, 0x0C, 0x1E, 0x38, + 0x03, 0x0C, 0x0C, 0xAD, 0x03, 0xF2, 0x13, 0x13, + 0xB2, 0x13, 0x10, 0xF0, 0xCE, 0x83, 0xDA, 0xBB, + 0x25, 0x17, 0x00, 0x0C, 0x45, 0xA8, 0x23, 0x92, + 0x13, 0x13, 0x0C, 0x04, 0x8C, 0x69, 0x0B, 0x99, + 0x90, 0x90, 0xF4, 0x92, 0x53, 0x13, 0xF6, 0x8A, + 0x2F, 0xB1, 0xC5, 0x03, 0xB0, 0xBA, 0xA0, 0xB8, + 0x0B, 0xA0, 0x0B, 0x00, 0xC8, 0x22, 0xB2, 0x13, + 0x11, 0xAD, 0x03, 0xCA, 0xBB, 0x65, 0x21, 0x00, + 0xD2, 0x13, 0x06, 0xF1, 0xC3, 0x03, 0xD7, 0x3A, + 0x0F, 0x0C, 0x29, 0x92, 0x4F, 0x00, 0xE2, 0x13, + 0x0F, 0xE0, 0xEF, 0x04, 0x16, 0xBE, 0x10, 0x99, + 0x23, 0x0C, 0x14, 0x2D, 0x04, 0x1D, 0xF0, 0x49, + 0x23, 0x0C, 0x24, 0x06, 0xFD, 0xFF, 0xAD, 0x03, + 0xE5, 0x1B, 0x00, 0x82, 0x13, 0x09, 0xB2, 0x13, + 0x08, 0x87, 0x3A, 0x02, 0x06, 0x24, 0x00, 0xC8, + 0x22, 0xB2, 0x13, 0x11, 0xAD, 0x03, 0xCA, 0xBB, + 0x65, 0x1D, 0x00, 0xD2, 0x13, 0x07, 0xD7, 0x3A, + 0x02, 0xC6, 0x36, 0x00, 0xE2, 0x13, 0x14, 0x0B, + 0xEE, 0xE0, 0xE0, 0xF4, 0xE2, 0x53, 0x14, 0x56, + 0xEE, 0x0D, 0x0C, 0x24, 0x0C, 0x7F, 0xF9, 0x23, + 0xC6, 0xED, 0xFF, 0xAD, 0x03, 0xE5, 0x17, 0x00, + 0x82, 0x13, 0x08, 0x87, 0x3A, 0x6A, 0x59, 0x23, + 0x42, 0x53, 0x16, 0x92, 0x13, 0x0A, 0x92, 0x53, + 0x14, 0x0C, 0x04, 0x06, 0xE7, 0xFF, 0xAD, 0x03, + 0x65, 0x16, 0x00, 0xB2, 0x13, 0x08, 0xB7, 0x3A, + 0x29, 0xC2, 0x13, 0x14, 0x0B, 0xCC, 0xC0, 0xC0, + 0xF4, 0xC2, 0x53, 0x14, 0xEC, 0xBC, 0x0C, 0x6D, + 0xE2, 0x13, 0x0B, 0xE2, 0x53, 0x14, 0xD9, 0x23, + 0xC6, 0x07, 0x00, 0xDC, 0xC9, 0x59, 0x23, 0x42, + 0x53, 0x16, 0xF2, 0x13, 0x0A, 0xF2, 0x53, 0x14, + 0xC6, 0x03, 0x00, 0x0C, 0x58, 0x92, 0x13, 0x0D, + 0xA2, 0x13, 0x0C, 0xA2, 0x53, 0x14, 0x92, 0x53, + 0x15, 0x89, 0x23, 0x0C, 0x04, 0x86, 0xD4, 0xFF, + 0xB7, 0x3A, 0x05, 0xC2, 0x13, 0x0B, 0xC2, 0x53, + 0x14, 0x42, 0x53, 0x16, 0x0C, 0x04, 0x46, 0xD0, + 0xFF, 0x92, 0x13, 0x15, 0x66, 0x19, 0x09, 0x0C, + 0x34, 0x0B, 0xD9, 0xD2, 0x53, 0x15, 0x46, 0xCC, + 0xFF, 0xCC, 0x39, 0x0C, 0x14, 0x86, 0x01, 0x00, + 0x0C, 0x04, 0x0B, 0xE9, 0xE2, 0x53, 0x15, 0xC8, + 0x22, 0xB2, 0x13, 0x11, 0xAD, 0x03, 0xCA, 0xBB, + 0x65, 0x11, 0x00, 0xD2, 0x13, 0x07, 0xD7, 0xBA, + 0x10, 0xE2, 0x13, 0x14, 0x0B, 0xEE, 0xE0, 0xE0, + 0xF4, 0xE2, 0x53, 0x14, 0xE0, 0x45, 0x83, 0x06, + 0xC0, 0xFF, 0xF2, 0x13, 0x0D, 0xF2, 0x53, 0x14, + 0xC6, 0xBD, 0xFF, 0x0C, 0x39, 0x86, 0xBB, 0xFF, + 0x82, 0x13, 0x06, 0x87, 0x3A, 0x05, 0x92, 0x13, + 0x0B, 0x92, 0x53, 0x14, 0x0C, 0x04, 0x46, 0xB8, + 0xFF, 0x0C, 0x04, 0x06, 0xB7, 0xFF, 0x00, 0x00, + 0x00, 0x36, 0x61, 0x00, 0xB2, 0xA0, 0x94, 0xA2, + 0xC2, 0x34, 0x92, 0xC2, 0x54, 0x99, 0x01, 0xA9, + 0x11, 0xBC, 0xB4, 0x68, 0x11, 0x5D, 0x09, 0x1C, + 0x04, 0x72, 0x12, 0x12, 0x82, 0xA0, 0x94, 0xC0, + 0x77, 0x11, 0x7A, 0x72, 0x8A, 0x77, 0x82, 0x16, + 0x00, 0xB2, 0x07, 0x00, 0x1B, 0x77, 0xAD, 0x0B, + 0xB0, 0x88, 0xC0, 0x82, 0x56, 0x00, 0x2B, 0x66, + 0x65, 0x96, 0x2D, 0x98, 0x05, 0x0B, 0x44, 0xA0, + 0x99, 0xC0, 0x99, 0x05, 0x4B, 0x55, 0x56, 0xC4, + 0xFD, 0x98, 0x01, 0xA8, 0x11, 0xB2, 0xA0, 0x94, + 0x5D, 0x09, 0x6D, 0x0A, 0x72, 0x12, 0x12, 0x1C, + 0x04, 0xC0, 0x77, 0x11, 0x7A, 0x72, 0xBA, 0x77, + 0xD2, 0x03, 0x01, 0xE2, 0x03, 0x03, 0xC2, 0x03, + 0x02, 0xB2, 0x03, 0x00, 0xEA, 0xCC, 0xDA, 0xBB, + 0xCA, 0xBB, 0xB0, 0xB2, 0x41, 0xAD, 0x0B, 0xB2, + 0x47, 0x00, 0x82, 0x16, 0x00, 0x1B, 0x77, 0xBA, + 0x88, 0x82, 0x56, 0x00, 0x2B, 0x66, 0x65, 0x91, + 0x2D, 0x8B, 0x33, 0xF8, 0x05, 0x0B, 0x44, 0xAA, + 0xFF, 0xF9, 0x05, 0x4B, 0x55, 0x56, 0x74, 0xFC, + 0x82, 0x12, 0x12, 0x1B, 0x88, 0x80, 0x80, 0x44, + 0x82, 0x52, 0x12, 0x1D, 0xF0, 0x36, 0x41, 0x00, + 0x32, 0xC2, 0x34, 0x1C, 0x05, 0x0C, 0x04, 0xB2, + 0x13, 0x00, 0xAD, 0x0B, 0xA5, 0x8E, 0x2D, 0x2B, + 0x33, 0x0B, 0x55, 0xA0, 0x95, 0x41, 0x82, 0x22, + 0x15, 0x4B, 0x22, 0x90, 0x88, 0xC0, 0x80, 0x85, + 0x41, 0x8A, 0x44, 0x56, 0x05, 0xFE, 0x40, 0x24, + 0x41, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x1C, 0x07, 0x0C, 0x06, 0x0C, 0x05, 0xB2, 0xC3, + 0x81, 0x42, 0x03, 0x00, 0xB2, 0x0B, 0x7E, 0xC2, + 0x03, 0x01, 0x47, 0xBB, 0x0C, 0x47, 0xBC, 0x11, + 0x4D, 0x0B, 0xC7, 0xBB, 0x0C, 0x4D, 0x0C, 0xC6, + 0x01, 0x00, 0x47, 0x3C, 0x04, 0xC7, 0xBB, 0x01, + 0x4D, 0x0B, 0xAD, 0x04, 0xBD, 0x04, 0x65, 0x89, + 0x2D, 0xAA, 0x66, 0x5A, 0x54, 0x0B, 0x77, 0x4B, + 0x33, 0xB2, 0xC3, 0x81, 0x56, 0x97, 0xFC, 0xAD, + 0x05, 0xBD, 0x05, 0x25, 0x88, 0x2D, 0xD2, 0x12, + 0x16, 0xA0, 0x94, 0x41, 0x90, 0x96, 0xC0, 0xD0, + 0xCD, 0xF0, 0x90, 0x94, 0x41, 0x90, 0xE3, 0x41, + 0xC0, 0xC3, 0x21, 0xEA, 0xCC, 0xD0, 0x9C, 0x93, + 0x92, 0x52, 0x16, 0x2D, 0x09, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xC6, 0x03, 0x21, + 0xC7, 0x03, 0x22, 0x63, 0x75, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xA1, 0xC8, 0x03, 0xB1, + 0xC9, 0x03, 0xC1, 0xCA, 0x03, 0xA5, 0x5D, 0x2D, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x9C, 0x85, 0x20, 0x61, 0x00, 0xE5, 0xC6, 0xFF, + 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, 0x0C, 0x0A, + 0x65, 0x98, 0x29, 0xA1, 0xCB, 0x03, 0xB1, 0xCC, + 0x03, 0xA5, 0x25, 0x2D, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x0C, 0xBB, 0x31, 0xC6, + 0x03, 0x21, 0xD0, 0x03, 0x81, 0xCF, 0x03, 0x91, + 0xCD, 0x03, 0xA1, 0xCE, 0x03, 0xA9, 0xF9, 0x82, + 0x69, 0x19, 0x22, 0x63, 0x6B, 0xB2, 0x59, 0x1C, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x21, 0xD1, 0x03, 0x88, 0x22, 0x37, 0x68, 0x0E, + 0xA1, 0xD2, 0x03, 0xA5, 0x4D, 0x2D, 0x98, 0x22, + 0x6C, 0x7A, 0xA0, 0x99, 0x10, 0x99, 0x22, 0xE5, + 0x79, 0x22, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0xCD, 0x04, 0xBD, 0x03, 0xAD, 0x02, 0xDD, 0x05, + 0x25, 0x0E, 0x2A, 0xAC, 0x15, 0x81, 0xD3, 0x03, + 0xA1, 0xD4, 0x03, 0x88, 0x08, 0x91, 0xD1, 0x03, + 0x82, 0x08, 0x02, 0x98, 0x29, 0xB6, 0x28, 0x06, + 0x91, 0xD5, 0x03, 0x99, 0x2A, 0x1D, 0xF0, 0x37, + 0x69, 0x05, 0x91, 0xD6, 0x03, 0x86, 0xFC, 0xFF, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xBD, 0x03, 0xAD, 0x02, 0xCD, 0x04, 0xDD, 0x05, + 0x1C, 0x8E, 0x25, 0x71, 0x22, 0xBC, 0x16, 0x82, + 0x12, 0x1A, 0x5A, 0xA4, 0xEC, 0xA8, 0x1C, 0x79, + 0xA7, 0x39, 0x28, 0x92, 0xA4, 0x21, 0x92, 0x52, + 0x1A, 0x06, 0x05, 0x00, 0xA1, 0xD2, 0x03, 0x25, + 0x42, 0x2D, 0xA8, 0x82, 0xE5, 0xBF, 0xFF, 0xB1, + 0xD1, 0x03, 0xA8, 0x2B, 0x30, 0xAA, 0x20, 0xA9, + 0x2B, 0xA8, 0x82, 0xA5, 0x05, 0x2D, 0x0C, 0x0B, + 0xB9, 0x82, 0x1D, 0xF0, 0x1C, 0x83, 0xA7, 0xB3, + 0xDA, 0x92, 0xA4, 0x22, 0x86, 0xF3, 0xFF, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x8C, 0x36, 0x0C, 0x03, + 0x32, 0x52, 0x1A, 0x1D, 0xF0, 0x36, 0x41, 0x00, + 0xA5, 0xB9, 0xFF, 0xAD, 0x02, 0x81, 0xD6, 0x03, + 0x89, 0x22, 0xE5, 0x8C, 0x29, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xD7, 0x03, 0x21, + 0xD8, 0x03, 0x29, 0x13, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x81, 0xD9, 0x03, 0x30, + 0x61, 0x00, 0x88, 0x08, 0x82, 0x08, 0x10, 0x26, + 0x48, 0x07, 0xAD, 0x02, 0xA5, 0x54, 0x28, 0x06, + 0x01, 0x00, 0x0C, 0x0A, 0xE5, 0xED, 0x20, 0x30, + 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x21, 0xDA, 0x03, 0x88, + 0x02, 0x27, 0x18, 0x09, 0xAD, 0x02, 0xE5, 0x07, + 0x00, 0xAD, 0x02, 0xE5, 0xE2, 0x20, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x20, 0x61, 0x00, 0xA1, + 0xDA, 0x03, 0xE5, 0xE1, 0x20, 0xA5, 0x28, 0x24, + 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x41, 0xDB, 0x03, 0x21, + 0xDC, 0x03, 0xC0, 0x20, 0x00, 0x32, 0x22, 0x81, + 0x98, 0x54, 0x88, 0x34, 0x30, 0x99, 0x20, 0x99, + 0x54, 0x87, 0x03, 0x06, 0x0C, 0x0A, 0xA9, 0x34, + 0xA5, 0xE5, 0x21, 0x0C, 0x1D, 0x3C, 0x8C, 0xB8, + 0x44, 0xC0, 0x20, 0x00, 0xC0, 0xBB, 0x10, 0xB2, + 0x62, 0x80, 0xC0, 0x20, 0x00, 0xE2, 0x22, 0x81, + 0xE0, 0xF0, 0x04, 0x07, 0xEE, 0xF3, 0xC0, 0x20, + 0x00, 0xB1, 0xDD, 0x03, 0x32, 0x62, 0x81, 0xC0, + 0x20, 0x00, 0xB8, 0x0B, 0xA1, 0xDE, 0x03, 0x1B, + 0xBB, 0xB9, 0x4A, 0x4B, 0xAA, 0x25, 0xDA, 0x20, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x20, 0x61, 0x00, 0x3C, 0x8A, 0x0C, 0x0B, 0xA5, + 0x25, 0x24, 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0xB8, 0x0F, 0x02, + 0x60, 0xC0, 0x0F, 0x02, 0x60, 0x04, 0x14, 0x02, + 0x60, 0xDC, 0x14, 0x02, 0x60, 0x04, 0x15, 0x00, + 0x60, 0x04, 0x15, 0x00, 0x60, 0x00, 0x15, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF4, 0x14, 0x00, 0x60, 0xF8, 0x14, 0x00, + 0x60, 0x50, 0x15, 0x00, 0x60, 0x94, 0x02, 0x00, + 0x00, 0x78, 0x10, 0x02, 0x60, 0x53, 0x10, 0x02, + 0x60, 0x78, 0x10, 0x02, 0x60, 0x02, 0x11, 0x02, + 0x60, 0xDD, 0x10, 0x02, 0x60, 0xC2, 0x10, 0x02, + 0x60, 0x85, 0x10, 0x02, 0x60, 0x7E, 0x10, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x0C, 0x00, + 0x60, 0xD4, 0x0C, 0x00, 0x60, 0x10, 0x30, 0x02, + 0x00, 0x60, 0x15, 0x00, 0x60, 0x00, 0x01, 0x00, + 0x00, 0xB0, 0x0A, 0x00, 0x60, 0x04, 0x13, 0x02, + 0x60, 0xA0, 0x0A, 0x00, 0x60, 0xA4, 0x13, 0x02, + 0x60, 0xF8, 0x13, 0x02, 0x60, 0x6C, 0x13, 0x02, + 0x60, 0x6C, 0x06, 0x00, 0x60, 0x14, 0x10, 0x02, + 0x60, 0xF4, 0x05, 0x00, 0x60, 0x4C, 0x13, 0x02, + 0x60, 0x68, 0x0A, 0x00, 0x60, 0x28, 0x8F, 0x04, + 0x60, 0x48, 0x08, 0x00, 0x60, 0x28, 0x14, 0x02, + 0x60, 0xAC, 0x06, 0x00, 0x60, 0x68, 0x14, 0x02, + 0x60, 0x80, 0x14, 0x02, 0x60, 0xD8, 0x56, 0x04, + 0x60, 0x36, 0x41, 0x00, 0x81, 0x57, 0x05, 0xB1, + 0x55, 0x05, 0x0C, 0x3A, 0x91, 0x56, 0x05, 0xA2, + 0x4B, 0x00, 0x89, 0x09, 0xE5, 0x01, 0x00, 0xE5, + 0x05, 0x00, 0xA5, 0x06, 0x00, 0x65, 0x07, 0x00, + 0x25, 0x02, 0x00, 0xA1, 0x58, 0x05, 0xB1, 0x59, + 0x05, 0x25, 0xFA, 0x2C, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0x5A, 0x05, 0x21, + 0x5B, 0x05, 0x22, 0x63, 0x75, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x0C, 0x8F, 0xB1, 0x5A, + 0x05, 0xA1, 0x5F, 0x05, 0x91, 0x60, 0x05, 0x81, + 0x61, 0x05, 0x31, 0x62, 0x05, 0x21, 0x63, 0x05, + 0xC1, 0x5E, 0x05, 0xD1, 0x5C, 0x05, 0xE1, 0x5D, + 0x05, 0xE9, 0xFD, 0xC2, 0x6D, 0x19, 0x29, 0x83, + 0x89, 0x39, 0xA2, 0x6B, 0x6B, 0xF2, 0x5D, 0x1C, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0x64, 0x05, 0x21, 0x65, 0x05, 0x29, 0x13, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0x66, 0x05, 0x21, 0x67, 0x05, 0x22, 0x63, + 0x19, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x91, 0x69, 0x05, 0x21, 0x6B, 0x05, 0x31, 0x68, + 0x05, 0x81, 0x6A, 0x05, 0x89, 0xC3, 0x29, 0xA3, + 0x99, 0xB3, 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x04, 0x00, 0xB0, 0x15, 0x02, + 0x60, +}; + +static const unsigned char vfs301_06_3[] = { /* 785 B */ + 0x06, 0x00, 0x00, 0x04, 0x03, 0x00, 0x0F, 0x00, + 0x60, 0xD8, 0x0C, 0x00, 0x60, 0xD4, 0x0C, 0x00, + 0x60, 0xB0, 0x0A, 0x00, 0x60, 0x58, 0xB3, 0x04, + 0x60, 0x84, 0x05, 0x00, 0x60, 0xA4, 0xED, 0x04, + 0x60, 0x8C, 0x04, 0x00, 0x00, 0xBC, 0x08, 0x00, + 0x60, 0x00, 0x0F, 0x00, 0x60, 0x50, 0x02, 0x00, + 0x00, 0xFC, 0x07, 0x00, 0x60, 0xF4, 0x8B, 0x04, + 0x60, 0xBC, 0x0D, 0x00, 0x60, 0xDC, 0x0C, 0x00, + 0x60, 0xC0, 0x0D, 0x00, 0x60, 0x40, 0x11, 0x00, + 0x60, 0x18, 0x0D, 0x00, 0x60, 0x00, 0x9E, 0x00, + 0x38, 0x3C, 0x11, 0x00, 0x60, 0x36, 0x41, 0x00, + 0xE5, 0x02, 0x00, 0x65, 0x14, 0x00, 0x25, 0x06, + 0x00, 0x25, 0x01, 0x00, 0x91, 0xC0, 0x03, 0xA1, + 0xC1, 0x03, 0x0C, 0x08, 0x89, 0x0A, 0x82, 0x49, + 0x00, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xC2, 0x03, 0x21, 0xC3, 0x03, 0x22, 0x63, + 0x75, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xA1, 0xC4, 0x03, 0xB1, 0xC5, 0x03, 0xC1, 0xC6, + 0x03, 0xE5, 0x94, 0x2D, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x9C, 0xD5, 0x20, 0x61, + 0x00, 0x25, 0xFB, 0xFF, 0x81, 0xC7, 0x03, 0x20, + 0xE6, 0x13, 0x10, 0x20, 0x00, 0x88, 0x28, 0x0C, + 0x0A, 0xE0, 0x08, 0x00, 0xA1, 0xC8, 0x03, 0xB1, + 0xC9, 0x03, 0xA5, 0x5C, 0x2D, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xCA, 0x03, 0x21, + 0xCB, 0x03, 0x29, 0xD3, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x41, 0xCC, 0x03, 0x88, + 0x04, 0x22, 0x08, 0xD2, 0x80, 0x22, 0xA0, 0x28, + 0x92, 0xAD, 0x02, 0xE5, 0x73, 0x2D, 0xC0, 0x20, + 0x00, 0x5D, 0x0A, 0x38, 0x0A, 0xA2, 0xC2, 0x10, + 0x25, 0x73, 0x2D, 0x88, 0x04, 0x30, 0x9A, 0x10, + 0x82, 0x28, 0x1D, 0xC0, 0x20, 0x00, 0x90, 0x88, + 0x20, 0x89, 0x05, 0xC0, 0x20, 0x00, 0x38, 0x05, + 0x7C, 0xF5, 0x50, 0x5A, 0x30, 0x30, 0x35, 0x10, + 0xCB, 0xA2, 0xE5, 0x70, 0x2D, 0x37, 0x9A, 0x29, + 0x4B, 0xA2, 0x65, 0x70, 0x2D, 0xB8, 0x04, 0xCD, + 0x0A, 0xA2, 0xC2, 0x14, 0x92, 0x2B, 0x1E, 0xC2, + 0x6B, 0x1D, 0x1B, 0x99, 0x92, 0x6B, 0x1E, 0x25, + 0x6F, 0x2D, 0xB8, 0x04, 0xD2, 0x2B, 0x1E, 0xD7, + 0xBA, 0x16, 0xA2, 0xCB, 0x64, 0x25, 0x2E, 0x2D, + 0x1D, 0xF0, 0x8B, 0xA2, 0xE5, 0x6D, 0x2D, 0xF8, + 0x04, 0x3A, 0xEA, 0xE0, 0xE5, 0x10, 0xE2, 0x6F, + 0x1D, 0x81, 0xCA, 0x03, 0x82, 0x28, 0x12, 0xE0, + 0x08, 0x00, 0xA2, 0xA0, 0x94, 0xC1, 0xCD, 0x03, + 0xB8, 0x04, 0xC0, 0x20, 0x00, 0xC8, 0x0C, 0x92, + 0x1B, 0x5D, 0xAA, 0xAB, 0xCA, 0x99, 0x92, 0x6B, + 0x28, 0xE5, 0x20, 0x21, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x81, 0xCE, 0x03, 0x30, + 0x61, 0x00, 0x88, 0x08, 0x82, 0x08, 0x10, 0x26, + 0x48, 0x07, 0xAD, 0x02, 0x25, 0x90, 0x28, 0x06, + 0x01, 0x00, 0x0C, 0x0A, 0x65, 0x29, 0x21, 0x30, + 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x21, 0xCF, 0x03, 0x88, + 0x02, 0x27, 0x18, 0x09, 0xAD, 0x02, 0xE5, 0x07, + 0x00, 0xAD, 0x02, 0x65, 0x1E, 0x21, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x20, 0x61, 0x00, 0xA1, + 0xCF, 0x03, 0x65, 0x1D, 0x21, 0x25, 0x64, 0x24, + 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x41, 0xD0, 0x03, 0x21, + 0xD1, 0x03, 0xC0, 0x20, 0x00, 0x32, 0x22, 0x81, + 0x98, 0x54, 0x88, 0x34, 0x30, 0x99, 0x20, 0x99, + 0x54, 0x87, 0x03, 0x06, 0x0C, 0x0A, 0xA9, 0x34, + 0x25, 0x21, 0x22, 0x0C, 0x1D, 0x3C, 0x8C, 0xB8, + 0x44, 0xC0, 0x20, 0x00, 0xC0, 0xBB, 0x10, 0xB2, + 0x62, 0x80, 0xC0, 0x20, 0x00, 0xE2, 0x22, 0x81, + 0xE0, 0xF0, 0x04, 0x07, 0xEE, 0xF3, 0xC0, 0x20, + 0x00, 0xB1, 0xCD, 0x03, 0x32, 0x62, 0x81, 0xC0, + 0x20, 0x00, 0xB8, 0x0B, 0xA1, 0xD2, 0x03, 0x1B, + 0xBB, 0xB9, 0x4A, 0x4B, 0xAA, 0xA5, 0x15, 0x21, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x20, 0x61, 0x00, 0x3C, 0x8A, 0x0C, 0x0B, 0x25, + 0x61, 0x24, 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x24, 0x11, 0x02, + 0x60, 0x40, 0x11, 0x00, 0x60, 0x40, 0x11, 0x00, + 0x60, 0x3C, 0x11, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0xD8, 0x0C, 0x00, 0x60, 0xD4, 0x0C, 0x00, + 0x60, 0x12, 0x30, 0x00, 0x00, 0x50, 0x11, 0x00, + 0x60, 0xB0, 0x00, 0x00, 0x00, 0xB0, 0x0A, 0x00, + 0x60, 0x90, 0x0F, 0x02, 0x60, 0xFC, 0x07, 0x00, + 0x60, 0xC8, 0x0F, 0x02, 0x60, 0x48, 0x08, 0x00, + 0x60, 0x70, 0x10, 0x02, 0x60, 0xAC, 0x06, 0x00, + 0x60, 0xB0, 0x10, 0x02, 0x60, 0xC8, 0x10, 0x02, + 0x60, 0xD8, 0x56, 0x04, 0x60, 0x36, 0x41, 0x00, + 0x81, 0x56, 0x04, 0xB1, 0x54, 0x04, 0x0C, 0x1A, + 0x91, 0x55, 0x04, 0xA2, 0x4B, 0x00, 0x89, 0x09, + 0xA5, 0x01, 0x00, 0x65, 0x02, 0x00, 0x25, 0x03, + 0x00, 0xE5, 0x03, 0x00, 0xA1, 0x57, 0x04, 0xB1, + 0x58, 0x04, 0xA5, 0x3C, 0x2D, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0x59, 0x04, 0x21, + 0x5A, 0x04, 0x22, 0x63, 0x75, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0x5B, 0x04, 0x21, + 0x5C, 0x04, 0x29, 0xD3, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0x5D, 0x04, 0x21, + 0x5E, 0x04, 0x22, 0x63, 0x19, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x91, 0x60, 0x04, 0x21, + 0x62, 0x04, 0x31, 0x5F, 0x04, 0x81, 0x61, 0x04, + 0x89, 0xC3, 0x29, 0xA3, 0x99, 0xB3, 0x1D, 0xF0, + 0x00, 0x01, 0x00, 0x04, 0x00, 0x8C, 0x11, 0x02, + 0x60, +}; + +static const unsigned char vfs301_06_4[] = { /* 3057 B */ + 0x06, 0x00, 0x00, 0xE4, 0x0B, 0x00, 0x0F, 0x00, + 0x60, 0xD8, 0x0C, 0x00, 0x60, 0xD4, 0x0C, 0x00, + 0x60, 0xB0, 0x0A, 0x00, 0x60, 0x58, 0xB3, 0x04, + 0x60, 0x84, 0x05, 0x00, 0x60, 0xA4, 0xED, 0x04, + 0x60, 0x8C, 0x04, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x60, 0xC0, 0x0A, 0x00, 0x00, 0xA0, 0x0A, 0x00, + 0x60, 0xD0, 0x38, 0x04, 0x60, 0xB4, 0x39, 0x04, + 0x60, 0x58, 0xB4, 0x04, 0x60, 0xFC, 0x0C, 0x00, + 0x60, 0x80, 0x19, 0x00, 0x60, 0xC8, 0x0D, 0x00, + 0x60, 0x9C, 0x0B, 0x00, 0x60, 0xF4, 0x18, 0x00, + 0x60, 0xCC, 0x08, 0x00, 0x60, 0xF8, 0x18, 0x00, + 0x60, 0xA8, 0x0B, 0x00, 0x60, 0xE4, 0x06, 0x00, + 0x60, 0x54, 0x11, 0x02, 0x60, 0xAC, 0x06, 0x00, + 0x60, 0x48, 0x11, 0x02, 0x60, 0x04, 0x19, 0x00, + 0x60, 0x80, 0x7F, 0x00, 0x38, 0x80, 0x5F, 0x00, + 0x38, 0x80, 0x3F, 0x00, 0x38, 0xDC, 0x0C, 0x00, + 0x60, 0x1C, 0x19, 0x00, 0x60, 0x2C, 0x19, 0x00, + 0x60, 0x48, 0x19, 0x00, 0x60, 0x00, 0x40, 0x00, + 0x38, 0x00, 0xA0, 0x00, 0x38, 0x68, 0x0A, 0x00, + 0x60, 0x4C, 0x3F, 0x04, 0x60, 0xC0, 0x0D, 0x00, + 0x60, 0x5C, 0x19, 0x00, 0x60, 0x18, 0x0D, 0x00, + 0x60, 0x00, 0x9E, 0x00, 0x38, 0x58, 0x19, 0x00, + 0x60, 0xB0, 0x19, 0x00, 0x60, 0x20, 0x0E, 0x00, + 0x60, 0xFC, 0xFF, 0x00, 0x00, 0x90, 0x19, 0x00, + 0x60, 0x36, 0x41, 0x00, 0x65, 0x03, 0x00, 0x25, + 0x18, 0x00, 0x65, 0x15, 0x00, 0x25, 0x06, 0x00, + 0x25, 0x54, 0x00, 0x65, 0x50, 0x00, 0x25, 0x01, + 0x00, 0x91, 0xC0, 0x03, 0xA1, 0xC1, 0x03, 0x0C, + 0x08, 0x89, 0x0A, 0x82, 0x49, 0x00, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x31, 0xC2, 0x03, 0x21, + 0xC3, 0x03, 0x22, 0x63, 0x75, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xA1, 0xC4, 0x03, 0xB1, + 0xC5, 0x03, 0xC1, 0xC6, 0x03, 0xA5, 0x8D, 0x2D, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x9C, 0x85, 0x20, 0x61, 0x00, 0xA5, 0xFA, 0xFF, + 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, 0x0C, 0x0A, + 0x65, 0xC8, 0x29, 0xA1, 0xC7, 0x03, 0xB1, 0xC8, + 0x03, 0xA5, 0x55, 0x2D, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x0C, 0xBB, 0x31, 0xC2, + 0x03, 0x21, 0xCC, 0x03, 0x81, 0xCB, 0x03, 0x91, + 0xC9, 0x03, 0xA1, 0xCA, 0x03, 0xA9, 0xF9, 0x82, + 0x69, 0x19, 0x22, 0x63, 0x6B, 0xB2, 0x59, 0x1C, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x21, 0xCD, 0x03, 0x88, 0x22, 0x37, 0x68, 0x0E, + 0xA1, 0xCE, 0x03, 0xA5, 0x7D, 0x2D, 0x98, 0x22, + 0x6C, 0x7A, 0xA0, 0x99, 0x10, 0x99, 0x22, 0xE5, + 0xA9, 0x22, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0xCD, 0x04, 0xBD, 0x03, 0xAD, 0x02, 0xDD, 0x05, + 0x25, 0x3E, 0x2A, 0xAC, 0x15, 0x81, 0xCF, 0x03, + 0xA1, 0xD0, 0x03, 0x88, 0x08, 0x91, 0xCD, 0x03, + 0x82, 0x08, 0x02, 0x98, 0x29, 0xB6, 0x28, 0x06, + 0x91, 0xD1, 0x03, 0x99, 0x2A, 0x1D, 0xF0, 0x37, + 0x69, 0x05, 0x91, 0xD2, 0x03, 0x86, 0xFC, 0xFF, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xBD, 0x03, 0xAD, 0x02, 0xCD, 0x04, 0xDD, 0x05, + 0x1C, 0x8E, 0x25, 0xA1, 0x22, 0xBC, 0x16, 0x82, + 0x12, 0x1A, 0x5A, 0xA4, 0xEC, 0xA8, 0x1C, 0x79, + 0xA7, 0x39, 0x28, 0x92, 0xA4, 0x21, 0x92, 0x52, + 0x1A, 0x06, 0x05, 0x00, 0xA1, 0xCE, 0x03, 0x25, + 0x72, 0x2D, 0xA8, 0x82, 0xA5, 0x50, 0x00, 0xB1, + 0xCD, 0x03, 0xA8, 0x2B, 0x30, 0xAA, 0x20, 0xA9, + 0x2B, 0xA8, 0x82, 0xA5, 0x35, 0x2D, 0x0C, 0x0B, + 0xB9, 0x82, 0x1D, 0xF0, 0x1C, 0x83, 0xA7, 0xB3, + 0xDA, 0x92, 0xA4, 0x22, 0x86, 0xF3, 0xFF, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x8C, 0x36, 0x0C, 0x03, + 0x32, 0x52, 0x1A, 0x1D, 0xF0, 0x36, 0x41, 0x00, + 0x65, 0x4A, 0x00, 0xAD, 0x02, 0x81, 0xD2, 0x03, + 0x89, 0x22, 0xE5, 0xBC, 0x29, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x21, 0xD3, 0x03, 0x31, + 0xD4, 0x03, 0x28, 0x22, 0x29, 0x03, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x21, 0xD8, 0x03, 0x31, + 0xD7, 0x03, 0x91, 0xD5, 0x03, 0x81, 0xD6, 0x03, + 0x89, 0x49, 0x29, 0x03, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x25, 0x18, 0x00, 0x1D, + 0xF0, 0x36, 0x41, 0x00, 0xA5, 0x17, 0x00, 0x65, + 0x20, 0x24, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0xAD, 0x02, 0x65, 0xBE, 0x24, 0x65, 0x16, 0x00, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x61, 0xD9, 0x03, 0xCC, 0xE4, 0xA2, 0xA0, 0x76, + 0x65, 0x22, 0x2D, 0xA9, 0x36, 0xCC, 0x4A, 0xA2, + 0xA4, 0x31, 0x25, 0xB2, 0x29, 0x72, 0xA0, 0x76, + 0xD8, 0x36, 0xA2, 0xA0, 0x75, 0xAC, 0x2D, 0x4A, + 0xB3, 0xB7, 0x37, 0x0E, 0xDA, 0xA4, 0xBD, 0x02, + 0xCD, 0x03, 0x65, 0x74, 0x2D, 0xA2, 0xA0, 0x75, + 0xC6, 0x03, 0x00, 0x47, 0x3A, 0x0C, 0xDA, 0xA4, + 0xBD, 0x02, 0x40, 0xC7, 0xC0, 0x25, 0x73, 0x2D, + 0xA2, 0xA0, 0x75, 0xBC, 0x75, 0xC8, 0x36, 0x4A, + 0xB3, 0xBC, 0x1C, 0xB7, 0x3A, 0x08, 0xA2, 0xA4, + 0x05, 0x25, 0xAE, 0x29, 0x46, 0x07, 0x00, 0xB7, + 0xB7, 0x25, 0xA2, 0xA4, 0x06, 0x65, 0xAD, 0x29, + 0x46, 0x04, 0x00, 0x0C, 0x0A, 0xE5, 0xAC, 0x29, + 0xA8, 0x46, 0xB8, 0x36, 0xC2, 0xA0, 0x76, 0x25, + 0x70, 0x2D, 0xA5, 0x02, 0x00, 0xA8, 0x36, 0xE5, + 0x25, 0x2D, 0x0C, 0x0D, 0xD9, 0x36, 0x1D, 0xF0, + 0xE8, 0x46, 0x8C, 0x1E, 0xA5, 0x0D, 0x00, 0xA2, + 0xA0, 0x76, 0x25, 0x1A, 0x2D, 0xA9, 0x46, 0x56, + 0x0A, 0xFD, 0xA2, 0xA4, 0x31, 0xE5, 0xA9, 0x29, + 0x46, 0xF6, 0xFF, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x21, 0xD9, 0x03, 0x91, 0xDA, 0x03, 0xB1, 0xDB, + 0x03, 0x81, 0xDC, 0x03, 0xC0, 0x20, 0x00, 0xA2, + 0x08, 0x84, 0xC0, 0x20, 0x00, 0xD2, 0x0B, 0x84, + 0xC0, 0x20, 0x00, 0xC2, 0x09, 0x84, 0x80, 0xDD, + 0x11, 0xD0, 0xAA, 0x20, 0x00, 0xCC, 0x11, 0xC0, + 0xAA, 0x20, 0xA9, 0xE2, 0xC0, 0x20, 0x00, 0x82, + 0x08, 0x81, 0xC0, 0x20, 0x00, 0xB2, 0x0B, 0x81, + 0xC0, 0x20, 0x00, 0xA8, 0x42, 0x80, 0xBB, 0x11, + 0x92, 0x09, 0x81, 0xB0, 0x88, 0x20, 0x00, 0x99, + 0x11, 0x90, 0x88, 0x20, 0x89, 0xF2, 0xE5, 0x73, + 0x24, 0x31, 0xDD, 0x03, 0x98, 0x42, 0x0C, 0x0B, + 0xA2, 0x09, 0x70, 0x92, 0x09, 0x71, 0xB2, 0x42, + 0x14, 0x80, 0x99, 0x11, 0xA0, 0x99, 0x20, 0x16, + 0x79, 0x04, 0xC0, 0x20, 0x00, 0xB8, 0x03, 0x9A, + 0xBB, 0x0B, 0xBB, 0xB9, 0x92, 0xA1, 0xDE, 0x03, + 0xA5, 0xFF, 0x20, 0xB8, 0x42, 0xB2, 0x0B, 0x75, + 0x9C, 0x9B, 0xC0, 0x20, 0x00, 0xA1, 0xDF, 0x03, + 0xD8, 0x03, 0xB0, 0xCB, 0x11, 0xB0, 0xCC, 0xC0, + 0xB0, 0xCC, 0xA0, 0xD0, 0xCC, 0xB0, 0x0B, 0xCC, + 0xC9, 0xD2, 0x65, 0xFD, 0x20, 0xA1, 0xE0, 0x03, + 0x0C, 0x1E, 0xE2, 0x62, 0x10, 0xC0, 0x20, 0x00, + 0xD8, 0x03, 0xD2, 0x62, 0x14, 0x25, 0xFC, 0x20, + 0x1D, 0xF0, 0xC0, 0x20, 0x00, 0xB8, 0x03, 0x06, + 0xEE, 0xFF, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x21, 0xD9, 0x03, 0x88, 0x42, 0x16, 0x28, 0x08, + 0xA2, 0xC2, 0x44, 0xE5, 0xFB, 0x20, 0xB8, 0x42, + 0x92, 0x0B, 0x74, 0x26, 0x19, 0x14, 0xA2, 0xC9, + 0xFE, 0x16, 0x9A, 0x07, 0xC2, 0xC9, 0xFD, 0x16, + 0xAC, 0x06, 0xA2, 0xCB, 0x48, 0x25, 0x1A, 0x00, + 0x46, 0x01, 0x00, 0xA2, 0xCB, 0x50, 0xA5, 0x19, + 0x00, 0xA1, 0xDE, 0x03, 0x65, 0xF9, 0x20, 0xA1, + 0xDF, 0x03, 0xE5, 0xF8, 0x20, 0xE1, 0xDA, 0x03, + 0x81, 0xDB, 0x03, 0xA1, 0xDC, 0x03, 0xD8, 0xE2, + 0xC0, 0x20, 0x00, 0xD2, 0x4A, 0x84, 0xC8, 0xE2, + 0xC0, 0x20, 0x00, 0xC0, 0xC8, 0x41, 0xC2, 0x48, + 0x84, 0xB8, 0xE2, 0xC0, 0x20, 0x00, 0xB0, 0xB0, + 0xF5, 0xB2, 0x4E, 0x84, 0x98, 0xF2, 0xC0, 0x20, + 0x00, 0x92, 0x4A, 0x81, 0xF8, 0xF2, 0xC0, 0x20, + 0x00, 0xF0, 0xF8, 0x41, 0xF2, 0x48, 0x81, 0xD8, + 0xF2, 0xC0, 0x20, 0x00, 0xD0, 0xD0, 0xF5, 0xD2, + 0x4E, 0x81, 0xA8, 0x42, 0x25, 0x0F, 0x2D, 0x0C, + 0x0E, 0xE9, 0x42, 0x1D, 0xF0, 0xA2, 0xCB, 0x60, + 0xA5, 0x13, 0x00, 0x86, 0xE6, 0xFF, 0xA2, 0xCB, + 0x58, 0xE5, 0x12, 0x00, 0x46, 0xE4, 0xFF, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xB1, 0xD9, 0x03, 0x0C, + 0x1D, 0x98, 0x4B, 0xA2, 0x0B, 0x14, 0xAC, 0x79, + 0xC1, 0xDD, 0x03, 0xEC, 0x4A, 0xA2, 0x09, 0x72, + 0xE2, 0x09, 0x73, 0xD2, 0x4B, 0x14, 0x80, 0x9E, + 0x11, 0xA0, 0x99, 0x20, 0xBC, 0xD9, 0xC0, 0x20, + 0x00, 0xA8, 0x0C, 0x9A, 0x9A, 0x0B, 0x99, 0x99, + 0x32, 0xD2, 0x6B, 0x10, 0xAD, 0x02, 0xA5, 0xED, + 0x20, 0x1D, 0xF0, 0x66, 0x1A, 0xF2, 0xE2, 0x09, + 0x71, 0xA2, 0x09, 0x70, 0x80, 0x9E, 0x11, 0xA0, + 0x99, 0x20, 0x0C, 0x0E, 0xE2, 0x4B, 0x14, 0x8C, + 0xA9, 0xC0, 0x20, 0x00, 0xA8, 0x0C, 0x9A, 0x9A, + 0x0B, 0x99, 0x46, 0xF4, 0xFF, 0xC0, 0x20, 0x00, + 0x98, 0x0C, 0x46, 0xF2, 0xFF, 0xC0, 0x20, 0x00, + 0x98, 0x0C, 0x46, 0xF0, 0xFF, 0x36, 0x41, 0x00, + 0x31, 0xD9, 0x03, 0xB8, 0x43, 0x92, 0x03, 0x14, + 0x16, 0xFB, 0x09, 0xFC, 0x99, 0x82, 0x0B, 0x71, + 0xA2, 0x0B, 0x70, 0x80, 0x88, 0x11, 0xA0, 0x88, + 0x20, 0xAC, 0xB8, 0xC2, 0x0B, 0x68, 0x92, 0x0B, + 0x6B, 0xA2, 0x0B, 0x6A, 0x80, 0x99, 0x11, 0xA0, + 0x99, 0x20, 0xA2, 0x0B, 0x69, 0x80, 0x99, 0x11, + 0xA0, 0x99, 0x20, 0xA2, 0x23, 0x10, 0x80, 0x99, + 0x11, 0xC0, 0x99, 0x20, 0xA7, 0x09, 0x6D, 0xA2, + 0xCB, 0x50, 0x65, 0x07, 0x00, 0xC6, 0x10, 0x00, + 0x66, 0x19, 0x40, 0xA2, 0x0B, 0x73, 0xC2, 0x0B, + 0x72, 0x80, 0xAA, 0x11, 0xC0, 0xAA, 0x20, 0xBC, + 0x1A, 0xE2, 0x0B, 0x6C, 0xC2, 0x0B, 0x6F, 0xD2, + 0x0B, 0x6E, 0x80, 0xCC, 0x11, 0xD0, 0xCC, 0x20, + 0xD2, 0x0B, 0x6D, 0x80, 0xCC, 0x11, 0xD0, 0xCC, + 0x20, 0xD2, 0x23, 0x10, 0x80, 0xCC, 0x11, 0xE0, + 0xCC, 0x20, 0xD7, 0x0C, 0x08, 0xA2, 0xCB, 0x60, + 0xA5, 0x03, 0x00, 0x46, 0x01, 0x00, 0xA2, 0xCB, + 0x58, 0xE5, 0x02, 0x00, 0xAD, 0x02, 0xD1, 0xDD, + 0x03, 0x82, 0x23, 0x10, 0x0C, 0x1F, 0xF0, 0x88, + 0x11, 0xED, 0x08, 0x80, 0xEF, 0x83, 0xE2, 0x63, + 0x10, 0xC0, 0x20, 0x00, 0xD8, 0x0D, 0xD9, 0x32, + 0xA5, 0xDF, 0x20, 0x1D, 0xF0, 0xA2, 0xCB, 0x48, + 0xA5, 0x00, 0x00, 0x46, 0xF5, 0xFF, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x4B, 0xA2, 0x25, 0x28, + 0x2D, 0x3D, 0x0A, 0xAD, 0x02, 0xA5, 0x27, 0x2D, + 0xB1, 0xE1, 0x03, 0xC1, 0xE2, 0x03, 0xC0, 0x20, + 0x00, 0x82, 0x0B, 0x03, 0xC0, 0x20, 0x00, 0x30, + 0x88, 0x10, 0x30, 0x38, 0x41, 0x80, 0x8A, 0x20, + 0xA0, 0xA8, 0x41, 0x82, 0x4B, 0x03, 0xB2, 0xDB, + 0x20, 0xC7, 0x9B, 0xE1, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0xA5, 0xDF, 0xFF, 0x1D, + 0xF0, 0x36, 0x41, 0x00, 0x31, 0xE3, 0x03, 0x21, + 0xE4, 0x03, 0x29, 0x13, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x81, 0xE5, 0x03, 0x30, + 0x61, 0x00, 0x88, 0x08, 0x82, 0x08, 0x10, 0x26, + 0x48, 0x07, 0xAD, 0x02, 0x25, 0x49, 0x28, 0x06, + 0x01, 0x00, 0x0C, 0x0A, 0x65, 0xE2, 0x20, 0x30, + 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x21, 0xE6, 0x03, 0x88, + 0x02, 0x27, 0x18, 0x09, 0xAD, 0x02, 0xE5, 0x07, + 0x00, 0xAD, 0x02, 0x65, 0xD7, 0x20, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x20, 0x61, 0x00, 0xA1, + 0xE6, 0x03, 0x65, 0xD6, 0x20, 0x25, 0x1D, 0x24, + 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0x41, 0xE7, 0x03, 0x21, + 0xE8, 0x03, 0xC0, 0x20, 0x00, 0x32, 0x22, 0x81, + 0x98, 0x54, 0x88, 0x34, 0x30, 0x99, 0x20, 0x99, + 0x54, 0x87, 0x03, 0x06, 0x0C, 0x0A, 0xA9, 0x34, + 0x25, 0xDA, 0x21, 0x0C, 0x1D, 0x3C, 0x8C, 0xB8, + 0x44, 0xC0, 0x20, 0x00, 0xC0, 0xBB, 0x10, 0xB2, + 0x62, 0x80, 0xC0, 0x20, 0x00, 0xE2, 0x22, 0x81, + 0xE0, 0xF0, 0x04, 0x07, 0xEE, 0xF3, 0xC0, 0x20, + 0x00, 0xB1, 0xDD, 0x03, 0x32, 0x62, 0x81, 0xC0, + 0x20, 0x00, 0xB8, 0x0B, 0xA1, 0xE9, 0x03, 0x1B, + 0xBB, 0xB9, 0x4A, 0x4B, 0xAA, 0xA5, 0xCE, 0x20, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x20, 0x61, 0x00, 0x3C, 0x8A, 0x0C, 0x0B, 0x25, + 0x1A, 0x24, 0x20, 0xE6, 0x13, 0x10, 0x20, 0x00, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xEA, 0x03, 0x38, 0x03, 0x8C, 0x73, 0x88, + 0x23, 0x66, 0x28, 0x03, 0x0C, 0x39, 0x99, 0x23, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0xEB, 0x03, 0x0C, 0x02, 0x22, 0x43, 0x00, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0xBD, 0x02, 0x21, 0xEA, 0x03, 0x28, 0x02, 0x1C, + 0x8C, 0xCB, 0xA2, 0xE5, 0x2E, 0x2D, 0xD1, 0xEC, + 0x03, 0x2C, 0x0B, 0x92, 0x12, 0x11, 0x0C, 0x1C, + 0xDC, 0x79, 0xA2, 0x12, 0x0F, 0x92, 0x12, 0x0E, + 0xA0, 0xA0, 0xE4, 0x90, 0xAA, 0xC0, 0xA2, 0xCA, + 0xC2, 0xA0, 0xA1, 0x21, 0xAA, 0x99, 0x8B, 0x99, + 0x92, 0x52, 0x11, 0xB2, 0x52, 0x13, 0xC9, 0x22, + 0xD0, 0xD9, 0x10, 0xD2, 0x52, 0x11, 0x1D, 0xF0, + 0x00, 0x36, 0x41, 0x00, 0xD8, 0x22, 0x31, 0xEA, + 0x03, 0x0C, 0x1E, 0x38, 0x03, 0x0C, 0x0C, 0xAD, + 0x03, 0xF2, 0x13, 0x13, 0xB2, 0x13, 0x10, 0xF0, + 0xCE, 0x83, 0xDA, 0xBB, 0x25, 0x17, 0x00, 0x0C, + 0x45, 0xA8, 0x23, 0x92, 0x13, 0x13, 0x0C, 0x04, + 0x8C, 0x69, 0x0B, 0x99, 0x90, 0x90, 0xF4, 0x92, + 0x53, 0x13, 0xF6, 0x8A, 0x2F, 0xB1, 0xED, 0x03, + 0xB0, 0xBA, 0xA0, 0xB8, 0x0B, 0xA0, 0x0B, 0x00, + 0xC8, 0x22, 0xB2, 0x13, 0x11, 0xAD, 0x03, 0xCA, + 0xBB, 0x65, 0x21, 0x00, 0xD2, 0x13, 0x06, 0xF1, + 0xEB, 0x03, 0xD7, 0x3A, 0x0F, 0x0C, 0x29, 0x92, + 0x4F, 0x00, 0xE2, 0x13, 0x0F, 0xE0, 0xEF, 0x04, + 0x16, 0xBE, 0x10, 0x99, 0x23, 0x0C, 0x14, 0x2D, + 0x04, 0x1D, 0xF0, 0x49, 0x23, 0x0C, 0x24, 0x06, + 0xFD, 0xFF, 0xAD, 0x03, 0xE5, 0x1B, 0x00, 0x82, + 0x13, 0x09, 0xB2, 0x13, 0x08, 0x87, 0x3A, 0x02, + 0x06, 0x24, 0x00, 0xC8, 0x22, 0xB2, 0x13, 0x11, + 0xAD, 0x03, 0xCA, 0xBB, 0x65, 0x1D, 0x00, 0xD2, + 0x13, 0x07, 0xD7, 0x3A, 0x02, 0xC6, 0x36, 0x00, + 0xE2, 0x13, 0x14, 0x0B, 0xEE, 0xE0, 0xE0, 0xF4, + 0xE2, 0x53, 0x14, 0x56, 0xEE, 0x0D, 0x0C, 0x24, + 0x0C, 0x7F, 0xF9, 0x23, 0xC6, 0xED, 0xFF, 0xAD, + 0x03, 0xE5, 0x17, 0x00, 0x82, 0x13, 0x08, 0x87, + 0x3A, 0x6A, 0x59, 0x23, 0x42, 0x53, 0x16, 0x92, + 0x13, 0x0A, 0x92, 0x53, 0x14, 0x0C, 0x04, 0x06, + 0xE7, 0xFF, 0xAD, 0x03, 0x65, 0x16, 0x00, 0xB2, + 0x13, 0x08, 0xB7, 0x3A, 0x29, 0xC2, 0x13, 0x14, + 0x0B, 0xCC, 0xC0, 0xC0, 0xF4, 0xC2, 0x53, 0x14, + 0xEC, 0xBC, 0x0C, 0x6D, 0xE2, 0x13, 0x0B, 0xE2, + 0x53, 0x14, 0xD9, 0x23, 0xC6, 0x07, 0x00, 0xDC, + 0xC9, 0x59, 0x23, 0x42, 0x53, 0x16, 0xF2, 0x13, + 0x0A, 0xF2, 0x53, 0x14, 0xC6, 0x03, 0x00, 0x0C, + 0x58, 0x92, 0x13, 0x0D, 0xA2, 0x13, 0x0C, 0xA2, + 0x53, 0x14, 0x92, 0x53, 0x15, 0x89, 0x23, 0x0C, + 0x04, 0x86, 0xD4, 0xFF, 0xB7, 0x3A, 0x05, 0xC2, + 0x13, 0x0B, 0xC2, 0x53, 0x14, 0x42, 0x53, 0x16, + 0x0C, 0x04, 0x46, 0xD0, 0xFF, 0x92, 0x13, 0x15, + 0x66, 0x19, 0x09, 0x0C, 0x34, 0x0B, 0xD9, 0xD2, + 0x53, 0x15, 0x46, 0xCC, 0xFF, 0xCC, 0x39, 0x0C, + 0x14, 0x86, 0x01, 0x00, 0x0C, 0x04, 0x0B, 0xE9, + 0xE2, 0x53, 0x15, 0xC8, 0x22, 0xB2, 0x13, 0x11, + 0xAD, 0x03, 0xCA, 0xBB, 0x65, 0x11, 0x00, 0xD2, + 0x13, 0x07, 0xD7, 0xBA, 0x10, 0xE2, 0x13, 0x14, + 0x0B, 0xEE, 0xE0, 0xE0, 0xF4, 0xE2, 0x53, 0x14, + 0xE0, 0x45, 0x83, 0x06, 0xC0, 0xFF, 0xF2, 0x13, + 0x0D, 0xF2, 0x53, 0x14, 0xC6, 0xBD, 0xFF, 0x0C, + 0x39, 0x86, 0xBB, 0xFF, 0x82, 0x13, 0x06, 0x87, + 0x3A, 0x05, 0x92, 0x13, 0x0B, 0x92, 0x53, 0x14, + 0x0C, 0x04, 0x46, 0xB8, 0xFF, 0x0C, 0x04, 0x06, + 0xB7, 0xFF, 0x00, 0x00, 0x00, 0x36, 0x61, 0x00, + 0xB2, 0xA0, 0x94, 0xA2, 0xC2, 0x34, 0x92, 0xC2, + 0x54, 0x99, 0x01, 0xA9, 0x11, 0xBC, 0xB4, 0x68, + 0x11, 0x5D, 0x09, 0x1C, 0x04, 0x72, 0x12, 0x12, + 0x82, 0xA0, 0x94, 0xC0, 0x77, 0x11, 0x7A, 0x72, + 0x8A, 0x77, 0x82, 0x16, 0x00, 0xB2, 0x07, 0x00, + 0x1B, 0x77, 0xAD, 0x0B, 0xB0, 0x88, 0xC0, 0x82, + 0x56, 0x00, 0x2B, 0x66, 0xA5, 0x35, 0x2D, 0x98, + 0x05, 0x0B, 0x44, 0xA0, 0x99, 0xC0, 0x99, 0x05, + 0x4B, 0x55, 0x56, 0xC4, 0xFD, 0x98, 0x01, 0xA8, + 0x11, 0xB2, 0xA0, 0x94, 0x5D, 0x09, 0x6D, 0x0A, + 0x72, 0x12, 0x12, 0x1C, 0x04, 0xC0, 0x77, 0x11, + 0x7A, 0x72, 0xBA, 0x77, 0xD2, 0x03, 0x01, 0xE2, + 0x03, 0x03, 0xC2, 0x03, 0x02, 0xB2, 0x03, 0x00, + 0xEA, 0xCC, 0xDA, 0xBB, 0xCA, 0xBB, 0xB0, 0xB2, + 0x41, 0xAD, 0x0B, 0xB2, 0x47, 0x00, 0x82, 0x16, + 0x00, 0x1B, 0x77, 0xBA, 0x88, 0x82, 0x56, 0x00, + 0x2B, 0x66, 0xA5, 0x30, 0x2D, 0x8B, 0x33, 0xF8, + 0x05, 0x0B, 0x44, 0xAA, 0xFF, 0xF9, 0x05, 0x4B, + 0x55, 0x56, 0x74, 0xFC, 0x82, 0x12, 0x12, 0x1B, + 0x88, 0x80, 0x80, 0x44, 0x82, 0x52, 0x12, 0x1D, + 0xF0, 0x36, 0x41, 0x00, 0x32, 0xC2, 0x34, 0x1C, + 0x05, 0x0C, 0x04, 0xB2, 0x13, 0x00, 0xAD, 0x0B, + 0xE5, 0x2D, 0x2D, 0x2B, 0x33, 0x0B, 0x55, 0xA0, + 0x95, 0x41, 0x82, 0x22, 0x15, 0x4B, 0x22, 0x90, + 0x88, 0xC0, 0x80, 0x85, 0x41, 0x8A, 0x44, 0x56, + 0x05, 0xFE, 0x40, 0x24, 0x41, 0x1D, 0xF0, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x1C, 0x07, 0x0C, 0x06, + 0x0C, 0x05, 0xB2, 0xC3, 0x81, 0x42, 0x03, 0x00, + 0xB2, 0x0B, 0x7E, 0xC2, 0x03, 0x01, 0x47, 0xBB, + 0x0C, 0x47, 0xBC, 0x11, 0x4D, 0x0B, 0xC7, 0xBB, + 0x0C, 0x4D, 0x0C, 0xC6, 0x01, 0x00, 0x47, 0x3C, + 0x04, 0xC7, 0xBB, 0x01, 0x4D, 0x0B, 0xAD, 0x04, + 0xBD, 0x04, 0xA5, 0x28, 0x2D, 0xAA, 0x66, 0x5A, + 0x54, 0x0B, 0x77, 0x4B, 0x33, 0xB2, 0xC3, 0x81, + 0x56, 0x97, 0xFC, 0xAD, 0x05, 0xBD, 0x05, 0x65, + 0x27, 0x2D, 0xD2, 0x12, 0x16, 0xA0, 0x94, 0x41, + 0x90, 0x96, 0xC0, 0xD0, 0xCD, 0xF0, 0x90, 0x94, + 0x41, 0x90, 0xE3, 0x41, 0xC0, 0xC3, 0x21, 0xEA, + 0xCC, 0xD0, 0x9C, 0x93, 0x92, 0x52, 0x16, 0x2D, + 0x09, 0x1D, 0xF0, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x64, 0x11, 0x02, 0x60, 0x04, 0x11, 0x02, + 0x60, 0xEC, 0x18, 0x00, 0x60, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x13, 0x02, + 0x60, 0xC8, 0x14, 0x02, 0x60, 0xD4, 0x13, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x19, 0x00, + 0x60, 0x1C, 0x19, 0x00, 0x60, 0x04, 0x19, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x19, 0x00, + 0x60, 0x2C, 0x19, 0x00, 0x60, 0x08, 0x19, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x19, 0x00, 0x60, 0x48, 0x19, 0x00, + 0x60, 0x0C, 0x19, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x94, 0x15, 0x02, 0x60, 0x5C, 0x19, 0x00, + 0x60, 0x5C, 0x19, 0x00, 0x60, 0x58, 0x19, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x15, 0x02, + 0x60, 0xCC, 0x15, 0x02, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6C, 0x19, 0x00, 0x60, 0x70, 0x19, 0x00, + 0x60, 0xB0, 0x19, 0x00, 0x60, 0x94, 0x02, 0x00, + 0x00, 0x84, 0x16, 0x02, 0x60, 0x5F, 0x16, 0x02, + 0x60, 0x84, 0x16, 0x02, 0x60, 0x0E, 0x17, 0x02, + 0x60, 0xE9, 0x16, 0x02, 0x60, 0xCE, 0x16, 0x02, + 0x60, 0x91, 0x16, 0x02, 0x60, 0x8A, 0x16, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x0C, 0x00, + 0x60, 0xD4, 0x0C, 0x00, 0x60, 0x10, 0xB0, 0x02, + 0x00, 0xC0, 0x19, 0x00, 0x60, 0x20, 0x01, 0x00, + 0x00, 0xB0, 0x0A, 0x00, 0x60, 0x04, 0x10, 0x02, + 0x60, 0xA0, 0x0A, 0x00, 0x60, 0xA4, 0x10, 0x02, + 0x60, 0xF8, 0x10, 0x02, 0x60, 0x6C, 0x10, 0x02, + 0x60, 0x6C, 0x06, 0x00, 0x60, 0x20, 0x16, 0x02, + 0x60, 0xF4, 0x05, 0x00, 0x60, 0x4C, 0x10, 0x02, + 0x60, 0xA8, 0x0B, 0x00, 0x60, 0xF8, 0x18, 0x00, + 0x60, 0x68, 0x0A, 0x00, 0x60, 0x28, 0x8F, 0x04, + 0x60, 0x48, 0x08, 0x00, 0x60, 0xE0, 0x14, 0x02, + 0x60, 0xAC, 0x06, 0x00, 0x60, 0x20, 0x15, 0x02, + 0x60, 0x38, 0x15, 0x02, 0x60, 0xD8, 0x56, 0x04, + 0x60, 0x36, 0x41, 0x00, 0x81, 0x6F, 0x06, 0xB1, + 0x6D, 0x06, 0x0C, 0x6A, 0x91, 0x6E, 0x06, 0xA2, + 0x4B, 0x00, 0x89, 0x09, 0x25, 0x02, 0x00, 0x65, + 0x07, 0x00, 0x25, 0x09, 0x00, 0xE5, 0x07, 0x00, + 0x65, 0x02, 0x00, 0x65, 0x05, 0x00, 0xA5, 0x6E, + 0xFF, 0xA1, 0x70, 0x06, 0xB1, 0x71, 0x06, 0x65, + 0xB3, 0x2C, 0x1D, 0xF0, 0x00, 0x36, 0x41, 0x00, + 0x31, 0x72, 0x06, 0x21, 0x73, 0x06, 0x22, 0x63, + 0x75, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x0C, 0x8F, 0xB1, 0x72, 0x06, 0xA1, 0x77, 0x06, + 0x91, 0x78, 0x06, 0x81, 0x79, 0x06, 0x31, 0x7A, + 0x06, 0x21, 0x7B, 0x06, 0xC1, 0x76, 0x06, 0xD1, + 0x74, 0x06, 0xE1, 0x75, 0x06, 0xE9, 0xFD, 0xC2, + 0x6D, 0x19, 0x29, 0x83, 0x89, 0x39, 0xA2, 0x6B, + 0x6B, 0xF2, 0x5D, 0x1C, 0x1D, 0xF0, 0x00, 0x00, + 0x00, 0x36, 0x41, 0x00, 0x31, 0x7C, 0x06, 0x21, + 0x7D, 0x06, 0x48, 0x03, 0x49, 0x22, 0x29, 0x03, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0x7E, 0x06, 0x21, 0x7F, 0x06, 0x29, 0x13, + 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x31, 0x80, 0x06, 0x21, 0x81, 0x06, 0x22, 0x63, + 0x19, 0x1D, 0xF0, 0x00, 0x00, 0x36, 0x41, 0x00, + 0x91, 0x83, 0x06, 0x21, 0x85, 0x06, 0x31, 0x82, + 0x06, 0x81, 0x84, 0x06, 0x89, 0xC3, 0x29, 0xA3, + 0x99, 0xB3, 0x1D, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x04, 0x00, 0x18, 0x1A, 0x02, + 0x60, +}; + +static const unsigned char vfs301_12[] = { /* 57 B */ + 0x12, 0x90, 0x02, 0x00, 0x00, 0xFE, 0x03, 0x00, + 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, + 0x00, 0xE3, 0x18, 0xD8, 0x01, 0xE3, 0x18, 0xD8, + 0x01, 0xE3, 0x18, 0xD8, 0x01, 0xE3, 0x18, 0xD8, + 0x01, 0xE3, 0x18, 0xD8, 0x01, 0x20, 0xFA, 0x80, + 0x00, 0x3F, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, + 0x00, +}; + +static const unsigned char vfs301_24[] = { /* 119 B */ + 0x24, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x07, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x07, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x07, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, + 0x07, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, + 0x07, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, + 0x07, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* or : + * 0x00, 0xF4, 0x01, 0xF4, 0x01, 0x00, 0xB4, */ +}; + +#define PACKET(cmd, length, payload)\ + cmd length payload + +/* This could be some kind of poke-command. + * a looks like the address; (addr << 2), stored in little endian, + * b looks like some flags, value of a seems to imply value of b + * c looks like the stored value */ +#define S1(a, b, c) \ + PACKET("0300", "0900", a b c "04") + +#define S2(a) \ + PACKET("0500", "0E00", a) + +#define S3(a) \ + PACKET("0A00", "0800", a a) + +#define S4_TAIL \ + "00008000" "6400F401" "00000000" "0000C780" "24004400" +#define S4(a) \ + PACKET("0800", "1800", a a S4_TAIL) + +#define Z8() \ + "00000000" + +#define TERM() \ + PACKET("1500", "0800", "0000000020280000") + +/* NOTE: + * * Reordering the S1() macros in BLOB1 (and similar) doesn't + * seem to make any change. + * * Reordering lines inside the PACKET() does modify the output's columns + * contents. + * + * The contents of PACKET() inside this blob seems to be some kind + * of a micro-program, which specifies which columns contain what. LE seems + * to be used also here. Not neccessarily is 1 output column described + * by 1 operation. For example the vfs301_line_t::sum section seems + * to perform 2 operations for each column - probably some kind of diff between + * input lines? + */ +#define vfs301_0220_BLOB1 \ + S1("0420", "0430", "00000000"),\ + S1("1820", "0430", "00000000"),\ + S1("2020", "0430", "08008000"),\ + S1("2420", "0430", "0000FF01"),\ + S1("2C20", "0430", "01000000"),\ + S1("4020", "0430", "FF030000"),\ + S1("4420", "0430", "E5030000"),\ + S1("4820", "0430", "EA030000"),\ + S1("4C20", "0430", "EA030000"),\ + S1("5020", "0430", "00000400"),\ + S1("5420", "0430", "01980200"),\ + S1("0021", "0430", "00000000"),\ + S1("0421", "0430", "01000000"),\ + S1("0821", "0430", "02000000"),\ + S1("0C21", "0430", "01000000"),\ + S1("1021", "0430", "01000000"),\ + S1("1421", "0430", "01000000"),\ + S1("1821", "0430", "01000000"),\ + S1("1C21", "0430", "1F000000"),\ + S1("2021", "0430", "08000000"),\ + S1("4021", "0430", "00000000"),\ + S1("4421", "0430", "01000000"),\ + S1("4821", "0430", "02000000"),\ + S1("4C21", "0430", "01000000"),\ + S1("5021", "0430", "01000000"),\ + S1("5421", "0430", "01000000"),\ + S1("5821", "0430", "01000000"),\ + S1("5C21", "0430", "1F000000"),\ + S1("6021", "0430", "08000000"),\ + S1("8021", "0430", "30000000"),\ + S1("8421", "0430", "01000000"),\ + S1("8821", "0430", "01000000"),\ + S1("8C21", "0430", "01000000"),\ + S1("9021", "0430", "00000000"),\ + S1("9421", "0430", "01000000"),\ + S1("9821", "0430", "00000000"),\ + S1("9C21", "0430", "1F000000"),\ + S1("A021", "0430", "04000000"),\ + S1("C021", "0430", "30000000"),\ + S1("C421", "0430", "01000000"),\ + S1("C821", "0430", "01000000"),\ + S1("CC21", "0430", "01000000"),\ + S1("D021", "0430", "01000000"),\ + S1("D421", "0430", "01000000"),\ + S1("D821", "0430", "01000000"),\ + S1("DC21", "0430", "1F000000"),\ + S1("E021", "0430", "03000000"),\ + S1("A020", "0430", "EFE10000"),\ + S1("A420", "0430", "00000000"),\ + S1("A820", "0430", "FE210400"),\ + S1("B020", "0430", "00000000"),\ + S1("C420", "0430", "14000000"),\ + S1("C820", "0430", "00000000"),\ + S1("CC20", "0430", "20000000"),\ + S1("38A0", "0038", "5CA30000"),\ + S1("0000", "0038", "02000000"),\ + S1("0400", "0038", "00080000"),\ + S1("0800", "0038", "00120000"),\ + S1("0C00", "0038", "01030200"),\ + S1("1000", "0038", "01070200"),\ + S1("1400", "0038", "0C0C8A00"),\ + PACKET("0200", "8005", \ + "FFF98720" \ + "1AF88700" \ + "1AF88700" \ + "1AF88700" \ + "1AF88700" \ + "1AF88700" \ + "1AF88700" \ + /* NOTE: The following(?) 200 values specify order of fingerprint columns \ + * in vfs301_line_t::scan. */ \ + "1AF80720" \ + "1BF80720" \ + "1CF80720" \ + "1DF80720" \ + "1EF80720" \ + "1FF80720" \ + "20F80720" \ + "21F80720" \ + "22F80720" \ + "23F80720" \ + "24F80722" \ + "25F80722" \ + "26F80722" \ + "27F80722" \ + "28F80722" \ + "29F80722" \ + "2AF80722" \ + "2BF80722" \ + "2CF80722" \ + "2DF80722" \ + "2EF80722" \ + "2FF80722" \ + "30F80722" \ + "31F80722" \ + "32F80722" \ + "33F80722" \ + "34F80722" \ + "35F80722" \ + "36F80722" \ + "37F80722" \ + "38F80722" \ + "39F80722" \ + "3AF80722" \ + "3BF80722" \ + "3CF80722" \ + "3DF80722" \ + "3EF80722" \ + "3FF80722" \ + "40F80722" \ + "41F80722" \ + "42F80722" \ + "43F80722" \ + "44F80722" \ + "45F80722" \ + "46F80722" \ + "47F80722" \ + "48F80722" \ + "49F80722" \ + "4AF80722" \ + "4BF80722" \ + "4CF80722" \ + "4DF80722" \ + "4EF80722" \ + "4FF80722" \ + "50F80722" \ + "51F80722" \ + "52F80722" \ + "53F80722" \ + "54F80722" \ + "55F80722" \ + "56F80722" \ + "57F80722" \ + "58F80722" \ + "59F80722" \ + "5AF80722" \ + "5BF80722" \ + "5CF80722" \ + "5DF80722" \ + "5EF80722" \ + "5FF80722" \ + "60F80722" \ + "61F80722" \ + "62F80722" \ + "63F80722" \ + "64F80722" \ + "65F80722" \ + "66F80722" \ + "67F80722" \ + "68F80722" \ + "69F80722" \ + "6AF80722" \ + "6BF80722" \ + "6CF80722" \ + "6DF80722" \ + "6EF80722" \ + "6FF80722" \ + "70F80722" \ + "71F80722" \ + "72F80722" \ + "73F80722" \ + "74F80722" \ + "75F80722" \ + "76F80722" \ + "77F80722" \ + "78F80722" \ + "79F80722" \ + "7AF80722" \ + "7BF80722" \ + "7CF80722" \ + "7DF80722" \ + "7EF80722" \ + "7FF80722" \ + "80F80722" \ + "81F80722" \ + "82F80722" \ + "83F80722" \ + "84F80722" \ + "85F80722" \ + "86F80722" \ + "87F80722" \ + "88F80722" \ + "89F80722" \ + "8AF80722" \ + "8BF80722" \ + "8CF80722" \ + "8DF80722" \ + "8EF80722" \ + "8FF80722" \ + "90F80722" \ + "91F80722" \ + "92F80722" \ + "93F80722" \ + "94F80722" \ + "95F80722" \ + "96F80722" \ + "97F80722" \ + "98F80722" \ + "99F80722" \ + "9AF80722" \ + "9BF80722" \ + "9CF80722" \ + "9DF80722" \ + "9EF80722" \ + "9FF80722" \ + "A0F80722" \ + "A1F80722" \ + "A2F80722" \ + "A3F80722" \ + "A4F80722" \ + "A5F80722" \ + "A6F80722" \ + "A7F80722" \ + "A8F80722" \ + "A9F80722" \ + "AAF80722" \ + "ABF80722" \ + "ACF80722" \ + "ADF80722" \ + "AEF80722" \ + "AFF80722" \ + "B0F80722" \ + "B1F80722" \ + "B2F80722" \ + "B3F80722" \ + "B4F80722" \ + "B5F80722" \ + "B6F80722" \ + "B7F80722" \ + "B8F80722" \ + "B9F80722" \ + "BAF80722" \ + "BBF80722" \ + "BCF80722" \ + "BDF80722" \ + "BEF80722" \ + "BFF80722" \ + "C0F80722" \ + "C1F80722" \ + "C2F80722" \ + "C3F80722" \ + "C4F80722" \ + "C5F80722" \ + "C6F80722" \ + "C7F80722" \ + "C8F80722" \ + "C9F80722" \ + "CAF80722" \ + "CBF80722" \ + "CCF80722" \ + "CDF80722" \ + "CEF80722" \ + "CFF80722" \ + "D0F80722" \ + "D1F80722" \ + "D2F80722" \ + "D3F80722" \ + "D4F80722" \ + "D5F80722" \ + "D6F80722" \ + "D7F80722" \ + "D8F80720" \ + "D9F80720" \ + "DAF80720" \ + "DBF80720" \ + "DCF80720" \ + "DDF80720" \ + "DEF80720" \ + "DFF80720" \ + "E0F80720" \ + "E1F80720" \ + \ + "E1F80700" \ + "0BF88700" \ + "0BF88700" \ + "0BF88700" \ + "0BF88700" \ + "0BF88700" \ + /* NOTE: The following(?) 64 values specify order of fingerprint columns \ + * in vfs301_line_t::mirror. \ + * Placing Z8() instead of the value shortens the mirror section. \ + * */ \ + "0BF88700" \ + "0AF80720" \ + "09F80720" \ + "08F80720" \ + "07F80720" \ + "06F80720" \ + "05F80720" \ + "04F80720" \ + "03F80720" \ + "02F80720" \ + "01F80720" \ + "00F80720" \ + "17F90720" \ + "16F90720" \ + "15F90720" \ + "14F90720" \ + "13F90720" \ + "12F90720" \ + "11F90720" \ + "10F90720" \ + "0FF90720" \ + "0EF90720" \ + "0DF90720" \ + "0CF90720" \ + "0BF90720" \ + "0AF90720" \ + "09F90720" \ + "08F90720" \ + "07F90720" \ + "06F90720" \ + "05F90720" \ + "04F90720" \ + "03F90720" \ + "02F90720" \ + "01F90720" \ + "00F90720" \ + "FFF80720" \ + "FEF80720" \ + "FDF80720" \ + "FCF80720" \ + "FBF80720" \ + "FAF80720" \ + "F9F80720" \ + "F8F80720" \ + "F7F80720" \ + "F6F80720" \ + "F5F80720" \ + "F4F80720" \ + "F3F80720" \ + "F2F80720" \ + "F1F80720" \ + "F0F80720" \ + "EFF80720" \ + "EEF80720" \ + "EDF80720" \ + "ECF80720" \ + "EBF80720" \ + "EAF80720" \ + "E9F80720" \ + "E8F80720" \ + "E7F80720" \ + "E6F80720" \ + "E5F80720" \ + "E4F80720" \ + \ + "0BF80720" \ + "0BF80700" \ + \ + "5CF2C700" \ + "5CF2C700" \ + "5CF2C700" \ + "5CF2C700" \ + "5CF2C700" \ + "5CF24700" \ + "5CF24700" \ + "5CF24720" \ + "FFF94700" \ + "FFF94700" \ + "FFF94700" \ + "FFF94700" \ + "FFF94700" \ + "FFF94720" \ + "5CF84700" \ + "5CF84700" \ + "5CF84700" \ + "5CF84700" \ + \ + /* NOTE: The following(?) values specify order of fingerprint columns \ + * in vfs301_line_t::sum*. */ \ + "5CF84700" \ + "5CF84720" \ + "62F84700" \ + "62F84720" \ + "68F84700" \ + "68F84720" \ + "6EF84700" \ + "6EF84720" \ + "74F84700" \ + "74F84720" \ + "7AF84700" \ + "7AF84720" \ + "80F84700" \ + "80F84720" \ + "86F84700" \ + "86F84720" \ + "8CF84700" \ + "8CF84720" \ + "92F84700" \ + "92F84720" \ + "98F84720" \ + "9E844700" \ + "9E844720" \ + "9E844700" \ + \ + "FFF96700" "FFF96700" "FFF96700" "FFF96700" "FFF96720" \ + "0DF86700" "0DF86700" "0DF86700" "0DF86700" "0DF86700" \ + "0DF86720" "0DF86700" \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + ), \ + S3("1003181C"), \ + S1("0020", "0430", "80000000") + +#define vfs301_0220_BLOB2 \ + S2("0C20FF00FFFF0000000000030000"),\ + S2("1020FF00FFFF0000000000070000"),\ + S1("0421", "0430", "01000000"),\ + S1("0821", "0430", "02000000"),\ + S1("0C21", "0430", "01000000"),\ + S1("1021", "0430", "01000000"),\ + S1("1421", "0430", "01000000"),\ + S1("1821", "0430", "01000000"),\ + S1("4421", "0430", "01000000"),\ + S1("4821", "0430", "02000000"),\ + S1("4C21", "0430", "01000000"),\ + S1("5021", "0430", "01000000"),\ + S1("5421", "0430", "01000000"),\ + S1("5821", "0430", "01000000"),\ + S1("C820", "0430", "07000000"),\ + S2("1420FFFF00FF0000000000008800"),\ + S1("8421", "0430", "01000000"),\ + S1("8821", "0430", "01000000"),\ + S1("8C21", "0430", "01000000"),\ + S1("9021", "0430", "01000000"),\ + S1("9421", "0430", "01000000"),\ + S1("9821", "0430", "01000000"),\ + S1("A021", "0430", "00000000"),\ + S1("2021", "0430", "08000000"),\ + S1("6021", "0430", "08000000") + +#define vfs301_02D0_BLOB1 \ + S1("A820", "0430", "FE210000"), \ + S1("B020", "0430", "00000000"), \ + S1("C420", "0430", "14000000"), \ + S1("C820", "0430", "00000000"), \ + S1("CC20", "0430", "20000000"), \ + S1("38A0", "0038", "5CA30000"), \ + S1("0000", "0038", "02000000"), \ + S1("0400", "0038", "00080000"), \ + S1("0800", "0038", "00120000"), \ + S1("0C00", "0038", "01030200"), \ + S1("1000", "0038", "01070200"), \ + S1("1400", "0038", "0C0C8A00") + +#define vfs301_02D0_BLOB4 \ + PACKET("1200", "0100", "01"),\ + S2("0C20FF00FFFF0000000000030000"),\ + S2("1020FF00FFFF0000000000070000"),\ + S1("0421", "0430", "01000000"),\ + S1("0821", "0430", "02000000"),\ + S1("0C21", "0430", "01000000"),\ + S1("1021", "0430", "01000000"),\ + S1("1421", "0430", "01000000"),\ + S1("1821", "0430", "01000000"),\ + S1("4421", "0430", "01000000"),\ + S1("4821", "0430", "02000000"),\ + S1("4C21", "0430", "01000000"),\ + S1("5021", "0430", "01000000"),\ + S1("5421", "0430", "01000000"),\ + S1("5821", "0430", "01000000") + +/* TODO: looks like that removing this whole packet doesn't cause + * any troubles. */ +#define vfs301_02D0_ALIGNED_BLOB\ + PACKET("0200", "8005", \ + "FF830720" "5F820720" "FF830720" \ + "5F820720" "FF830720" "5F820720" "FF830720" \ + "5F820720" "FF830720" "5F820720" "FF8B0720" \ + "608A0720" "FF930720" "61920720" "FF9B0720" \ + "629A0720" "FFA30720" "63A20720" "FFAB0720" \ + "64AA0720" "FFB30720" "65B20720" "FFBB0720" \ + "66BA0720" "FFC30720" "67C20720" "FFCB0720" \ + "68CA0720" "FFD30720" "69D20720" "FFDB0720" \ + "6ADA0720" "FFE30720" "6BE20720" "FFEB0720" \ + "6CEA0720" "FFF30720" "6DF20720" "FFFB0720" \ + "6EFA0720" "FF850720" "6F840720" "FF8D0720" \ + "708C0720" "FF950720" "71940720" "FF9D0720" \ + "729C0720" "FFA50720" "73A40720" "FFAD0720" \ + "74AC0720" "FFB50720" "75B40720" "FFBD0720" \ + "76BC0720" "FFC50720" "77C40720" "FFCD0720" \ + "78CC0720" "FFD50720" "79D40720" "FFDD0720" \ + "7ADC0720" "FFE50720" "7BE40720" "FFED0720" \ + "7CEC0720" "FFF50720" "7DF40720" "FFFD0720" \ + "7EFC0720" "FF870720" "7F860720" "FF8F0720" \ + "808E0720" "FF970720" "81960720" "FF9F0720" \ + "829E0720" "FFA70720" "83A60720" "FFAF0720" \ + "84AE0720" "FFB70720" "85B60720" "FFBF0720" \ + "86BE0720" "FFC70720" "87C60720" "FFCF0720" \ + "88CE0720" "FFD70720" "89D60720" "FFDF0720" \ + "8ADE0720" "FFE70720" "8BE60720" "FFEF0720" \ + "8CEE0720" "FFF70720" "8DF60720" "FFFF0720" \ + "8EFE0720" \ + "FFFF0720" "8EFE0720" "FFF70720" "8DF60720" \ + "FFEF0720" "8CEE0720" "FFE70720" "8BE60720" \ + "FFDF0720" "8ADE0720" "FFD70720" "89D60720" \ + "FFCF0720" "88CE0720" "FFC70720" "87C60720" \ + "FFBF0720" "86BE0720" "FFB70720" "85B60720" \ + "FFAF0720" "84AE0720" "FFA70720" "83A60720" \ + "FF9F0720" "829E0720" "FF970720" "81960720" \ + "FF8F0720" "808E0720" "FF870720" "7F860720" \ + "FFFD0720" "7EFC0720" "FFF50720" "7DF40720" \ + "FFED0720" "7CEC0720" "FFE50720" "7BE40720" \ + "FFDD0720" "7ADC0720" "FFD50720" "79D40720" \ + "FFCD0720" "78CC0720" "FFC50720" "77C40720" \ + "FFBD0720" "76BC0720" "FFB50720" "75B40720" \ + "FFAD0720" "74AC0720" "FFA50720" "73A40720" \ + "FF9D0720" "729C0720" "FF950720" "71940720" \ + "FF8D0720" "708C0720" "FF850720" "6F840720" \ + "FFFB0720" "6EFA0720" "FFF30720" "6DF20720" \ + "FFEB0720" "6CEA0720" "FFE30720" "6BE20720" \ + "FFDB0720" "6ADA0720" "FFD30720" "69D20720" \ + "FFCB0720" "68CA0720" "FFC30720" "67C20720" \ + "FFBB0720" "66BA0720" "FFB30720" "65B20720" \ + "FFAB0720" "64AA0720" "FFA30720" "63A20720" \ + "FF9B0720" "629A0720" "FF930720" "61920720" \ + "FF8B0720" "608A0720" "FF830720" "5F820720" \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() \ + ),\ + S3("1003181C"),\ + S1("0020", "0430", "80000000") + +const char *vfs301_0220_01[] = { + "0220010100", + + /* NOTE: replacing this by vfs301_0220_BLOB1 seems to not cause problems */ + S1("0420", "0430", "00000000"), + S1("1820", "0430", "00000000"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "AD010000"), + S1("4420", "0430", "AD010000"), + S1("4820", "0430", "AD010000"), + S1("4C20", "0430", "FF030000"), + S1("5020", "0430", "00005003"), + S1("5420", "0430", "013E0200"), + S1("0021", "0430", "14000000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "01000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "01000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "01000000"), + S1("1C21", "0430", "12000000"), + S1("2021", "0430", "04000000"), + S1("4021", "0430", "00000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "10000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "01000000"), + S1("5421", "0430", "00000000"), + S1("5821", "0430", "01000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "0F000000"), + S1("8021", "0430", "00000000"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "10000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "00000000"), + S1("9821", "0430", "01000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "0F000000"), + S1("C021", "0430", "00000000"), + S1("C421", "0430", "01000000"), + S1("C821", "0430", "10000000"), + S1("CC21", "0430", "01000000"), + S1("D021", "0430", "01000000"), + S1("D421", "0430", "00000000"), + S1("D821", "0430", "01000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "0F000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00000000"), + S1("A820", "0430", "FE210000"), + S1("B020", "0430", "00000000"), + S1("C420", "0430", "47000000"), + S1("C820", "0430", "00000000"), + S1("CC20", "0430", "20000000"), + S1("38A0", "0038", "5CA30000"), + S1("0000", "0038", "02000000"), + S1("0400", "0038", "00080000"), + S1("0800", "0038", "00120000"), + S1("0C00", "0038", "01030200"), + S1("1000", "0038", "01070200"), + S1("1400", "0038", "0C0C8A00"), + + /* TODO: looks like that removing this whole packet doesn't cause + * any troubles. */ + PACKET("0200", "8005", + "FFF98720" + "83488420" + "83488420" + "83488420" + "83488420" + "83488420" + "83488420" + "83488420" + "83488420" + "83488420" + "83488420" + "85480420" + "87480420" + "89480420" + "8B480420" + "8D480420" + "8F480420" + "91480420" + "93480420" + "95480420" + "97480420" + "99480420" + "9B480420" + "9D480420" + "9F480420" + "A1480420" + "A3480420" + "A3480400" + "855A0420" + "875A0420" + "895A0420" + "8B5A0420" + "8D5A0420" + "8F5A0420" + "915A0420" + "935A0420" + "955A0420" + "975A0420" + "995A0420" + "9B5A0420" + "9D5A0420" + "9F5A0420" + "A15A0420" + "A35A0420" + "A35A0400" + "856C0420" + "876C0420" + "896C0420" + "8B6C0420" + "8D6C0420" + "8F6C0420" + "916C0420" + "936C0420" + "956C0420" + "976C0420" + "996C0420" + "9B6C0420" + "9D6C0420" + "9F6C0420" + "A16C0420" + "A36C0420" + "A36C0400" + "86480420" + "88480420" + "8A480420" + "8C480420" + "8E480420" + "90480420" + "92480420" + "94480420" + "96480420" + "98480420" + "9A480420" + "9C480420" + "9E480420" + "A0480420" + "A2480420" + "A4480420" + "A4480400" + "865A0420" + "885A0420" + "8A5A0420" + "8C5A0420" + "8E5A0420" + "905A0420" + "925A0420" + "945A0420" + "965A0420" + "985A0420" + "9A5A0420" + "9C5A0420" + "9E5A0420" + "A05A0420" + "A25A0420" + "A45A0420" + "A45A0400" + "866C0420" + "886C0420" + "8A6C0420" + "8C6C0420" + "8E6C0420" + "906C0420" + "926C0420" + "946C0420" + "966C0420" + "986C0420" + "9A6C0420" + "9C6C0420" + "9E6C0420" + "A06C0420" + "A26C0420" + "A46C0420" + "A46C0400" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" "83688420" "83688420" + "83688420" "83688420" + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() + ), + S3("10035109"), + S1("0020", "0430", "80000000"), + + TERM(), + + NULL +}; + + +const char *vfs301_next_scan_template[] = { + PACKET("0220", "0100", "00"), + + vfs301_0220_BLOB1, + + vfs301_0220_BLOB2, + + TERM(), + + S4("DEAD"), + + NULL +}; + +const char *vfs301_0220_02[] = { + "0220011400", + + vfs301_0220_BLOB1, + + vfs301_0220_BLOB2, + + TERM(), + + NULL +}; + +const char *vfs301_0220_03[] = { + "0220011400", + + vfs301_0220_BLOB1, + + "17000000", + + vfs301_0220_BLOB2, + + TERM(), + + NULL +}; + + +const char *vfs301_02D0_01[] = { + "02D0003800", + + S1("0420", "0430", "00000000"), + S1("1820", "0430", "01807800"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "FF030000"), + S1("4420", "0430", "E6030000"), + S1("4820", "0430", "E7030000"), + S1("4C20", "0430", "E8030000"), + S1("5020", "0430", "00025802"), + S1("5420", "0430", "00E20100"), + S1("0021", "0430", "00000000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "01000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "01000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "01000000"), + S1("1C21", "0430", "1F000000"), + S1("2021", "0430", "01000000"), + S1("4021", "0430", "00000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "01000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "01000000"), + S1("5421", "0430", "01000000"), + S1("5821", "0430", "01000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "01000000"), + S1("8021", "0430", "00000000"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "01000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "01000000"), + S1("C021", "0430", "00000000"), + S1("C421", "0430", "01000000"), + S1("C821", "0430", "01000000"), + S1("CC21", "0430", "01000000"), + S1("D021", "0430", "01000000"), + S1("D421", "0430", "01000000"), + S1("D821", "0430", "01000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "01000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00000000"), + vfs301_02D0_BLOB1, + vfs301_02D0_ALIGNED_BLOB, + + PACKET("0C00", "0100", "00"), + PACKET("0D00", "E800", + "C0000000080000000200000000000000" + "00000050D52200180000009CCE156100" + "0000002003000000" + "0C00003800080000FF00FFFF" + "0C00003800090000FF00FFFF" + "0C00003800020000FF00FFFF" + "0C00003800030000FF00FFFF" + "0C00003800040000FF00FFFF" + "0C00003800050000FF00FFFF" + "0C00003800060000FF00FFFF" + "0C00003800070000FF00FFFF" + "1000003800040000FF00FFFF" + "1000003800050000FF00FFFF" + "1000003800060000FF00FFFF" + "1000003800070000FF00FFFF" + "1000003800080000FF00FFFF" + "1000003800090000FF00FFFF" + "10000038000A0000FF00FFFF" + "10000038000B0000FF00FFFF"), + PACKET("0E00", "E000", + "000100010101011F010000000000FF01" + "000101010101011F010000000000FF01" + "000102010101011F010000000000FF01" + "000104010101011F010000000000FF01" + "000108010101011F010000000000FF01" + "000110010101011F010000000000FF01" + "000110010201011F010000000000FF01" + "000110010401011F010000000000FF01" + "000110010801011F010000000000FF01" + "000110011001011F010000000000FF01" + "000110011001021F010000000000FF01" + "000110011001041F010000000000FF01" + "000110011001081F010000000000FF01" + "000110011001101F010000000000FF01" + "0F000100021000010001110002000800" ), + PACKET("1200", "0100", "0E"), + + TERM(), + + NULL +}; + + +const char *vfs301_02D0_02[] = { + "02D0000001", + + S1("0420", "0430", "00000000"), + S1("1820", "0430", "01806300"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "FF030000"), + S1("4420", "0430", "E6030000"), + S1("4820", "0430", "E7030000"), + S1("4C20", "0430", "E8030000"), + S1("5020", "0430", "00025802"), + S1("5420", "0430", "008E0100"), + S1("0021", "0430", "00000000"), + S1("0421", "0430", "00000000"), + S1("0821", "0430", "00000000"), + S1("0C21", "0430", "00000000"), + S1("1021", "0430", "00000000"), + S1("1421", "0430", "00000000"), + S1("1821", "0430", "00000000"), + S1("1C21", "0430", "1F000000"), + S1("2021", "0430", "01000000"), + S1("4021", "0430", "00000000"), + S1("4421", "0430", "00000000"), + S1("4821", "0430", "00000000"), + S1("4C21", "0430", "00000000"), + S1("5021", "0430", "00000000"), + S1("5421", "0430", "00000000"), + S1("5821", "0430", "00000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "01000000"), + S1("8021", "0430", "00000000"), + S1("8421", "0430", "00000000"), + S1("8821", "0430", "00000000"), + S1("8C21", "0430", "00000000"), + S1("9021", "0430", "00000000"), + S1("9421", "0430", "00000000"), + S1("9821", "0430", "00000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "01000000"), + S1("C021", "0430", "00000000"), + S1("C421", "0430", "00000000"), + S1("C821", "0430", "00000000"), + S1("CC21", "0430", "00000000"), + S1("D021", "0430", "00000000"), + S1("D421", "0430", "00000000"), + S1("D821", "0430", "00000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "01000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00400000"), + vfs301_02D0_BLOB1, + vfs301_02D0_ALIGNED_BLOB, + + PACKET("0C00", "0100", "03"), + PACKET("0D00", "2800", "C82004300000000001000000FF00000000FFFFFF01000000C8200430000000000000003001000000"), + PACKET("0E00", "1000", "000101010100011F0800000000000001"), + PACKET("0F00", "0100", "01"), + PACKET("1000", "0100", "01"), + PACKET("1100", "0200", "0001"), + vfs301_02D0_BLOB4, + + TERM(), + + NULL +}; + + +const char *vfs301_02D0_03[] = { + "02D0006000", + + S1("0420", "0430", "00000000"), + S1("1820", "0430", "01806300"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "FF030000"), + S1("4420", "0430", "E6030000"), + S1("4820", "0430", "E7030000"), + S1("4C20", "0430", "E8030000"), + S1("5020", "0430", "00025802"), + S1("5420", "0430", "008E0100"), + S1("0021", "0430", "00000000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "01000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "01000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "01000000"), + S1("1C21", "0430", "1F000000"), + S1("2021", "0430", "05000000"), + S1("4021", "0430", "00000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "01000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "01000000"), + S1("5421", "0430", "01000000"), + S1("5821", "0430", "01000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "05000000"), + S1("8021", "0430", "00000000"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "01000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "05000000"), + S1("C021", "0430", "00000000"), + S1("C421", "0430", "01000000"), + S1("C821", "0430", "01000000"), + S1("CC21", "0430", "01000000"), + S1("D021", "0430", "01000000"), + S1("D421", "0430", "01000000"), + S1("D821", "0430", "01000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "05000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00000000"), + vfs301_02D0_BLOB1, + vfs301_02D0_ALIGNED_BLOB, + + PACKET("0C00", "0100", "02"), + PACKET("0D00", "2800", "1400003800006E000000010000008F00FFFF00FF01000000000002000000010000000F0002000000"), + PACKET("0E00", "1000", "00000000000000000500000000000001"), + PACKET("0F00", "0100", "01"), + PACKET("1000", "0100", "02") + PACKET("1100", "0200", "6000"), + vfs301_02D0_BLOB4, + S1("C820", "0430", "07000000"), + + TERM(), + + NULL +}; + + +const char *vfs301_02D0_04[] = { + "02D0001C00", + + S1("0420", "0430", "00000000"), + S1("1820", "0430", "01806300"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "FF030000"), + S1("4420", "0430", "E7030000"), + S1("4820", "0430", "FF030000"), + S1("4C20", "0430", "FF030000"), + S1("5020", "0430", "00025802"), + S1("5420", "0430", "008E0100"), + S1("0021", "0430", "30000000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "01000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "01000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "01000000"), + S1("1C21", "0430", "1F000000"), + S1("2021", "0430", "00000000"), + S1("4021", "0430", "30000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "01000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "01000000"), + S1("5421", "0430", "01000000"), + S1("5821", "0430", "01000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "00000000"), + S1("8021", "0430", "30000000"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "01000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "00000000"), + S1("C021", "0430", "30000000"), + S1("C421", "0430", "01000000"), + S1("C821", "0430", "01000000"), + S1("CC21", "0430", "01000000"), + S1("D021", "0430", "01000000"), + S1("D421", "0430", "01000000"), + S1("D821", "0430", "01000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "00000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00000000"), + vfs301_02D0_BLOB1, + + /* TODO: looks like that removing this whole packet doesn't cause + * any troubles. */ + PACKET("0200", "8005", + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + "FFF30720" "80F20720" "FFF30720" "80F20720" + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + ), + + S3("1003181C"), + S1("0020", "0430", "80000000"), + + PACKET("0C00", "0100", "00"), + PACKET("0D00", "2800", "A02104300100000001000000010000000100000001000000A0210430000000000031003801000000"), + PACKET("0E00", "E000", + "00010001000100000000000000007E00" + "00010101000100000000000000007E00" + "00010101010100000000000000007E00" + "00010101010101000000000000007E00" + "00010201010101000000000000007E00" + "00010401010101000000000000007E00" + "00010801010101000000000000007E00" + "00011001010101000000000000007E00" + "00011001020101000000000000007E00" + "00011001040101000000000000007E00" + "00011001080101000000000000007E00" + "00011001100102000000000000007E00" + "00011001100104000000000000007E00" + "00011001100108000000000000007E00"), + PACKET("0F00", "0100", "01"), + PACKET("1000", "0100", "02"), + PACKET("1100", "0200", "0200"), + PACKET("1200", "0100", "0E"), + S2("0C20FF00FFFF0000000000030000"), + S2("1020FF00FFFF0000000000070000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "02000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "01000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "01000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "02000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "01000000"), + S1("5421", "0430", "01000000"), + S1("5821", "0430", "01000000"), + S1("C820", "0430", "07000000"), + S2("1420FFFF00FF0000000000008800"), + + TERM(), + + NULL +}; + +/* Sorry had to replace BLOB3 (was a fragment!) */ +const char *vfs301_02D0_05[] = { + "02D0002000", + + S1("0420", "0430", "00000000"), + S1("1820", "0430", "01806300"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "FF030000"), + S1("4420", "0430", "E7030000"), + S1("4820", "0430", "FF030000"), + S1("4C20", "0430", "FF030000"), + S1("5020", "0430", "00025802"), + S1("5420", "0430", "008E0100"), + S1("0021", "0430", "30000000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "01000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "00000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "00000000"), + S1("1C21", "0430", "1F000000"), + S1("2021", "0430", "04000000"), + S1("4021", "0430", "30000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "01000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "00000000"), + S1("5421", "0430", "01000000"), + S1("5821", "0430", "00000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "04000000"), + S1("8021", "0430", "30000000"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "00000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "00000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "04000000"), + S1("C021", "0430", "30000000"), + S1("C421", "0430", "01000000"), + S1("C821", "0430", "01000000"), + S1("CC21", "0430", "01000000"), + S1("D021", "0430", "00000000"), + S1("D421", "0430", "01000000"), + S1("D821", "0430", "00000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "04000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00000000"), + vfs301_02D0_BLOB1, + + /* TODO: looks like that removing this whole packet doesn't cause + * any troubles. */ + PACKET("0200", "8005", + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + "FFF34720" "80F24720" "FFF34720" "80F24720" + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() + Z8() Z8() Z8() Z8() Z8() Z8() Z8() Z8() ), + + S3("1003181C"), + S1("0020", "0430", "80000000") + + PACKET("0C00", "0100", "01"), + PACKET("0D00", "2800", "A021043000000000010000000F00000000FFFFFF01000000A0210430000000000000003001000000"), + PACKET("0E00", "1000", "00000000000000000000000000000000"), + PACKET("0F00", "0100", "01"), + PACKET("1000", "0100", "02"), + PACKET("1100", "0200", "2000"), + vfs301_02D0_BLOB4, + S1("C820", "0430", "07000000"), + S2("1420FFFF00FF0000000000008800"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "01000000"), + + TERM(), + + NULL +}; + + +const char *vfs301_02D0_06[] = { + "02D0002000", + + S1("0420", "0430", "00000000"), + S1("1820", "0430", "01806300"), + S1("2020", "0430", "08008000"), + S1("2420", "0430", "0000FF01"), + S1("2C20", "0430", "01000000"), + S1("4020", "0430", "FF030000"), + S1("4420", "0430", "E6030000"), + S1("4820", "0430", "E7030000"), + S1("4C20", "0430", "E8030000"), + S1("5020", "0430", "00025802"), + S1("5420", "0430", "008E0100"), + S1("0021", "0430", "00000000"), + S1("0421", "0430", "01000000"), + S1("0821", "0430", "01000000"), + S1("0C21", "0430", "01000000"), + S1("1021", "0430", "01000000"), + S1("1421", "0430", "01000000"), + S1("1821", "0430", "01000000"), + S1("1C21", "0430", "1F000000"), + S1("2021", "0430", "08000000"), + S1("4021", "0430", "00000000"), + S1("4421", "0430", "01000000"), + S1("4821", "0430", "01000000"), + S1("4C21", "0430", "01000000"), + S1("5021", "0430", "01000000"), + S1("5421", "0430", "01000000"), + S1("5821", "0430", "01000000"), + S1("5C21", "0430", "1F000000"), + S1("6021", "0430", "08000000"), + S1("8021", "0430", "00000000"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "01000000"), + S1("9C21", "0430", "1F000000"), + S1("A021", "0430", "08000000"), + S1("C021", "0430", "00000000"), + S1("C421", "0430", "01000000"), + S1("C821", "0430", "01000000"), + S1("CC21", "0430", "01000000"), + S1("D021", "0430", "01000000"), + S1("D421", "0430", "01000000"), + S1("D821", "0430", "01000000"), + S1("DC21", "0430", "1F000000"), + S1("E021", "0430", "08000000"), + S1("A020", "0430", "EFE10000"), + S1("A420", "0430", "00000000"), + vfs301_02D0_BLOB1, + vfs301_02D0_ALIGNED_BLOB, + + PACKET("0C00", "0100", "01"), + PACKET("0D00", "2800", "2021043000000000010000000F00000000FFFFFF0100000020210430000000000000003001000000"), + PACKET("0E00", "1000", "00000000000000000000000000000001"), + PACKET("0F00", "0100", "01"), + PACKET("1000", "0100", "02"), + PACKET("1100", "0200", "2000"), + vfs301_02D0_BLOB4, + S1("C820", "0430", "07000000"), + S2("1420FFFF00FF0000000000008800"), + S1("8421", "0430", "01000000"), + S1("8821", "0430", "01000000"), + S1("8C21", "0430", "01000000"), + S1("9021", "0430", "01000000"), + S1("9421", "0430", "01000000"), + S1("9821", "0430", "01000000"), + S1("A021", "0430", "00000000"), + + TERM(), + + NULL +}; + + +const char *vfs301_02D0_07[] = { + "02D0000400" + S3("1003181C"), + PACKET("0C00", "0100", "04"), + PACKET("0D00", "2800", "28A0003803000000020000003B000000C0FFFFFF0100000028A00038000000001047004801000000"), + PACKET("1100", "0200", "0400"), + PACKET("1300", "0400", "18000000"), + PACKET("1400", "0400", "1E000000"), + + S1("A020", "0430", "EFE10000"), + S1("08A0", "0038", "78000200"), + S1("10A0", "0038", "E3186800"), + S1("14A0", "0038", "E3186800"), + S1("18A0", "0038", "E3186800"), + S1("1CA0", "0038", "E3186800"), + S1("20A0", "0038", "E3186800"), + S1("24A0", "0038", "0CFA8000"), + S1("28A0", "0038", "00000800"), + S1("04A0", "0038", "FFFFFFFF"), + + vfs301_0220_BLOB2, + + TERM(), + + NULL +}; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 5bd46279..44881cd1 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -268,6 +268,9 @@ extern struct fp_img_driver vcom5s_driver; #ifdef ENABLE_VFS101 extern struct fp_img_driver vfs101_driver; #endif +#ifdef ENABLE_VFS301 +extern struct fp_img_driver vfs301_driver; +#endif extern libusb_context *fpi_usb_ctx; extern GSList *opened_devices; From 132b17830492187b80c8442b1e6e981343b1d27e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Aug 2012 20:02:17 +0100 Subject: [PATCH 11/49] lib: Add driver names to the udev rules --- libfprint/fprint-list-udev-rules.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c index 182ee107..791a4575 100644 --- a/libfprint/fprint-list-udev-rules.c +++ b/libfprint/fprint-list-udev-rules.c @@ -35,13 +35,16 @@ static const struct usb_id blacklist_id_table[] = { struct fp_driver whitelist = { .id_table = whitelist_id_table, + .full_name = "Hardcoded whitelist" }; GHashTable *printed = NULL; static void print_driver (struct fp_driver *driver) { - int i, j, blacklist; + int i, j, blacklist, num_printed; + + num_printed = 0; for (i = 0; driver->id_table[i].vendor != 0; i++) { char *key; @@ -66,8 +69,15 @@ static void print_driver (struct fp_driver *driver) g_hash_table_insert (printed, key, GINT_TO_POINTER (1)); + if (num_printed == 0) + printf ("# %s\n", driver->full_name); + printf ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", ATTR{power/control}=\"auto\"\n", driver->id_table[i].vendor, driver->id_table[i].product); + num_printed++; } + + if (num_printed > 0) + printf ("\n"); } int main (int argc, char **argv) From 83333bce3f06ca55651a7516666ee63a5892f09f Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 9 Oct 2012 01:20:44 +0300 Subject: [PATCH 12/49] lib: Add AES2550/AES2810 driver Initial implementation of AES2550/AES2810 driver. Does not support AES2810 crypto engine and external flash. https://bugs.freedesktop.org/show_bug.cgi?id=50859 --- configure.ac | 14 +- libfprint/Makefile.am | 6 + libfprint/core.c | 3 + libfprint/drivers/aes2550.c | 741 ++++++++++++++++++++++++++++++++++++ libfprint/drivers/aes2550.h | 114 ++++++ libfprint/fp_internal.h | 3 + 6 files changed, 880 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/aes2550.c create mode 100644 libfprint/drivers/aes2550.h diff --git a/configure.ac b/configure.ac index a2bd3c25..90cb0f61 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) AC_SUBST(lt_age) -all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000 vfs101 vfs301" +all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes2550 aes4000 vfs101 vfs301" require_imaging='no' require_aeslib='no' @@ -36,6 +36,7 @@ enable_uru4000='no' enable_fdu2000='no' enable_aes1610='no' enable_aes2501='no' +enable_aes2550='no' enable_aes4000='no' enable_vfs101='no' enable_vfs301='no' @@ -82,6 +83,11 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do require_aeslib="yes" enable_aes2501="yes" ;; + aes2550) + AC_DEFINE([ENABLE_AES2550], [], [Build AuthenTec AES2550/AES2810 driver]) + require_aeslib="yes" + enable_aes2550="yes" + ;; aes1610) AC_DEFINE([ENABLE_AES1610], [], [Build AuthenTec AES1610 driver]) require_aeslib="yes" @@ -113,6 +119,7 @@ AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" = "yes"]) AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" = "yes"]) AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" = "yes"]) AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) +AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"]) AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"]) AM_CONDITIONAL([ENABLE_VFS101], [test "$enable_vfs101" = "yes"]) @@ -294,6 +301,11 @@ if test x$enable_aes2501 != xno ; then else AC_MSG_NOTICE([ aes2501 driver disabled]) fi +if test x$enable_aes2550 != xno ; then + AC_MSG_NOTICE([** aes2550/aes2810 driver enabled]) +else + AC_MSG_NOTICE([ aes2550/aes2810 driver disabled]) +fi if test x$enable_aes4000 != xno ; then AC_MSG_NOTICE([** aes4000 driver enabled]) else diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 96489e6d..5ecf0622 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -9,6 +9,7 @@ UPEKSONLY_SRC = drivers/upeksonly.c URU4000_SRC = drivers/uru4000.c AES1610_SRC = drivers/aes1610.c AES2501_SRC = drivers/aes2501.c drivers/aes2501.h +AES2550_SRC = drivers/aes2550.c drivers/aes2550.h AES4000_SRC = drivers/aes4000.c FDU2000_SRC = drivers/fdu2000.c VCOM5S_SRC = drivers/vcom5s.c @@ -23,6 +24,7 @@ EXTRA_DIST = \ $(URU4000_SRC) \ $(AES1610_SRC) \ $(AES2501_SRC) \ + $(AES2550_SRC) \ $(AES4000_SRC) \ $(FDU2000_SRC) \ $(VCOM5S_SRC) \ @@ -124,6 +126,10 @@ if ENABLE_AES2501 DRIVER_SRC += $(AES2501_SRC) endif +if ENABLE_AES2550 +DRIVER_SRC += $(AES2550_SRC) +endif + if ENABLE_AES4000 DRIVER_SRC += $(AES4000_SRC) endif diff --git a/libfprint/core.c b/libfprint/core.c index 3a430b7a..9916faa3 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -355,6 +355,9 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_AES2501 &aes2501_driver, #endif +#ifdef ENABLE_AES2550 + &aes2550_driver, +#endif #ifdef ENABLE_URU4000 &uru4000_driver, #endif diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c new file mode 100644 index 00000000..92c988ed --- /dev/null +++ b/libfprint/drivers/aes2550.c @@ -0,0 +1,741 @@ +/* + * AuthenTec AES2550/AES2810 driver for libfprint + * Copyright (C) 2007-2008 Daniel Drake + * Copyright (C) 2007 Cyrille Bagard + * Copyright (C) 2007-2012 Vasily Khoruzhick + * + * Based on AES2501 driver + * + * 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 + */ + +#define FP_COMPONENT "aes2550" + +#include +#include + +#include + +#include +#include +#include "aes2550.h" + +static void start_capture(struct fp_img_dev *dev); +static void complete_deactivation(struct fp_img_dev *dev); + +#define EP_IN (1 | LIBUSB_ENDPOINT_IN) +#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) +#define BULK_TIMEOUT 4000 + +/* + * The AES2550 is an imaging device using a swipe-type sensor. It samples + * the finger at preprogrammed intervals, sending a 192x16 frame to the + * computer. + * Unless the user is scanning their finger unreasonably fast, the frames + * *will* overlap. The implementation below detects this overlap and produces + * a contiguous image as the end result. + * The fact that the user determines the length of the swipe (and hence the + * number of useful frames) and also the fact that overlap varies means that + * images returned from this driver vary in height. + */ + +#define FRAME_WIDTH 192 +#define FRAME_HEIGHT 8 +#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) + +struct aes2550_dev { + GSList *strips; + size_t strips_len; + gboolean deactivating; +}; + +/****** IMAGE PROCESSING ******/ + +/* find overlapping parts of frames */ +static unsigned int find_overlap(unsigned char *first_frame, + unsigned char *second_frame, unsigned int *min_error) +{ + unsigned int dy; + unsigned int not_overlapped_height = 0; + /* 255 is highest brightness value for an 8bpp image */ + *min_error = 255 * FRAME_SIZE; + for (dy = 0; dy < FRAME_HEIGHT; dy++) { + /* Calculating difference (error) between parts of frames */ + unsigned int i; + unsigned int error = 0; + for (i = 0; i < FRAME_WIDTH * (FRAME_HEIGHT - dy); i++) { + /* Using ? operator to avoid abs function */ + error += first_frame[i] > second_frame[i] ? + (first_frame[i] - second_frame[i]) : + (second_frame[i] - first_frame[i]); + } + + /* Normalize error */ + error *= 15; + error /= i; + if (error < *min_error) { + *min_error = error; + not_overlapped_height = dy; + } + first_frame += FRAME_WIDTH; + } + + return not_overlapped_height; +} + +/* assemble a series of frames into a single image */ +static unsigned int assemble(struct aes2550_dev *aesdev, unsigned char *output, + gboolean reverse, unsigned int *errors_sum) +{ + uint8_t *assembled = output; + int frame; + uint32_t image_height = FRAME_HEIGHT; + unsigned int min_error; + size_t num_strips = aesdev->strips_len; + GSList *list_entry = aesdev->strips; + *errors_sum = 0; + + if (reverse) + output += (num_strips - 1) * FRAME_SIZE; + for (frame = 0; frame < num_strips; frame++) { + aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output); + + if (reverse) + output -= FRAME_SIZE; + else + output += FRAME_SIZE; + list_entry = g_slist_next(list_entry); + } + + /* Detecting where frames overlaped */ + output = assembled; + for (frame = 1; frame < num_strips; frame++) { + int not_overlapped; + + output += FRAME_SIZE; + not_overlapped = find_overlap(assembled, output, &min_error); + *errors_sum += min_error; + image_height += not_overlapped; + assembled += FRAME_WIDTH * not_overlapped; + memcpy(assembled, output, FRAME_SIZE); + } + return image_height; +} + +static void assemble_and_submit_image(struct fp_img_dev *dev) +{ + struct aes2550_dev *aesdev = dev->priv; + size_t final_size; + struct fp_img *img; + unsigned int errors_sum, r_errors_sum; + + BUG_ON(aesdev->strips_len == 0); + + /* reverse list */ + aesdev->strips = g_slist_reverse(aesdev->strips); + + /* create buffer big enough for max image */ + img = fpi_img_new(aesdev->strips_len * FRAME_SIZE); + + img->flags = FP_IMG_COLORS_INVERTED; + img->height = assemble(aesdev, img->data, FALSE, &errors_sum); + img->height = assemble(aesdev, img->data, TRUE, &r_errors_sum); + + if (r_errors_sum > errors_sum) { + img->height = assemble(aesdev, img->data, FALSE, &errors_sum); + img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; + fp_dbg("normal scan direction"); + } else { + fp_dbg("reversed scan direction"); + } + + /* now that overlap has been removed, resize output image buffer */ + final_size = img->height * FRAME_WIDTH; + img = fpi_img_resize(img, final_size); + fpi_imgdev_image_captured(dev, img); + + /* free strips and strip list */ + g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); + g_slist_free(aesdev->strips); + aesdev->strips = NULL; + aesdev->strips_len = 0; +} + + +/****** FINGER PRESENCE DETECTION ******/ + +static unsigned char finger_det_reqs[] = { + 0x80, AES2550_REG80_MASTER_RESET, + 0x95, (8 << AES2550_REG95_COL_SCANNED_OFS) | (1 << AES2550_REG95_EPIX_AVG_OFS), + 0xad, 0x00, + 0xbd, (0 << AES2550_REGBD_LPO_IN_15_8_OFS), + 0xbe, (0 << AES2550_REGBE_LPO_IN_7_0_OFS), + 0xcf, AES2550_REGCF_INTERFERENCE_CHK_EN, + AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */ + AES2550_CMD_RUN_FD, +}; + +static void start_finger_detection(struct fp_img_dev *dev); + +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; + } + + fp_dbg("transfer completed, len: %.4x, data: %.2x %.2x", + transfer->actual_length, (int)data[0], (int)data[1]); + + /* Check if we got 2 bytes, reg address 0x83 and its value */ + if ((transfer->actual_length >= 2) && (data[0] == 0x83) && (data[1] & AES2550_REG83_FINGER_PRESENT)) { + /* 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); + } +out: + g_free(data); + libusb_free_transfer(transfer); +} + +static void finger_det_reqs_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, got %d bytes", t->length, t->actual_length); + fpi_imgdev_session_error(dev, -EPROTO); + goto exit_free_transfer; + } + + transfer = libusb_alloc_transfer(0); + if (!transfer) { + fpi_imgdev_session_error(dev, -ENOMEM); + goto exit_free_transfer; + } + + /* 2 bytes of result */ + data = g_malloc(AES2550_EP_IN_BUF_SIZE); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + finger_det_data_cb, dev, BULK_TIMEOUT); + + 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); +} + +static void start_finger_detection(struct fp_img_dev *dev) +{ + int r; + struct aes2550_dev *aesdev = dev->priv; + struct libusb_transfer *transfer; + fp_dbg(""); + + if (aesdev->deactivating) { + complete_deactivation(dev); + return; + } + + transfer = libusb_alloc_transfer(0); + if (!transfer) { + fpi_imgdev_session_error(dev, -ENOMEM); + return; + } + libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, finger_det_reqs, + sizeof(finger_det_reqs), finger_det_reqs_cb, dev, BULK_TIMEOUT); + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + fpi_imgdev_session_error(dev, r); + } +} + +/****** CAPTURE ******/ + +static unsigned char capture_reqs[] = { + 0x80, AES2550_REG80_MASTER_RESET, + 0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_HGC_ENABLE), + 0x85, AES2550_REG85_FLUSH_PER_FRAME, + 0x8f, AES2550_REG8F_AUTH_DISABLE | AES2550_REG8F_EHISTO_DISABLE, + 0xbf, AES2550_REGBF_RSR_DIR_UPDOWN_MOTION | AES2550_REGBF_RSR_LEVEL_SUPER_RSR, + 0xcf, (3 << AES2550_REGCF_INTERFERENCE_AVG_OFFS) | AES2550_REGCF_INTERFERENCE_AVG_EN, + 0xdc, (1 << AES2550_REGDC_BP_NUM_REF_SWEEP_OFS), + AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x03, /* Heart beat cmd, 3 * 16 cycles without sending image */ + AES2550_CMD_GET_ENROLL_IMG, +}; + +static unsigned char capture_set_idle_reqs[] = { + 0x80, AES2550_REG80_MASTER_RESET, + AES2550_CMD_HEARTBEAT, 0x00, 0x01, 0x00, /* Heart beat off */ + AES2550_CMD_SET_IDLE_MODE, +}; + +enum capture_states { + CAPTURE_WRITE_REQS, + CAPTURE_READ_DATA, + CAPTURE_SET_IDLE, + CAPTURE_NUM_STATES, +}; + +/* Returns number of processed bytes */ +static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data) +{ + unsigned char *stripdata; + struct fp_img_dev *dev = ssm->priv; + struct aes2550_dev *aesdev = dev->priv; + int len; + + if (data[0] != AES2550_EDATA_MAGIC) { + fp_dbg("Bogus magic: %.2x\n", (int)(data[0])); + return -EPROTO; + } + len = data[1] * 256 + data[2]; + if (len != (AES2550_STRIP_SIZE - 3)) { + fp_dbg("Bogus frame len: %.4x\n", len); + } + stripdata = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2); /* 4 bits per pixel */ + if (!stripdata) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + return -ENOMEM; + } + memcpy(stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2); + aesdev->strips = g_slist_prepend(aesdev->strips, stripdata); + aesdev->strips_len++; + + return 0; +} + +static void capture_reqs_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + assemble_and_submit_image(dev); + fpi_imgdev_report_finger_status(dev, FALSE); + /* marking machine complete will re-trigger finger detection loop */ + fpi_ssm_mark_completed(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +static void capture_read_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + unsigned char *data = transfer->buffer; + int r; + + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + fp_dbg("request is not completed, %d", transfer->status); + fpi_ssm_mark_aborted(ssm, -EIO); + goto out; + } + + fp_dbg("request completed, len: %.4x", transfer->actual_length); + if (transfer->actual_length >= 2) + fp_dbg("data: %.2x %.2x", (int)data[0], (int)data[1]); + + switch (transfer->actual_length) { + case AES2550_STRIP_SIZE: + r = process_strip_data(ssm, data); + if (r < 0) { + fp_dbg("Processing strip data failed: %d", r); + fpi_ssm_mark_aborted(ssm, -EPROTO); + goto out; + } + fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); + break; + case AES2550_HEARTBEAT_SIZE: + if (data[0] == AES2550_HEARTBEAT_MAGIC) { + /* No data for a long time, looks like finger was removed (or no movement) */ + /* assemble image and submit it to library */ + fp_dbg("Got heartbeat => last frame"); + fpi_ssm_next_state(ssm); + } + break; + default: + fp_dbg("Short frame %d, skip", transfer->actual_length); + fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); + break; + } +out: + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +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_REQS: + { + 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, capture_reqs, + sizeof(capture_reqs), capture_reqs_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; + } + + data = g_malloc(AES2550_EP_IN_BUF_SIZE); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + capture_read_data_cb, ssm, BULK_TIMEOUT); + + r = libusb_submit_transfer(transfer); + if (r < 0) { + g_free(data); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, r); + } + } + break; + case CAPTURE_SET_IDLE: + { + 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, capture_set_idle_reqs, + sizeof(capture_set_idle_reqs), capture_set_idle_reqs_cb, ssm, BULK_TIMEOUT); + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, -ENOMEM); + } + } + break; + }; +} + +static void capture_sm_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct aes2550_dev *aesdev = dev->priv; + + fp_dbg("Capture completed"); + if (aesdev->deactivating) + complete_deactivation(dev); + else if (ssm->error) + fpi_imgdev_session_error(dev, ssm->error); + else + start_finger_detection(dev); + fpi_ssm_free(ssm); +} + +static void start_capture(struct fp_img_dev *dev) +{ + struct aes2550_dev *aesdev = dev->priv; + struct fpi_ssm *ssm; + + if (aesdev->deactivating) { + complete_deactivation(dev); + return; + } + + ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + fp_dbg(""); + ssm->priv = dev; + fpi_ssm_start(ssm, capture_sm_complete); +} + +/****** INITIALIZATION/DEINITIALIZATION ******/ + +static unsigned char init_reqs[] = { + 0x80, AES2550_REG80_MASTER_RESET, /* Master reset */ + 0x80, (1 << AES2550_REG80_SENSOR_MODE_OFS) | (AES2550_REG80_FORCE_FINGER_PRESENT), + 0x85, AES2550_REG85_FLUSH_PER_FRAME, + 0xa8, AES2550_REGA8_DIG_BIT_EN, + 0x81, AES2550_REG81_NSHOT, +}; + +static unsigned char calibrate_reqs[] = { + 0x80, AES2550_REG80_MASTER_RESET, /* Master reset */ + AES2550_CMD_CALIBRATE, + AES2550_CMD_READ_CALIBRATION_DATA, +}; + +enum activate_states { + WRITE_INIT, + READ_DATA, + CALIBRATE, + READ_CALIB_TABLE, + ACTIVATE_NUM_STATES, +}; + +static void init_reqs_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +static void init_read_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +/* TODO: use calibration table, datasheet is rather terse on that + * need more info for implementaion */ +static void calibrate_read_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +static void activate_run_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->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, init_reqs, + sizeof(init_reqs), init_reqs_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; + } + + data = g_malloc(AES2550_EP_IN_BUF_SIZE); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + init_read_data_cb, ssm, BULK_TIMEOUT); + + r = libusb_submit_transfer(transfer); + if (r < 0) { + g_free(data); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, r); + } + } + break; + case CALIBRATE: + { + 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, calibrate_reqs, + sizeof(calibrate_reqs), init_reqs_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_CALIB_TABLE: + { + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + unsigned char *data; + + if (!transfer) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + break; + } + + data = g_malloc(AES2550_EP_IN_BUF_SIZE); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + calibrate_read_data_cb, ssm, BULK_TIMEOUT); + + r = libusb_submit_transfer(transfer); + if (r < 0) { + g_free(data); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, r); + } + } + break; + } +} + +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 (!ssm->error) + start_finger_detection(dev); + fpi_ssm_free(ssm); +} + +static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +{ + struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + ACTIVATE_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, activate_sm_complete); + return 0; +} + +static void dev_deactivate(struct fp_img_dev *dev) +{ + struct aes2550_dev *aesdev = dev->priv; + + aesdev->deactivating = TRUE; +} + +static void complete_deactivation(struct fp_img_dev *dev) +{ + struct aes2550_dev *aesdev = dev->priv; + fp_dbg(""); + + aesdev->deactivating = FALSE; + g_slist_free(aesdev->strips); + aesdev->strips = NULL; + aesdev->strips_len = 0; + fpi_imgdev_deactivate_complete(dev); +} + +static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) +{ + /* TODO check that device has endpoints we're using */ + int r; + + r = libusb_claim_interface(dev->udev, 0); + if (r < 0) { + fp_err("could not claim interface 0"); + return r; + } + + dev->priv = g_malloc0(sizeof(struct aes2550_dev)); + fpi_imgdev_open_complete(dev, 0); + return 0; +} + +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[] = { + { .vendor = 0x08ff, .product = 0x2550 }, /* AES2550 */ + { .vendor = 0x08ff, .product = 0x2810 }, /* AES2810 */ + { 0, 0, 0, }, +}; + +struct fp_img_driver aes2550_driver = { + .driver = { + .id = 4, + .name = FP_COMPONENT, + .full_name = "AuthenTec AES2550/AES2810", + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + .flags = 0, + .img_height = -1, + .img_width = 192, + + .open = dev_init, + .close = dev_deinit, + .activate = dev_activate, + .deactivate = dev_deactivate, +}; diff --git a/libfprint/drivers/aes2550.h b/libfprint/drivers/aes2550.h new file mode 100644 index 00000000..cd1e22d3 --- /dev/null +++ b/libfprint/drivers/aes2550.h @@ -0,0 +1,114 @@ +/* + * AuthenTec AES2550/AES2810 driver for libfprint + * Copyright (C) 2012 Vasily Khoruzhick + * + * 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 __AES2550_H +#define __AES2550_H + +/* Registers bits */ + +#define AES2550_REG80_MASTER_RESET (1 << 0) +#define AES2550_REG80_FORCE_FINGER_PRESENT (1 << 1) +#define AES2550_REG80_LPO_START (1 << 2) +#define AES2550_REG80_HGC_ENABLE (1 << 3) +#define AES2550_REG80_SENSOR_MODE_OFS (4) +#define AES2550_REG80_AUTO_RESTART_FD (1 << 6) +#define AES2550_REG80_EXT_REG_ENABLE (1 << 7) + +#define AES2550_REG81_CONT_SCAN (1 << 0) +#define AES2550_REG81_READ_REG (1 << 1) +#define AES2550_REG81_NSHOT (1 << 2) +#define AES2550_REG81_RUN_FD (1 << 3) +#define AES2550_REG81_READ_ID (1 << 4) +#define AES2550_REG81_RUN_CAL (1 << 5) +#define AES2550_REG81_RUN_TIMER (1 << 6) +#define AES2550_REG81_RUN_BIST (1 << 7) + +#define AES2550_REG83_FINGER_PRESENT (1 << 7) + +#define AES2550_REG85_FLUSH_PER_FRAME (1 << 7) + +#define AES2550_REG8F_EDATA_DISABLE (1 << 1) +#define AES2550_REG8F_AUTH_DISABLE (1 << 2) +#define AES2550_REG8F_EHISTO_DISABLE (1 << 3) +#define AES2550_REG8F_HISTO64 (1 << 4) +#define AES2550_REG8F_SINGLE_REG_ENABLE (1 << 6) + +#define AES2550_REG95_COL_SCANNED_OFS (0) +#define AES2550_REG95_EPIX_AVG_OFS (4) + +#define AES2550_REGA8_DIG_BIT_DATA_OFS (0) +#define AES2550_REGA8_DIG_BIT_EN (1 << 4) +#define AES2550_REGA8_FIXED_BIT_DATA (1 << 5) +#define AES2550_REGA8_INVERT_BIT_DATA (1 << 6) + +#define AES2550_REGAD_LPFD_AVG_OFS (0) +#define AES2550_REGAD_DETECT_FGROFF (1 << 4) +#define AES2550_REGAD_ADVRANGE_2V (1 << 6) + +#define AES2550_REGB1_ATE_CONT_IMAGE (1 << 1) +#define AES2550_REGB1_ANALOG_RESET (1 << 2) +#define AES2550_REGB1_ANALOG_PD (1 << 3) +#define AES2550_REGB1_TEST_EMBD_WORD (1 << 4) +#define AES2550_REGB1_ORIG_EMBD_WORD (1 << 5) +#define AES2550_REGB1_RESET_UHSM (1 << 6) +#define AES2550_REGB1_RESET_SENSOR (1 << 7) + +#define AES2550_REGBD_LPO_IN_15_8_OFS (0) +#define AES2550_REGBE_LPO_IN_7_0_OFS (0) + +#define AES2550_REGBF_RSR_LEVEL_DISABLED (0 << 0) +#define AES2550_REGBF_RSR_LEVEL_LEADING_RSR (1 << 0) +#define AES2550_REGBF_RSR_LEVEL_SIMPLE_RSR (2 << 0) +#define AES2550_REGBF_RSR_LEVEL_SUPER_RSR (3 << 0) +#define AES2550_REGBF_RSR_DIR_DOWN_MOTION (0 << 2) +#define AES2550_REGBF_RSR_DIR_UP_MOTION (1 << 2) +#define AES2550_REGBF_RSR_DIR_UPDOWN_MOTION (2 << 2) +#define AES2550_REGBF_NOISE_FLOOR_MODE (1 << 4) +#define AES2550_REGBF_QUADRATURE_MODE (1 << 5) + +#define AES2550_REGCF_INTERFERENCE_CHK_EN (1 << 0) +#define AES2550_REGCF_INTERFERENCE_AVG_EN (1 << 1) +#define AES2550_REGCF_INTERFERENCE_AVG_OFFS (4) + +#define AES2550_REGDC_BP_NUM_REF_SWEEP_OFS (0) +#define AES2550_REGDC_DEBUG_CTRL2_OFS (3) + +#define AES2550_REGDD_DEBUG_CTRL1_OFS (0) + +/* Commands */ + +enum aes2550_cmds { + AES2550_CMD_SET_IDLE_MODE = 0x00, + AES2550_CMD_RUN_FD = 0x01, + AES2550_CMD_GET_ENROLL_IMG = 0x02, + AES2550_CMD_CALIBRATE = 0x06, + AES2550_CMD_READ_CALIBRATION_DATA = 0x10, + AES2550_CMD_HEARTBEAT = 0x70, +}; + +/* Messages */ + +#define AES2550_STRIP_SIZE (0x31e + 3) +#define AES2550_HEARTBEAT_SIZE (4 + 3) +#define AES2550_EDATA_MAGIC 0xe0 +#define AES2550_HEARTBEAT_MAGIC 0xdb + +#define AES2550_EP_IN_BUF_SIZE 8192 + +#endif diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 44881cd1..fdb4002b 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -256,6 +256,9 @@ extern struct fp_img_driver aes1610_driver; #ifdef ENABLE_AES2501 extern struct fp_img_driver aes2501_driver; #endif +#ifdef ENABLE_AES2550 +extern struct fp_img_driver aes2550_driver; +#endif #ifdef ENABLE_AES4000 extern struct fp_img_driver aes4000_driver; #endif From 0f7ad00fc49023ff7f637eb740e7120d0e16b47e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 15 Oct 2012 11:46:03 +0200 Subject: [PATCH 13/49] HACKING: Update with bugzilla link --- HACKING | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HACKING b/HACKING index 00ff2062..43bf4e79 100644 --- a/HACKING +++ b/HACKING @@ -85,11 +85,11 @@ be reflected by updating the appropriate doxygen comments. Contributing ============ -Patches should be sent to the fprint mailing list detailed on the website. -A subscription is required. +Patches should be sent to the fprint bugzilla: +https://bugs.freedesktop.org/enter_bug.cgi?product=libfprint Information about libfprint development repositories can be found here: -http://www.reactivated.net/fprint/Libfprint_development +http://www.freedesktop.org/wiki/Software/fprint/libfprint If you're looking for ideas for things to work on, look at the TODO file or grep the source code for FIXMEs. From d003f08855ba34be88775e4281e7f686b00f6d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 26 Sep 2012 13:41:13 +0300 Subject: [PATCH 14/49] lib: Add support for DigitalPersona URU4500 By adding native encryption support, rather than poking at the firmware to disable it. This also makes the URU4000B use native encryption. https://bugs.freedesktop.org/show_bug.cgi?id=55351 --- libfprint/drivers/uru4000.c | 581 ++++++++++++++++++++---------------- libfprint/fp_internal.h | 2 + 2 files changed, 334 insertions(+), 249 deletions(-) diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 0dbea965..f42b6095 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -1,6 +1,7 @@ /* - * Digital Persona U.are.U 4000/4000B driver for libfprint + * Digital Persona U.are.U 4000/4000B/4500 driver for libfprint * Copyright (C) 2007-2008 Daniel Drake + * Copyright (C) 2012 Timo Teräs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,14 +35,14 @@ #define USB_RQ 0x04 #define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN) #define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT) -#define CTRL_TIMEOUT 5000 -#define BULK_TIMEOUT 5000 -#define DATABLK_RQLEN 0x1b340 -#define DATABLK_EXPECT 0x1b1c0 -#define CAPTURE_HDRLEN 64 +#define CTRL_TIMEOUT 5000 +#define BULK_TIMEOUT 5000 #define IRQ_LENGTH 64 #define CR_LENGTH 16 +#define IMAGE_HEIGHT 290 +#define IMAGE_WIDTH 384 + enum { IRQDATA_SCANPWR_ON = 0x56aa, IRQDATA_FINGER_ON = 0x0101, @@ -51,7 +52,10 @@ enum { enum { REG_HWSTAT = 0x07, + REG_SCRAMBLE_DATA_INDEX = 0x33, + REG_SCRAMBLE_DATA_KEY = 0x34, REG_MODE = 0x4e, + REG_DEVICE_INFO = 0xf0, /* firmware starts at 0x100 */ REG_RESPONSE = 0x2000, REG_CHALLENGE = 0x2010, @@ -62,7 +66,8 @@ enum { MODE_AWAIT_FINGER_ON = 0x10, MODE_AWAIT_FINGER_OFF = 0x12, MODE_CAPTURE = 0x20, - MODE_SHUT_UP = 0x30, + MODE_CAPTURE_AUX = 0x30, + MODE_OFF = 0x70, MODE_READY = 0x80, }; @@ -78,6 +83,7 @@ enum { static const struct uru4k_dev_profile { const char *name; gboolean auth_cr; + gboolean encryption; } uru4k_dev_info[] = { [MS_KBD] = { .name = "Microsoft Keyboard with Fingerprint Reader", @@ -102,21 +108,10 @@ static const struct uru4k_dev_profile { [DP_URU4000B] = { .name = "Digital Persona U.are.U 4000B", .auth_cr = FALSE, + .encryption = TRUE, }, }; -/* As we don't know the encryption scheme, we have to disable encryption - * by powering the device down and modifying the firmware. The location of - * the encryption control byte changes based on device revision. - * - * We use a search approach to find it: we look at the 3 bytes of data starting - * from these addresses, looking for a pattern "ff X7 41" (where X is dontcare) - * When we find a pattern we know that the encryption byte ius the X7 byte. - */ -static const uint16_t fwenc_offsets[] = { - 0x510, 0x62d, 0x792, 0x7f4, -}; - typedef void (*irq_cb_fn)(struct fp_img_dev *dev, int status, uint16_t type, void *user_data); typedef void (*irqs_stopped_cb_fn)(struct fp_img_dev *dev); @@ -125,11 +120,14 @@ struct uru4k_dev { const struct uru4k_dev_profile *profile; uint8_t interface; enum fp_imgdev_state activate_state; - unsigned char last_reg_rd; + unsigned char last_reg_rd[16]; unsigned char last_hwstat; struct libusb_transfer *irq_transfer; struct libusb_transfer *img_transfer; + void *img_data; + uint16_t img_lines_done, img_block; + uint32_t img_enc_seed; irq_cb_fn irq_cb; void *irq_cb_data; @@ -225,7 +223,7 @@ static int write_reg(struct fp_img_dev *dev, uint16_t reg, } typedef void (*read_regs_cb_fn)(struct fp_img_dev *dev, int status, - unsigned char *data, void *user_data); + uint16_t num_regs, unsigned char *data, void *user_data); struct read_regs_data { struct fp_img_dev *dev; @@ -248,7 +246,7 @@ static void read_regs_cb(struct libusb_transfer *transfer) else data = libusb_control_transfer_get_data(transfer); - rrdata->callback(rrdata->dev, r, data, rrdata->user_data); + rrdata->callback(rrdata->dev, r, transfer->actual_length, data, rrdata->user_data); g_free(rrdata); g_free(transfer->buffer); libusb_free_transfer(transfer); @@ -284,12 +282,6 @@ static int read_regs(struct fp_img_dev *dev, uint16_t first_reg, return r; } -static int read_reg(struct fp_img_dev *dev, uint16_t reg, - read_regs_cb_fn callback, void *user_data) -{ - return read_regs(dev, reg, 1, callback, user_data); -} - /* * HWSTAT * @@ -325,7 +317,7 @@ static void response_cb(struct fp_img_dev *dev, int status, void *user_data) } static void challenge_cb(struct fp_img_dev *dev, int status, - unsigned char *data, void *user_data) + uint16_t num_regs, unsigned char *data, void *user_data) { struct fpi_ssm *ssm = user_data; struct uru4k_dev *urudev = dev->priv; @@ -469,95 +461,10 @@ static void stop_irq_handler(struct fp_img_dev *dev, irqs_stopped_cb_fn cb) } } -/***** IMAGING LOOP *****/ - -static int start_imaging_loop(struct fp_img_dev *dev); - -static void image_cb(struct libusb_transfer *transfer) -{ - struct fp_img_dev *dev = transfer->user_data; - struct uru4k_dev *urudev = dev->priv; - int hdr_skip = CAPTURE_HDRLEN; - int image_size = DATABLK_EXPECT - CAPTURE_HDRLEN; - struct fp_img *img; - int r = 0; - - /* remove the global reference early: otherwise we may report results, - * leading to immediate deactivation of driver, which will potentially - * try to cancel an already-completed transfer */ - urudev->img_transfer = NULL; - - if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { - fp_dbg("cancelled"); - g_free(transfer->buffer); - libusb_free_transfer(transfer); - return; - } else if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - r = -EIO; - goto out; - } - - if (transfer->actual_length == image_size) { - /* no header! this is rather odd, but it happens sometimes with my MS - * keyboard */ - fp_dbg("got image with no header!"); - hdr_skip = 0; - } else if (transfer->actual_length != DATABLK_EXPECT) { - fp_err("unexpected image capture size (%d)", transfer->actual_length); - r = -EPROTO; - goto out; - } - - img = fpi_img_new(image_size); - memcpy(img->data, transfer->buffer + hdr_skip, image_size); - img->flags = FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED | FP_IMG_COLORS_INVERTED; - fpi_imgdev_image_captured(dev, img); - -out: - g_free(transfer->buffer); - libusb_free_transfer(transfer); - if (r == 0) - r = start_imaging_loop(dev); - - if (r) - fpi_imgdev_session_error(dev, r); -} - -static int start_imaging_loop(struct fp_img_dev *dev) -{ - struct uru4k_dev *urudev = dev->priv; - struct libusb_transfer *transfer = libusb_alloc_transfer(0); - unsigned char *data; - int r; - - if (!transfer) - return -ENOMEM; - - data = g_malloc(DATABLK_RQLEN); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_DATA, data, - DATABLK_RQLEN, image_cb, dev, 0); - - urudev->img_transfer = transfer; - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(data); - libusb_free_transfer(transfer); - } - - return r; -} - -static void stop_imaging_loop(struct fp_img_dev *dev) -{ - struct uru4k_dev *urudev = dev->priv; - struct libusb_transfer *transfer = urudev->img_transfer; - if (transfer) - libusb_cancel_transfer(transfer); - /* FIXME: should probably wait for cancellation to complete */ -} - /***** STATE CHANGING *****/ +static int execute_state_change(struct fp_img_dev *dev); + static void finger_presence_irq_cb(struct fp_img_dev *dev, int status, uint16_t type, void *user_data) { @@ -582,33 +489,22 @@ static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state) { struct uru4k_dev *urudev = dev->priv; - stop_imaging_loop(dev); - switch (state) { + case IMGDEV_STATE_INACTIVE: case IMGDEV_STATE_AWAIT_FINGER_ON: - if (!IRQ_HANDLER_IS_RUNNING(urudev)) - return -EIO; - urudev->irq_cb = finger_presence_irq_cb; - return write_reg(dev, REG_MODE, MODE_AWAIT_FINGER_ON, - change_state_write_reg_cb, NULL); - - case IMGDEV_STATE_CAPTURE: - urudev->irq_cb = NULL; - start_imaging_loop(dev); - return write_reg(dev, REG_MODE, MODE_CAPTURE, change_state_write_reg_cb, - NULL); - case IMGDEV_STATE_AWAIT_FINGER_OFF: - if (!IRQ_HANDLER_IS_RUNNING(urudev)) - return -EIO; - urudev->irq_cb = finger_presence_irq_cb; - return write_reg(dev, REG_MODE, MODE_AWAIT_FINGER_OFF, - change_state_write_reg_cb, NULL); - + case IMGDEV_STATE_CAPTURE: + break; default: fp_err("unrecognised state %d", state); return -EINVAL; } + + urudev->activate_state = state; + if (urudev->img_transfer != NULL) + return 0; + + return execute_state_change(dev); } /***** GENERIC STATE MACHINE HELPER FUNCTIONS *****/ @@ -623,17 +519,23 @@ static void sm_write_reg_cb(struct fp_img_dev *dev, int result, void *user_data) fpi_ssm_next_state(ssm); } -static void sm_write_reg(struct fpi_ssm *ssm, uint16_t reg, - unsigned char value) +static void sm_write_regs(struct fpi_ssm *ssm, uint16_t first_reg, uint16_t num_regs, + void *data) { struct fp_img_dev *dev = ssm->priv; - int r = write_reg(dev, reg, value, sm_write_reg_cb, ssm); + int r = write_regs(dev, first_reg, num_regs, data, sm_write_reg_cb, ssm); if (r < 0) fpi_ssm_mark_aborted(ssm, r); } +static void sm_write_reg(struct fpi_ssm *ssm, uint16_t reg, + unsigned char value) +{ + sm_write_regs(ssm, reg, 1, &value); +} + static void sm_read_reg_cb(struct fp_img_dev *dev, int result, - unsigned char *data, void *user_data) + uint16_t num_regs, unsigned char *data, void *user_data) { struct fpi_ssm *ssm = user_data; struct uru4k_dev *urudev = dev->priv; @@ -641,27 +543,32 @@ static void sm_read_reg_cb(struct fp_img_dev *dev, int result, if (result) { fpi_ssm_mark_aborted(ssm, result); } else { - urudev->last_reg_rd = *data; - fp_dbg("reg value %x", urudev->last_reg_rd); + memcpy(urudev->last_reg_rd, data, num_regs); + fp_dbg("reg value %x", urudev->last_reg_rd[0]); fpi_ssm_next_state(ssm); } } -static void sm_read_reg(struct fpi_ssm *ssm, uint16_t reg) +static void sm_read_regs(struct fpi_ssm *ssm, uint16_t reg, uint16_t num_regs) { struct fp_img_dev *dev = ssm->priv; + struct uru4k_dev *urudev = dev->priv; int r; - - fp_dbg("read reg %x", reg); - r = read_reg(dev, reg, sm_read_reg_cb, ssm); + + if (num_regs > sizeof(urudev->last_reg_rd)) { + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + fp_dbg("read %d regs at %x", num_regs, reg); + r = read_regs(dev, reg, num_regs, sm_read_reg_cb, ssm); if (r < 0) fpi_ssm_mark_aborted(ssm, r); } -static void sm_set_mode(struct fpi_ssm *ssm, unsigned char mode) +static void sm_read_reg(struct fpi_ssm *ssm, uint16_t reg) { - fp_dbg("mode %02x", mode); - sm_write_reg(ssm, REG_MODE, mode); + sm_read_regs(ssm, reg, 1); } static void sm_set_hwstat(struct fpi_ssm *ssm, unsigned char value) @@ -670,77 +577,232 @@ static void sm_set_hwstat(struct fpi_ssm *ssm, unsigned char value) sm_write_reg(ssm, REG_HWSTAT, value); } -/***** INITIALIZATION *****/ +/***** IMAGING LOOP *****/ -enum fwfixer_states { - FWFIXER_INIT, - FWFIXER_READ_NEXT, - FWFIXER_WRITE, - FWFIXER_NUM_STATES, +enum imaging_states { + IMAGING_CAPTURE, + IMAGING_SEND_INDEX, + IMAGING_READ_KEY, + IMAGING_DECODE, + IMAGING_REPORT_IMAGE, + IMAGING_NUM_STATES }; -static void fwfixer_read_cb(struct fp_img_dev *dev, int status, - unsigned char *data, void *user_data) +static void image_transfer_cb(struct libusb_transfer *transfer) { - struct fpi_ssm *ssm = user_data; - struct uru4k_dev *urudev = dev->priv; + struct fpi_ssm *ssm = transfer->user_data; - if (status != 0) - fpi_ssm_mark_aborted(ssm, status); - - fp_dbg("data: %02x %02x %02x", data[0], data[1], data[2]); - if (data[0] == 0xff && (data[1] & 0x0f) == 0x07 && data[2] == 0x41) { - fp_dbg("using offset %x", fwenc_offsets[urudev->fwfixer_offset]); - urudev->fwfixer_value = data[1]; - fpi_ssm_jump_to_state(ssm, FWFIXER_WRITE); + if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { + fp_dbg("cancelled"); + fpi_ssm_mark_aborted(ssm, -ECANCELED); + } else if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + fp_dbg("error"); + fpi_ssm_mark_aborted(ssm, -EIO); } else { - fpi_ssm_jump_to_state(ssm, FWFIXER_READ_NEXT); + fpi_ssm_next_state(ssm); } } -static void fwfixer_run_state(struct fpi_ssm *ssm) +enum { + BLOCKF_CHANGE_KEY = 0x80, + BLOCKF_NO_KEY_UPDATE = 0x04, + BLOCKF_ENCRYPTED = 0x02, + BLOCKF_NOT_PRESENT = 0x01, +}; + +struct uru4k_image { + uint8_t unknown_00[4]; + uint16_t num_lines; + uint8_t key_number; + uint8_t unknown_07[9]; + struct { + uint8_t flags; + uint8_t num_lines; + } block_info[15]; + uint8_t unknown_2E[18]; + uint8_t data[IMAGE_HEIGHT][IMAGE_WIDTH]; +}; + +static uint32_t update_key(uint32_t key) +{ + /* linear feedback shift register + * taps at bit positions 1 3 4 7 11 13 20 23 26 29 32 */ + uint32_t bit = key & 0x9248144d; + bit ^= bit << 16; + bit ^= bit << 8; + bit ^= bit << 4; + bit ^= bit << 2; + bit ^= bit << 1; + return (bit & 0x80000000) | (key >> 1); +} + +static uint32_t do_decode(uint8_t *data, int num_bytes, uint32_t key) +{ + uint8_t xorbyte; + int i; + + for (i = 0; i < num_bytes - 1; i++) { + /* calculate xor byte and update key */ + xorbyte = ((key >> 4) & 1) << 0; + xorbyte |= ((key >> 8) & 1) << 1; + xorbyte |= ((key >> 11) & 1) << 2; + xorbyte |= ((key >> 14) & 1) << 3; + xorbyte |= ((key >> 18) & 1) << 4; + xorbyte |= ((key >> 21) & 1) << 5; + xorbyte |= ((key >> 24) & 1) << 6; + xorbyte |= ((key >> 29) & 1) << 7; + key = update_key(key); + + /* decrypt data */ + data[i] = data[i+1] ^ xorbyte; + } + + /* the final byte is implictly zero */ + data[i] = 0; + return update_key(key); +} + +static void imaging_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; struct uru4k_dev *urudev = dev->priv; - int r; + struct uru4k_image *img = urudev->img_data; + struct fp_img *fpimg; + uint32_t key; + uint8_t flags, num_lines; + int i, r, to; + char buf[5]; switch (ssm->cur_state) { - case FWFIXER_INIT: - urudev->fwfixer_offset = -1; - fpi_ssm_next_state(ssm); + case IMAGING_CAPTURE: + urudev->img_lines_done = 0; + urudev->img_block = 0; + libusb_fill_bulk_transfer(urudev->img_transfer, dev->udev, EP_DATA, + urudev->img_data, sizeof(struct uru4k_image), image_transfer_cb, ssm, 0); + r = libusb_submit_transfer(urudev->img_transfer); + if (r < 0) + fpi_ssm_mark_aborted(ssm, -EIO); break; - case FWFIXER_READ_NEXT: ; - int offset = ++urudev->fwfixer_offset; - uint16_t try_addr; + case IMAGING_SEND_INDEX: + fp_dbg("hw header lines %d", img->num_lines); - if (offset == G_N_ELEMENTS(fwenc_offsets)) { - fp_err("could not find encryption byte"); - fpi_ssm_mark_aborted(ssm, -ENODEV); + if (img->num_lines >= IMAGE_HEIGHT || + urudev->img_transfer->actual_length != img->num_lines * IMAGE_WIDTH + 64) { + fp_err("bad captured image (%d lines) or size mismatch %d != %d", + img->num_lines, + urudev->img_transfer->actual_length, + img->num_lines * IMAGE_WIDTH + 64); + fpi_ssm_jump_to_state(ssm, IMAGING_CAPTURE); return; } - - try_addr = fwenc_offsets[offset]; - fp_dbg("looking for encryption byte at %x", try_addr); - - r = read_regs(dev, try_addr, 3, fwfixer_read_cb, ssm); - if (r < 0) - fpi_ssm_mark_aborted(ssm, r); - break; - case FWFIXER_WRITE: ; - uint16_t enc_addr = fwenc_offsets[urudev->fwfixer_offset] + 1; - unsigned char cur = urudev->fwfixer_value; - unsigned char new = cur & 0xef; - if (new == cur) { - fp_dbg("encryption is already disabled"); - fpi_ssm_next_state(ssm); - } else { - fp_dbg("fixing encryption byte at %x to %02x", enc_addr, new); - sm_write_reg(ssm, enc_addr, new); + if (!urudev->profile->encryption) { + fpi_ssm_jump_to_state(ssm, IMAGING_REPORT_IMAGE); + return; } + buf[0] = img->key_number; + buf[1] = urudev->img_enc_seed; + buf[2] = urudev->img_enc_seed >> 8; + buf[3] = urudev->img_enc_seed >> 16; + buf[4] = urudev->img_enc_seed >> 24; + sm_write_regs(ssm, REG_SCRAMBLE_DATA_INDEX, 5, buf); + break; + case IMAGING_READ_KEY: + sm_read_regs(ssm, REG_SCRAMBLE_DATA_KEY, 4); + break; + case IMAGING_DECODE: + key = urudev->last_reg_rd[0]; + key |= urudev->last_reg_rd[1] << 8; + key |= urudev->last_reg_rd[2] << 16; + key |= urudev->last_reg_rd[3] << 24; + key ^= urudev->img_enc_seed; + + fp_dbg("encryption id %02x -> key %08x", img->key_number, key); + while (urudev->img_block < array_n_elements(img->block_info) && + urudev->img_lines_done < img->num_lines) { + flags = img->block_info[urudev->img_block].flags; + num_lines = img->block_info[urudev->img_block].num_lines; + if (num_lines == 0) + break; + + fp_dbg("%d %02x %d", urudev->img_block, flags, num_lines); + if (flags & BLOCKF_CHANGE_KEY) { + fp_dbg("changing encryption keys.\n"); + img->block_info[urudev->img_block].flags &= ~BLOCKF_CHANGE_KEY; + img->key_number++; + urudev->img_enc_seed = rand(); + fpi_ssm_jump_to_state(ssm, IMAGING_SEND_INDEX); + return; + } + switch (flags & (BLOCKF_NO_KEY_UPDATE | BLOCKF_ENCRYPTED)) { + case BLOCKF_ENCRYPTED: + fp_dbg("decoding %d lines", num_lines); + key = do_decode(&img->data[urudev->img_lines_done][0], + IMAGE_WIDTH*num_lines, key); + break; + case 0: + fp_dbg("skipping %d lines", num_lines); + for (r = 0; r < IMAGE_WIDTH*num_lines; r++) + key = update_key(key); + break; + } + if ((flags & BLOCKF_NOT_PRESENT) == 0) + urudev->img_lines_done += num_lines; + urudev->img_block++; + } + fpi_ssm_next_state(ssm); + break; + case IMAGING_REPORT_IMAGE: + fpimg = fpi_img_new_for_imgdev(dev); + + to = r = 0; + for (i = 0; i < array_n_elements(img->block_info) && r < img->num_lines; i++) { + flags = img->block_info[i].flags; + num_lines = img->block_info[i].num_lines; + if (num_lines == 0) + break; + memcpy(&fpimg->data[to], &img->data[r][0], + num_lines * IMAGE_WIDTH); + if (!(flags & BLOCKF_NOT_PRESENT)) + r += num_lines; + to += num_lines * IMAGE_WIDTH; + } + + fpimg->flags = FP_IMG_COLORS_INVERTED; + if (!urudev->profile->encryption) + fpimg->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; + fpi_imgdev_image_captured(dev, fpimg); + + if (urudev->activate_state == IMGDEV_STATE_CAPTURE) + fpi_ssm_jump_to_state(ssm, IMAGING_CAPTURE); + else + fpi_ssm_mark_completed(ssm); break; } } +static void imaging_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct uru4k_dev *urudev = dev->priv; + int r = ssm->error; + fpi_ssm_free(ssm); + + g_free(urudev->img_data); + urudev->img_data = NULL; + + libusb_free_transfer(urudev->img_transfer); + urudev->img_transfer = NULL; + + if (r) + fpi_imgdev_session_error(dev, r); + + r = execute_state_change(dev); + if (r) + fpi_imgdev_session_error(dev, r); +} + +/***** INITIALIZATION *****/ + /* After closing an app and setting hwstat to 0x80, my ms keyboard gets in a * confused state and returns hwstat 0x85. On next app run, we don't get the * 56aa interrupt. This is the best way I've found to fix it: mess around @@ -793,7 +855,7 @@ static void rebootpwr_run_state(struct fpi_ssm *ssm) sm_read_reg(ssm, REG_HWSTAT); break; case REBOOTPWR_CHECK_HWSTAT: - urudev->last_hwstat = urudev->last_reg_rd; + urudev->last_hwstat = urudev->last_reg_rd[0]; if (urudev->last_hwstat & 0x1) fpi_ssm_mark_completed(ssm); else @@ -876,8 +938,8 @@ static void powerup_run_state(struct fpi_ssm *ssm) sm_read_reg(ssm, REG_HWSTAT); break; case POWERUP_CHECK_HWSTAT: - urudev->last_hwstat = urudev->last_reg_rd; - if ((urudev->last_reg_rd & 0x80) == 0) + urudev->last_hwstat = urudev->last_reg_rd[0]; + if ((urudev->last_reg_rd[0] & 0x80) == 0) fpi_ssm_mark_completed(ssm); else fpi_ssm_next_state(ssm); @@ -890,7 +952,7 @@ static void powerup_run_state(struct fpi_ssm *ssm) sm_do_challenge_response(ssm); break; case POWERUP_CHALLENGE_RESPONSE_SUCCESS: - fpi_ssm_jump_to_state(ssm, POWERUP_SET_HWSTAT); + fpi_ssm_jump_to_state(ssm, POWERUP_SET_HWSTAT); break; } } @@ -908,12 +970,6 @@ static void powerup_run_state(struct fpi_ssm *ssm) if ((status & 0x80) == 0) set_hwstat(status | 0x80); - // disable encryption - fwenc = read_firmware_encryption_byte(); - new = fwenc & 0xef; - if (new != fwenc) - write_firmware_encryption_byte(new); - // power device up run_powerup_sm(); await_irq(IRQDATA_SCANPWR_ON); @@ -924,10 +980,11 @@ enum init_states { INIT_CHECK_HWSTAT_REBOOT, INIT_REBOOT_POWER, INIT_CHECK_HWSTAT_POWERDOWN, - INIT_FIX_FIRMWARE, INIT_POWERUP, INIT_AWAIT_SCAN_POWER, INIT_DONE, + INIT_GET_VERSION, + INIT_REPORT_VERSION, INIT_NUM_STATES, }; @@ -975,7 +1032,7 @@ static void init_run_state(struct fpi_ssm *ssm) sm_read_reg(ssm, REG_HWSTAT); break; case INIT_CHECK_HWSTAT_REBOOT: - urudev->last_hwstat = urudev->last_reg_rd; + urudev->last_hwstat = urudev->last_reg_rd[0]; if ((urudev->last_hwstat & 0x84) == 0x84) fpi_ssm_next_state(ssm); else @@ -993,12 +1050,6 @@ static void init_run_state(struct fpi_ssm *ssm) else fpi_ssm_next_state(ssm); break; - case INIT_FIX_FIRMWARE: ; - struct fpi_ssm *fwsm = fpi_ssm_new(dev->dev, fwfixer_run_state, - FWFIXER_NUM_STATES); - fwsm->priv = dev; - fpi_ssm_start_subsm(ssm, fwsm); - break; case INIT_POWERUP: ; struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state, POWERUP_NUM_STATES); @@ -1029,6 +1080,17 @@ static void init_run_state(struct fpi_ssm *ssm) urudev->scanpwr_irq_timeout = NULL; urudev->irq_cb_data = NULL; urudev->irq_cb = NULL; + fpi_ssm_next_state(ssm); + break; + case INIT_GET_VERSION: + sm_read_regs(ssm, REG_DEVICE_INFO, 16); + break; + case INIT_REPORT_VERSION: + /* Likely hardware revision, and firmware version. + * Not sure which is which. */ + fp_info("Versions %02x%02x and %02x%02x", + urudev->last_reg_rd[10], urudev->last_reg_rd[11], + urudev->last_reg_rd[4], urudev->last_reg_rd[5]); fpi_ssm_mark_completed(ssm); break; } @@ -1037,7 +1099,6 @@ static void init_run_state(struct fpi_ssm *ssm) static void activate_initsm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; - struct uru4k_dev *urudev = dev->priv; int r = ssm->error; fpi_ssm_free(ssm); @@ -1046,7 +1107,7 @@ static void activate_initsm_complete(struct fpi_ssm *ssm) return; } - r = dev_change_state(dev, urudev->activate_state); + r = execute_state_change(dev); fpi_imgdev_activate_complete(dev, r); } @@ -1074,47 +1135,69 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) /***** DEINITIALIZATION *****/ -enum deinit_states { - DEINIT_SET_MODE_INIT = 0, - DEINIT_POWERDOWN, - DEINIT_NUM_STATES, -}; - -static void deinit_run_state(struct fpi_ssm *ssm) -{ - switch (ssm->cur_state) { - case DEINIT_SET_MODE_INIT: - sm_set_mode(ssm, MODE_INIT); - break; - case DEINIT_POWERDOWN: - sm_set_hwstat(ssm, 0x80); - break; - } -} - static void deactivate_irqs_stopped(struct fp_img_dev *dev) { fpi_imgdev_deactivate_complete(dev); } -static void deactivate_deinitsm_complete(struct fpi_ssm *ssm) +static void deactivate_write_reg_cb(struct fp_img_dev *dev, int status, + void *user_data) { - struct fp_img_dev *dev = ssm->priv; - fpi_ssm_free(ssm); stop_irq_handler(dev, deactivate_irqs_stopped); } static void dev_deactivate(struct fp_img_dev *dev) { - struct uru4k_dev *urudev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, deinit_run_state, - DEINIT_NUM_STATES); + dev_change_state(dev, IMGDEV_STATE_INACTIVE); +} - stop_imaging_loop(dev); - urudev->irq_cb = NULL; - urudev->irq_cb_data = NULL; - ssm->priv = dev; - fpi_ssm_start(ssm, deactivate_deinitsm_complete); +static int execute_state_change(struct fp_img_dev *dev) +{ + struct uru4k_dev *urudev = dev->priv; + struct fpi_ssm *ssm; + + switch (urudev->activate_state) { + case IMGDEV_STATE_INACTIVE: + fp_dbg("deactivating"); + urudev->irq_cb = NULL; + urudev->irq_cb_data = NULL; + return write_reg(dev, REG_MODE, MODE_OFF, + deactivate_write_reg_cb, NULL); + break; + + case IMGDEV_STATE_AWAIT_FINGER_ON: + fp_dbg("wait finger on"); + if (!IRQ_HANDLER_IS_RUNNING(urudev)) + return -EIO; + urudev->irq_cb = finger_presence_irq_cb; + return write_reg(dev, REG_MODE, MODE_AWAIT_FINGER_ON, + change_state_write_reg_cb, NULL); + + case IMGDEV_STATE_CAPTURE: + fp_dbg("starting capture"); + urudev->irq_cb = NULL; + + urudev->img_transfer = libusb_alloc_transfer(0); + urudev->img_data = g_malloc(sizeof(struct uru4k_image)); + urudev->img_enc_seed = rand(); + + ssm = fpi_ssm_new(dev->dev, imaging_run_state, IMAGING_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, imaging_complete); + + return write_reg(dev, REG_MODE, MODE_CAPTURE, + change_state_write_reg_cb, NULL); + + case IMGDEV_STATE_AWAIT_FINGER_OFF: + fp_dbg("await finger off"); + if (!IRQ_HANDLER_IS_RUNNING(urudev)) + return -EIO; + urudev->irq_cb = finger_presence_irq_cb; + return write_reg(dev, REG_MODE, MODE_AWAIT_FINGER_OFF, + change_state_write_reg_cb, NULL); + } + + return 0; } /***** LIBRARY STUFF *****/ @@ -1278,13 +1361,13 @@ struct fp_img_driver uru4000_driver = { .driver = { .id = 2, .name = FP_COMPONENT, - .full_name = "Digital Persona U.are.U 4000/4000B", + .full_name = "Digital Persona U.are.U 4000/4000B/4500", .id_table = id_table, .scan_type = FP_SCAN_TYPE_PRESS, }, .flags = FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE, - .img_height = 289, - .img_width = 384, + .img_height = IMAGE_HEIGHT, + .img_width = IMAGE_WIDTH, .open = dev_init, .close = dev_deinit, diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index fdb4002b..7d2cf893 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -28,6 +28,8 @@ #include +#define array_n_elements(array) (sizeof(array) / sizeof(array[0])) + #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) From be29f27e254317b713c7a0f007d6e959ee2a3905 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 20 Oct 2012 12:27:52 +0300 Subject: [PATCH 15/49] upeke2: Fix build-time warnings Fix warnings reported by gcc https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/drivers/upeke2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/drivers/upeke2.c b/libfprint/drivers/upeke2.c index 3a7c2d89..94bc8ae4 100644 --- a/libfprint/drivers/upeke2.c +++ b/libfprint/drivers/upeke2.c @@ -738,14 +738,14 @@ static void initsm_run_state(struct fpi_ssm *ssm) break; case SEND28_51: ; unsigned char dummy28_51[] = { 0x04, 0x0a, 0x00, 0x00, 0x00 }; - initsm_send_msg28_handler(ssm, 0x51, &dummy28_51, 5); + initsm_send_msg28_handler(ssm, 0x51, dummy28_51, 5); break; case READ28_51: initsm_read_msg_handler(ssm, read28_51_cb); break; case SEND28_07: ; unsigned char dummy28_07[] = { 0x04, 0x20, 0x00, 0x00, 0x00 }; - initsm_send_msg28_handler(ssm, 0x07, &dummy28_07, 5); + initsm_send_msg28_handler(ssm, 0x07, dummy28_07, 5); break; case READ28_07: initsm_read_msg_handler(ssm, read28_07_cb); From 8f987438573d38581039a98a1178a7fd25bba4ad Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 20 Oct 2012 12:28:31 +0300 Subject: [PATCH 16/49] upeksonly: Fix build-time warnings Fix warnings reported by gcc https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/drivers/upeksonly.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 6ca97067..50df8ca0 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -467,7 +467,6 @@ static void write_regs_finished(struct write_regs_data *wrdata, int result) static void write_regs_iterate(struct write_regs_data *wrdata) { - struct fpi_ssm *ssm; struct libusb_control_setup *setup; const struct sonly_regwrite *regwrite; int r; @@ -478,7 +477,6 @@ static void write_regs_iterate(struct write_regs_data *wrdata) } regwrite = &wrdata->regs[wrdata->regs_written]; - ssm = wrdata->ssm; fp_dbg("set %02x=%02x", regwrite->reg, regwrite->value); setup = libusb_control_transfer_get_setup(wrdata->transfer); @@ -1019,9 +1017,6 @@ static void initsm_2016_run_state(struct fpi_ssm *ssm) static void initsm_1000_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { case INITSM_1000_WRITEV_1: sm_write_regs(ssm, initsm_1000_writev_1, G_N_ELEMENTS(initsm_1000_writev_1)); @@ -1183,7 +1178,7 @@ static void initsm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { struct sonly_dev *sdev = dev->priv; - struct fpi_ssm *ssm; + struct fpi_ssm *ssm = NULL; int i; sdev->deactivating = FALSE; From 84b97ea15b519ac26af3a71e2a4d929cb140f0ff Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 26 Oct 2012 16:44:37 +0300 Subject: [PATCH 17/49] lib: Fix warning when debug logs are disabled Fix warning in sync.c when debug logs are not enabled https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/sync.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libfprint/sync.c b/libfprint/sync.c index 440b725a..ca2f302f 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -320,7 +320,6 @@ static void verify_stop_cb(struct fp_dev *dev, void *user_data) API_EXPORTED int fp_verify_finger_img(struct fp_dev *dev, struct fp_print_data *enrolled_print, struct fp_img **img) { - struct fp_driver *drv = dev->drv; struct sync_verify_data *vdata; gboolean stopped = FALSE; int r; @@ -335,7 +334,7 @@ API_EXPORTED int fp_verify_finger_img(struct fp_dev *dev, return -EINVAL; } - fp_dbg("to be handled by %s", drv->name); + fp_dbg("to be handled by %s", dev->drv->name); vdata = g_malloc0(sizeof(struct sync_verify_data)); r = fp_async_verify_start(dev, enrolled_print, sync_verify_cb, vdata); if (r < 0) { @@ -452,13 +451,12 @@ API_EXPORTED int fp_identify_finger_img(struct fp_dev *dev, struct fp_print_data **print_gallery, size_t *match_offset, struct fp_img **img) { - struct fp_driver *drv = dev->drv; gboolean stopped = FALSE; struct sync_identify_data *idata = g_malloc0(sizeof(struct sync_identify_data)); int r; - fp_dbg("to be handled by %s", drv->name); + fp_dbg("to be handled by %s", dev->drv->name); r = fp_async_identify_start(dev, print_gallery, sync_identify_cb, idata); if (r < 0) { From d8aae30a672485de747e5a58ff7520128b718515 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 3 Nov 2012 16:08:04 +0300 Subject: [PATCH 18/49] aes2501: Harden against low finger pressure Wait for 3 empty frames before stopping the scan The driver used to stop the scan immediately after an empty frame (by checking for hist sum == 0), but it is possible to get empty frames in the middle of the scan due to low finger pressure. Waiting for 3 empty frames stop the driver wrongly aborting the scan too early. https://bugs.freedesktop.org/show_bug.cgi?id=56715 --- libfprint/drivers/aes2501.c | 41 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 617bb64f..f002b93d 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -67,6 +67,7 @@ struct aes2501_dev { GSList *strips; size_t strips_len; gboolean deactivating; + int no_finger_cnt; }; typedef void (*aes2501_read_regs_cb)(struct fp_img_dev *dev, int status, @@ -559,12 +560,6 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) goto out; } - /* FIXME: would preallocating strip buffers be a decent optimization? */ - stripdata = g_malloc(192 * 8); - memcpy(stripdata, data + 1, 192*8); - aesdev->strips = g_slist_prepend(aesdev->strips, stripdata); - aesdev->strips_len++; - threshold = regval_from_dump(data + 1 + 192*8 + 1 + 16*2 + 1 + 8, AES2501_REG_DATFMT); if (threshold < 0) { @@ -572,27 +567,36 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) goto out; } - sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f); + sum = sum_histogram_values(data + 1 + 192*8, threshold & 0x0f); if (sum < 0) { fpi_ssm_mark_aborted(ssm, sum); goto out; } fp_dbg("sum=%d", sum); - /* FIXME: 0 might be too low as a threshold */ - /* FIXME: sometimes we get 0 in the middle of a scan, should we wait for - * a few consecutive zeroes? */ - /* FIXME: we should have an upper limit on the number of strips */ - - /* If sum is 0, finger has been removed */ + /* Sum is 0, maybe finger was removed? Wait for 3 empty frames + * to ensure + */ if (sum == 0) { - /* assemble image and submit it to library */ - assemble_and_submit_image(dev); - fpi_imgdev_report_finger_status(dev, FALSE); - /* marking machine complete will re-trigger finger detection loop */ - fpi_ssm_mark_completed(ssm); + aesdev->no_finger_cnt++; + if (aesdev->no_finger_cnt == 3) { + /* assemble image and submit it to library */ + assemble_and_submit_image(dev); + fpi_imgdev_report_finger_status(dev, FALSE); + /* marking machine complete will re-trigger finger detection loop */ + fpi_ssm_mark_completed(ssm); + } else { + fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP); + } } else { /* obtain next strip */ + /* FIXME: would preallocating strip buffers be a decent optimization? */ + stripdata = g_malloc(192 * 8); + memcpy(stripdata, data + 1, 192*8); + aesdev->no_finger_cnt = 0; + aesdev->strips = g_slist_prepend(aesdev->strips, stripdata); + aesdev->strips_len++; + fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP); } @@ -677,6 +681,7 @@ static void start_capture(struct fp_img_dev *dev) return; } + aesdev->no_finger_cnt = 0; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); fp_dbg(""); ssm->priv = dev; From e32fa8cc3825a6ce5db558094e81134d433293e3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 3 Nov 2012 16:13:05 +0300 Subject: [PATCH 19/49] aes2501: Improve image contrast When scanning, check the histogram sum, and increase the ADREFHI register value if the sum is too low, or decrease it if it's too high. https://bugs.freedesktop.org/show_bug.cgi?id=56715 --- libfprint/drivers/aes2501.c | 17 +++++++++++++++-- libfprint/drivers/aes2501.h | 6 ++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index f002b93d..2a4ecd86 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -515,13 +515,13 @@ static const struct aes_regwrite capture_reqs_2[] = { { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT }, }; -static const struct aes_regwrite strip_scan_reqs[] = { +static struct aes_regwrite strip_scan_reqs[] = { { AES2501_REG_IMAGCTRL, AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE }, { AES2501_REG_STRTCOL, 0x00 }, { AES2501_REG_ENDCOL, 0x2f }, { AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X }, - { AES2501_REG_ADREFHI, 0x5b }, + { AES2501_REG_ADREFHI, AES2501_ADREFHI_MAX_VALUE }, { AES2501_REG_ADREFLO, 0x20 }, { AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT }, }; @@ -574,6 +574,17 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) } fp_dbg("sum=%d", sum); + if (sum < AES2501_SUM_LOW_THRESH) { + strip_scan_reqs[4].value -= 0x8; + if (strip_scan_reqs[4].value < AES2501_ADREFHI_MIN_VALUE) + strip_scan_reqs[4].value = AES2501_ADREFHI_MIN_VALUE; + } else if (sum > AES2501_SUM_HIGH_THRESH) { + strip_scan_reqs[4].value += 0x8; + if (strip_scan_reqs[4].value > AES2501_ADREFHI_MAX_VALUE) + strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE; + } + fp_dbg("ADREFHI is %.2x", strip_scan_reqs[4].value); + /* Sum is 0, maybe finger was removed? Wait for 3 empty frames * to ensure */ @@ -682,6 +693,8 @@ static void start_capture(struct fp_img_dev *dev) } aesdev->no_finger_cnt = 0; + /* Reset gain */ + strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); fp_dbg(""); ssm->priv = dev; diff --git a/libfprint/drivers/aes2501.h b/libfprint/drivers/aes2501.h index a15699f9..9f2f1b6e 100644 --- a/libfprint/drivers/aes2501.h +++ b/libfprint/drivers/aes2501.h @@ -167,4 +167,10 @@ enum aes2501_sensor_gain2 { #define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */ #define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */ +#define AES2501_ADREFHI_MIN_VALUE 0x28 +#define AES2501_ADREFHI_MAX_VALUE 0x58 + +#define AES2501_SUM_HIGH_THRESH 1000 +#define AES2501_SUM_LOW_THRESH 700 + #endif /* __AES2501_H */ From fecf6d6fe5d17f4d0cb5cc8e19d0f51c58fcc712 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 3 Nov 2012 16:29:51 +0300 Subject: [PATCH 20/49] aes2501: Update copyright line https://bugs.freedesktop.org/show_bug.cgi?id=56715 --- libfprint/drivers/aes2501.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 2a4ecd86..8b7fa582 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -2,7 +2,7 @@ * AuthenTec AES2501 driver for libfprint * Copyright (C) 2007-2008 Daniel Drake * Copyright (C) 2007 Cyrille Bagard - * Copyright (C) 2007 Vasily Khoruzhick + * Copyright (C) 2007, 2012 Vasily Khoruzhick * * Based on code from http://home.gna.org/aes2501, relicensed with permission * From 9e10edd422e5130e210e17d90c5db9135029f165 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 5 Nov 2012 19:52:46 +0100 Subject: [PATCH 21/49] aes2501: Add year 2008 to the copyright. https://bugs.freedesktop.org/show_bug.cgi?id=56715#c7 --- libfprint/drivers/aes2501.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 8b7fa582..1b827376 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -2,7 +2,7 @@ * AuthenTec AES2501 driver for libfprint * Copyright (C) 2007-2008 Daniel Drake * Copyright (C) 2007 Cyrille Bagard - * Copyright (C) 2007, 2012 Vasily Khoruzhick + * Copyright (C) 2007-2008, 2012 Vasily Khoruzhick * * Based on code from http://home.gna.org/aes2501, relicensed with permission * From 5d32102efefe955e9f5bdbf5809a5fb637d77e89 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 26 Oct 2012 16:36:21 +0300 Subject: [PATCH 22/49] nbis: prefix global variables with "g_" It fixes a lot of warnings about shadowing global variable https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/img.c | 2 +- libfprint/nbis/include/lfs.h | 14 +++++++------- libfprint/nbis/include/log.h | 8 ++++---- libfprint/nbis/mindtct/contour.c | 8 ++++---- libfprint/nbis/mindtct/detect.c | 2 +- libfprint/nbis/mindtct/globals.c | 16 ++++++++-------- libfprint/nbis/mindtct/loop.c | 4 ++-- libfprint/nbis/mindtct/matchpat.c | 12 ++++++------ libfprint/nbis/mindtct/minutia.c | 32 +++++++++++++++---------------- 9 files changed, 49 insertions(+), 49 deletions(-) diff --git a/libfprint/img.c b/libfprint/img.c index 1c708582..64a6240b 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -290,7 +290,7 @@ int fpi_img_detect_minutiae(struct fp_img *img) &low_contrast_map, &low_flow_map, &high_curve_map, &map_w, &map_h, &bdata, &bw, &bh, &bd, img->data, img->width, img->height, 8, - DEFAULT_PPI / (double)25.4, &lfsparms_V2); + DEFAULT_PPI / (double)25.4, &g_lfsparms_V2); g_timer_stop(timer); fp_dbg("minutiae scan completed in %f secs", g_timer_elapsed(timer, NULL)); g_timer_destroy(timer); diff --git a/libfprint/nbis/include/lfs.h b/libfprint/nbis/include/lfs.h index 2da5d258..49aad842 100644 --- a/libfprint/nbis/include/lfs.h +++ b/libfprint/nbis/include/lfs.h @@ -1021,12 +1021,12 @@ extern int closest_dir_dist(const int, const int, const int); /*************************************************************************/ /* EXTERNAL GLOBAL VARIABLE DEFINITIONS */ /*************************************************************************/ -extern double dft_coefs[]; -extern LFSPARMS lfsparms; -extern LFSPARMS lfsparms_V2; -extern int nbr8_dx[]; -extern int nbr8_dy[]; -extern int chaincodes_nbr8[]; -extern FEATURE_PATTERN feature_patterns[]; +extern double g_dft_coefs[]; +extern LFSPARMS g_lfsparms; +extern LFSPARMS g_lfsparms_V2; +extern int g_nbr8_dx[]; +extern int g_nbr8_dy[]; +extern int g_chaincodes_nbr8[]; +extern FEATURE_PATTERN g_feature_patterns[]; #endif diff --git a/libfprint/nbis/include/log.h b/libfprint/nbis/include/log.h index 36967f19..a9cd6030 100644 --- a/libfprint/nbis/include/log.h +++ b/libfprint/nbis/include/log.h @@ -36,10 +36,10 @@ identified are necessarily the best available for the purpose. #define LOG_FILE "log.txt" #endif -extern FILE *logfp; -extern int avrdir; -extern float dir_strength; -extern int nvalid; +extern FILE *g_logfp; +extern int g_avrdir; +extern float g_dir_strength; +extern int g_nvalid; extern int open_logfile(void); extern int close_logfile(void); diff --git a/libfprint/nbis/mindtct/contour.c b/libfprint/nbis/mindtct/contour.c index 24d15c4a..92e77f50 100644 --- a/libfprint/nbis/mindtct/contour.c +++ b/libfprint/nbis/mindtct/contour.c @@ -742,8 +742,8 @@ static int next_contour_pixel(int *next_x_loc, int *next_y_loc, /* Set current scan pixel to the new neighbor. */ /* REMEMBER: the neighbors are being scanned around the original */ /* feature point. */ - cur_nbr_x = cur_x_loc + nbr8_dx[nbr_i]; - cur_nbr_y = cur_y_loc + nbr8_dy[nbr_i]; + cur_nbr_x = cur_x_loc + g_nbr8_dx[nbr_i]; + cur_nbr_y = cur_y_loc + g_nbr8_dy[nbr_i]; /* If new neighbor is not within image boundaries... */ if((cur_nbr_x < 0) || (cur_nbr_x >= iw) || @@ -766,8 +766,8 @@ static int next_contour_pixel(int *next_x_loc, int *next_y_loc, if(nbr_i % 2){ /* To do this, look ahead one more neighbor pixel. */ ni = next_scan_nbr(nbr_i, scan_clock); - nx = cur_x_loc + nbr8_dx[ni]; - ny = cur_y_loc + nbr8_dy[ni]; + nx = cur_x_loc + g_nbr8_dx[ni]; + ny = cur_y_loc + g_nbr8_dy[ni]; /* If new neighbor is not within image boundaries... */ if((nx < 0) || (nx >= iw) || (ny < 0) || (ny >= ih)) diff --git a/libfprint/nbis/mindtct/detect.c b/libfprint/nbis/mindtct/detect.c index 214459b8..9b1bdbc9 100644 --- a/libfprint/nbis/mindtct/detect.c +++ b/libfprint/nbis/mindtct/detect.c @@ -122,7 +122,7 @@ static int lfs_detect_minutiae_V2(MINUTIAE **ominutiae, /* Initialize wave form lookup tables for DFT analyses. */ /* used for direction binarization. */ - if((ret = init_dftwaves(&dftwaves, dft_coefs, lfsparms->num_dft_waves, + if((ret = init_dftwaves(&dftwaves, g_dft_coefs, lfsparms->num_dft_waves, lfsparms->windowsize))){ /* Free memory allocated to this point. */ free_dir2rad(dir2rad); diff --git a/libfprint/nbis/mindtct/globals.c b/libfprint/nbis/mindtct/globals.c index 01454dba..da85aab4 100644 --- a/libfprint/nbis/mindtct/globals.c +++ b/libfprint/nbis/mindtct/globals.c @@ -40,7 +40,7 @@ identified are necessarily the best available for the purpose. /*************************************************************************/ #ifdef LOG_REPORT -FILE *logfp; +FILE *g_logfp; #endif /* Constants (C) for defining 4 DFT frequencies, where */ @@ -50,10 +50,10 @@ FILE *logfp; /* 2 = twice the frequency in range X. */ /* 3 = three times the frequency in reange X. */ /* 4 = four times the frequency in ranage X. */ -double dft_coefs[NUM_DFT_WAVES] = { 1,2,3,4 }; +double g_dft_coefs[NUM_DFT_WAVES] = { 1,2,3,4 }; /* Allocate and initialize a global LFS parameters structure. */ -LFSPARMS lfsparms = { +LFSPARMS g_lfsparms = { /* Image Controls */ PAD_VALUE, JOIN_LINE_RADIUS, @@ -137,7 +137,7 @@ LFSPARMS lfsparms = { /* Allocate and initialize VERSION 2 global LFS parameters structure. */ -LFSPARMS lfsparms_V2 = { +LFSPARMS g_lfsparms_V2 = { /* Image Controls */ PAD_VALUE, JOIN_LINE_RADIUS, @@ -221,17 +221,17 @@ LFSPARMS lfsparms_V2 = { /* Variables for conducting 8-connected neighbor analyses. */ /* Pixel neighbor offsets: 0 1 2 3 4 5 6 7 */ /* 7 0 1 */ -int nbr8_dx[] = { 0, 1, 1, 1, 0,-1,-1,-1 }; /* 6 C 2 */ -int nbr8_dy[] = { -1,-1, 0, 1, 1, 1, 0,-1 }; /* 5 4 3 */ +int g_nbr8_dx[] = { 0, 1, 1, 1, 0,-1,-1,-1 }; /* 6 C 2 */ +int g_nbr8_dy[] = { -1,-1, 0, 1, 1, 1, 0,-1 }; /* 5 4 3 */ /* The chain code lookup matrix for 8-connected neighbors. */ /* Should put this in globals. */ -int chaincodes_nbr8[]={ 3, 2, 1, +int g_chaincodes_nbr8[]={ 3, 2, 1, 4,-1, 0, 5, 6, 7}; /* Global array of feature pixel pairs. */ -FEATURE_PATTERN feature_patterns[]= +FEATURE_PATTERN g_feature_patterns[]= {{RIDGE_ENDING, /* a. Ridge Ending (appearing) */ APPEARING, {0,0}, diff --git a/libfprint/nbis/mindtct/loop.c b/libfprint/nbis/mindtct/loop.c index da5de0e5..21c8d592 100644 --- a/libfprint/nbis/mindtct/loop.c +++ b/libfprint/nbis/mindtct/loop.c @@ -110,14 +110,14 @@ static int chain_code_loop(int **ochain, int *onchain, /* Derive chain code index from neighbor deltas. */ /* The deltas are on the range [-1..1], so to use them as indices */ /* into the code list, they must first be incremented by one. */ - chain[i] = *(chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1); + chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1); } /* Now derive chain code between last and first points in the */ /* contour list. */ dx = contour_x[0] - contour_x[i]; dy = contour_y[0] - contour_y[i]; - chain[i] = *(chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1); + chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1); /* Store results to the output pointers. */ *ochain = chain; diff --git a/libfprint/nbis/mindtct/matchpat.c b/libfprint/nbis/mindtct/matchpat.c index ed4fc7c4..04bb27b8 100644 --- a/libfprint/nbis/mindtct/matchpat.c +++ b/libfprint/nbis/mindtct/matchpat.c @@ -69,8 +69,8 @@ int match_1st_pair(unsigned char p1, unsigned char p2, /* Foreach set of feature pairs ... */ for(i = 0; i < NFEATURES; i++){ /* If current scan pair matches first pair for feature ... */ - if((p1==feature_patterns[i].first[0]) && - (p2==feature_patterns[i].first[1])){ + if((p1==g_feature_patterns[i].first[0]) && + (p2==g_feature_patterns[i].first[1])){ /* Store feature as a possible match. */ possible[*nposs] = i; /* Bump number of stored possibilities. */ @@ -117,8 +117,8 @@ int match_2nd_pair(unsigned char p1, unsigned char p2, /* Foreach possible match based on first pair ... */ for(i = 0; i < tnposs; i++){ /* If current scan pair matches second pair for feature ... */ - if((p1==feature_patterns[possible[i]].second[0]) && - (p2==feature_patterns[possible[i]].second[1])){ + if((p1==g_feature_patterns[possible[i]].second[0]) && + (p2==g_feature_patterns[possible[i]].second[1])){ /* Store feature as a possible match. */ possible[*nposs] = possible[i]; /* Bump number of stored possibilities. */ @@ -160,8 +160,8 @@ int match_3rd_pair(unsigned char p1, unsigned char p2, /* Foreach possible match based on first and second pairs ... */ for(i = 0; i < tnposs; i++){ /* If current scan pair matches third pair for feature ... */ - if((p1==feature_patterns[possible[i]].third[0]) && - (p2==feature_patterns[possible[i]].third[1])){ + if((p1==g_feature_patterns[possible[i]].third[0]) && + (p2==g_feature_patterns[possible[i]].third[1])){ /* Store feature as a possible match. */ possible[*nposs] = possible[i]; /* Bump number of stored possibilities. */ diff --git a/libfprint/nbis/mindtct/minutia.c b/libfprint/nbis/mindtct/minutia.c index 6bcfaab7..497336b1 100644 --- a/libfprint/nbis/mindtct/minutia.c +++ b/libfprint/nbis/mindtct/minutia.c @@ -2521,7 +2521,7 @@ int process_horizontal_scan_minutia(MINUTIAE *minutiae, /* Feature location should always point to either ending */ /* of ridge or (for bifurcations) ending of valley. */ /* So, if detected feature is APPEARING... */ - if(feature_patterns[feature_id].appearing){ + if(g_feature_patterns[feature_id].appearing){ /* Set y location to second scan row. */ y_loc = cy+1; /* Set y location of neighboring edge pixel to the first scan row. */ @@ -2550,15 +2550,15 @@ int process_horizontal_scan_minutia(MINUTIAE *minutiae, else{ /* Get minutia direction based on current IMAP value. */ idir = get_low_curvature_direction(SCAN_HORIZONTAL, - feature_patterns[feature_id].appearing, + g_feature_patterns[feature_id].appearing, imapval, lfsparms->num_directions); } /* Create a minutia object based on derived attributes. */ if((ret = create_minutia(&minutia, x_loc, y_loc, x_edge, y_edge, idir, DEFAULT_RELIABILITY, - feature_patterns[feature_id].type, - feature_patterns[feature_id].appearing, feature_id))) + g_feature_patterns[feature_id].type, + g_feature_patterns[feature_id].appearing, feature_id))) /* Return system error. */ return(ret); @@ -2627,7 +2627,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae, /* Feature location should always point to either ending */ /* of ridge or (for bifurcations) ending of valley. */ /* So, if detected feature is APPEARING... */ - if(feature_patterns[feature_id].appearing){ + if(g_feature_patterns[feature_id].appearing){ /* Set y location to second scan row. */ y_loc = cy+1; /* Set y location of neighboring edge pixel to the first scan row. */ @@ -2665,7 +2665,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae, else{ /* Get minutia direction based on current block's direction. */ idir = get_low_curvature_direction(SCAN_HORIZONTAL, - feature_patterns[feature_id].appearing, dmapval, + g_feature_patterns[feature_id].appearing, dmapval, lfsparms->num_directions); } @@ -2680,8 +2680,8 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae, /* Create a minutia object based on derived attributes. */ if((ret = create_minutia(&minutia, x_loc, y_loc, x_edge, y_edge, idir, reliability, - feature_patterns[feature_id].type, - feature_patterns[feature_id].appearing, feature_id))) + g_feature_patterns[feature_id].type, + g_feature_patterns[feature_id].appearing, feature_id))) /* Return system error. */ return(ret); @@ -2740,7 +2740,7 @@ int process_vertical_scan_minutia(MINUTIAE *minutiae, /* Feature location should always point to either ending */ /* of ridge or (for bifurcations) ending of valley. */ /* So, if detected feature is APPEARING... */ - if(feature_patterns[feature_id].appearing){ + if(g_feature_patterns[feature_id].appearing){ /* Set x location to second scan column. */ x_loc = cx+1; /* Set x location of neighboring edge pixel to the first scan column. */ @@ -2776,15 +2776,15 @@ int process_vertical_scan_minutia(MINUTIAE *minutiae, else{ /* Get minutia direction based on current IMAP value. */ idir = get_low_curvature_direction(SCAN_VERTICAL, - feature_patterns[feature_id].appearing, + g_feature_patterns[feature_id].appearing, imapval, lfsparms->num_directions); } /* Create a minutia object based on derived attributes. */ if((ret = create_minutia(&minutia, x_loc, y_loc, x_edge, y_edge, idir, DEFAULT_RELIABILITY, - feature_patterns[feature_id].type, - feature_patterns[feature_id].appearing, feature_id))) + g_feature_patterns[feature_id].type, + g_feature_patterns[feature_id].appearing, feature_id))) /* Return system error. */ return(ret); @@ -2845,7 +2845,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae, /* Feature location should always point to either ending */ /* of ridge or (for bifurcations) ending of valley. */ /* So, if detected feature is APPEARING... */ - if(feature_patterns[feature_id].appearing){ + if(g_feature_patterns[feature_id].appearing){ /* Set x location to second scan column. */ x_loc = cx+1; /* Set x location of neighboring edge pixel to the first scan column. */ @@ -2890,7 +2890,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae, else{ /* Get minutia direction based on current block's direction. */ idir = get_low_curvature_direction(SCAN_VERTICAL, - feature_patterns[feature_id].appearing, dmapval, + g_feature_patterns[feature_id].appearing, dmapval, lfsparms->num_directions); } @@ -2905,8 +2905,8 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae, /* Create a minutia object based on derived attributes. */ if((ret = create_minutia(&minutia, x_loc, y_loc, x_edge, y_edge, idir, reliability, - feature_patterns[feature_id].type, - feature_patterns[feature_id].appearing, feature_id))) + g_feature_patterns[feature_id].type, + g_feature_patterns[feature_id].appearing, feature_id))) /* Return system error. */ return(ret); From 1cfd14b7fe8f9e68c5bd74461bcd17e25b9f1d15 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 26 Oct 2012 16:40:53 +0300 Subject: [PATCH 23/49] nbis: fix rest of warnings reported by gcc https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/nbis/mindtct/block.c | 3 +-- libfprint/nbis/mindtct/detect.c | 12 ++++++------ libfprint/nbis/mindtct/loop.c | 8 -------- libfprint/nbis/mindtct/ridges.c | 14 +++++++------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/libfprint/nbis/mindtct/block.c b/libfprint/nbis/mindtct/block.c index 7c7a6565..be0b3f97 100644 --- a/libfprint/nbis/mindtct/block.c +++ b/libfprint/nbis/mindtct/block.c @@ -86,7 +86,7 @@ int block_offsets(int **optr, int *ow, int *oh, int *blkoffs, bx, by, bw, bh, bi, bsize; int blkrow_start, blkrow_size, offset; int lastbw, lastbh; - int pad2, pw, ph; + int pad2, pw; /* Test if unpadded image is smaller than a single block */ if((iw < blocksize) || (ih < blocksize)){ @@ -99,7 +99,6 @@ int block_offsets(int **optr, int *ow, int *oh, /* Compute padded width and height of image */ pad2 = pad<<1; pw = iw + pad2; - ph = ih + pad2; /* Compute the number of columns and rows of blocks in the image. */ /* Take the ceiling to account for "leftovers" at the right and */ diff --git a/libfprint/nbis/mindtct/detect.c b/libfprint/nbis/mindtct/detect.c index 9b1bdbc9..deadf291 100644 --- a/libfprint/nbis/mindtct/detect.c +++ b/libfprint/nbis/mindtct/detect.c @@ -385,12 +385,12 @@ int get_minutiae(MINUTIAE **ominutiae, int **oquality_map, const int id, const double ppmm, const LFSPARMS *lfsparms) { int ret; - MINUTIAE *minutiae; - int *direction_map, *low_contrast_map, *low_flow_map; - int *high_curve_map, *quality_map; - int map_w, map_h; - unsigned char *bdata; - int bw, bh; + MINUTIAE *minutiae = NULL; + int *direction_map = NULL, *low_contrast_map = NULL, *low_flow_map = NULL; + int *high_curve_map = NULL, *quality_map = NULL; + int map_w = 0, map_h = 0; + unsigned char *bdata = NULL; + int bw = 0, bh = 0; /* If input image is not 8-bit grayscale ... */ if(id != 8){ diff --git a/libfprint/nbis/mindtct/loop.c b/libfprint/nbis/mindtct/loop.c index 21c8d592..3792b88d 100644 --- a/libfprint/nbis/mindtct/loop.c +++ b/libfprint/nbis/mindtct/loop.c @@ -782,7 +782,6 @@ int process_loop(MINUTIAE *minutiae, unsigned char *bdata, const int iw, const int ih, const LFSPARMS *lfsparms) { - int halfway; int idir, type, appearing; double min_dist, max_dist; int min_fr, max_fr, min_to, max_to; @@ -800,9 +799,6 @@ int process_loop(MINUTIAE *minutiae, /* Get pixel value of feature's interior. */ feature_pix = *(bdata + (contour_y[0] * iw) + contour_x[0]); - /* Compute half the perimeter of the loop. */ - halfway = ncontour>>1; - /* Get the aspect dimensions of the loop in units of */ /* squared distance. */ get_loop_aspect(&min_fr, &min_to, &min_dist, @@ -940,7 +936,6 @@ int process_loop_V2(MINUTIAE *minutiae, unsigned char *bdata, const int iw, const int ih, int *plow_flow_map, const LFSPARMS *lfsparms) { - int halfway; int idir, type, appearing; double min_dist, max_dist; int min_fr, max_fr, min_to, max_to; @@ -960,9 +955,6 @@ int process_loop_V2(MINUTIAE *minutiae, /* Get pixel value of feature's interior. */ feature_pix = *(bdata + (contour_y[0] * iw) + contour_x[0]); - /* Compute half the perimeter of the loop. */ - halfway = ncontour>>1; - /* Get the aspect dimensions of the loop in units of */ /* squared distance. */ get_loop_aspect(&min_fr, &min_to, &min_dist, diff --git a/libfprint/nbis/mindtct/ridges.c b/libfprint/nbis/mindtct/ridges.c index 0fb26863..9fb110f2 100644 --- a/libfprint/nbis/mindtct/ridges.c +++ b/libfprint/nbis/mindtct/ridges.c @@ -565,7 +565,7 @@ static int ridge_count(const int first, const int second, MINUTIAE *minutiae, MINUTIA *minutia1, *minutia2; int i, ret, found; int *xlist, *ylist, num; - int ridge_count, ridge_start, ridge_end; + int ridge_cnt, ridge_start, ridge_end; int prevpix, curpix; minutia1 = minutiae->list[first]; @@ -614,7 +614,7 @@ static int ridge_count(const int first, const int second, MINUTIAE *minutiae, } /* Ready to count ridges, so initialize counter to 0. */ - ridge_count = 0; + ridge_cnt = 0; print2log("RIDGE COUNT: %d,%d to %d,%d ", minutia1->x, minutia1->y, minutia2->x, minutia2->y); @@ -630,7 +630,7 @@ static int ridge_count(const int first, const int second, MINUTIAE *minutiae, print2log("\n"); /* Return number of ridges counted to this point. */ - return(ridge_count); + return(ridge_cnt); } /* Otherwise, we found a new ridge start transition, so store */ /* its location (the location of the 1 in 0-to-1 transition). */ @@ -647,7 +647,7 @@ static int ridge_count(const int first, const int second, MINUTIAE *minutiae, print2log("\n"); /* Return number of ridges counted to this point. */ - return(ridge_count); + return(ridge_cnt); } /* Otherwise, we found a new ridge end transition, so store */ /* its location (the location of the 0 in 1-to-0 transition). */ @@ -680,7 +680,7 @@ static int ridge_count(const int first, const int second, MINUTIAE *minutiae, if(ret){ /* Then assume we have found a valid ridge crossing and bump */ /* the ridge counter. */ - ridge_count++; + ridge_cnt++; } /* Otherwise, ignore the current ridge start and end transitions */ @@ -694,7 +694,7 @@ static int ridge_count(const int first, const int second, MINUTIAE *minutiae, print2log("\n"); /* Return the number of ridges counted. */ - return(ridge_count); + return(ridge_cnt); } /************************************************************************* @@ -719,7 +719,7 @@ static int count_minutia_ridges(const int first, MINUTIAE *minutiae, unsigned char *bdata, const int iw, const int ih, const LFSPARMS *lfsparms) { - int i, ret, *nbr_list, *nbr_nridges, nnbrs; + int i, ret, *nbr_list = NULL, *nbr_nridges, nnbrs; /* Find up to the maximum number of qualifying neighbors. */ if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs, From f569d0bf4479c4d6ebf1972b59cd7450ec9a3258 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 20 Oct 2012 12:26:38 +0300 Subject: [PATCH 24/49] AES1610: driver cleanup, part #1 Fix warnings reported by gcc https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/drivers/aes1610.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 8b81a80c..fe046e3e 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -500,7 +500,6 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, void *user_da static void start_finger_detection(struct fp_img_dev *dev) { struct aes1610_dev *aesdev = dev->priv; - struct libusb_transfer *transfer; if (aesdev->deactivating) { complete_deactivation(dev); @@ -780,7 +779,7 @@ static int adjust_gain(unsigned char *buffer, int status) /* * Restore the default gain values */ -static void restore_gain() +static void restore_gain(void) { strip_scan_reqs[0].value = list_BE_values[0]; strip_scan_reqs[1].value = 0x04; @@ -815,7 +814,6 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) struct aes1610_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; int sum, i; - int threshold; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fpi_ssm_mark_aborted(ssm, -EIO); From 6b84c6664fe9da98e013caab99145d8f0279b9bb Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 5 Nov 2012 22:39:49 +0300 Subject: [PATCH 25/49] AES1610: driver cleanup, part #2 Remove dead code https://bugs.freedesktop.org/show_bug.cgi?id=56439 --- libfprint/drivers/aes1610.c | 169 ------------------------------------ 1 file changed, 169 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index fe046e3e..20bbe695 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -110,103 +110,6 @@ static void generic_ignore_data_cb(struct libusb_transfer *transfer) libusb_free_transfer(transfer); } - -static void read_regs_data_cb(struct libusb_transfer *transfer) -{ - struct aes1610_read_regs *rdata = transfer->user_data; - unsigned char *retdata = NULL; - int r; - - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - r = -EIO; - } else if (transfer->length != transfer->actual_length) { - r = -EPROTO; - } else { - r = 0; - retdata = transfer->buffer; - } - - rdata->callback(rdata->dev, r, retdata, rdata->user_data); - g_free(rdata); - g_free(transfer->buffer); - libusb_free_transfer(transfer); -} - -static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data) -{ - struct aes1610_read_regs *rdata = user_data; - struct libusb_transfer *transfer; - unsigned char *data; - int r; - - g_free(rdata->regwrite); - if (result != 0) - goto err; - - transfer = libusb_alloc_transfer(0); - if (!transfer) { - result = -ENOMEM; - goto err; - } - - data = g_malloc(126); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 126, - read_regs_data_cb, rdata, BULK_TIMEOUT); - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(data); - libusb_free_transfer(transfer); - result = -EIO; - goto err; - } - - return; -err: - rdata->callback(dev, result, NULL, rdata->user_data); - g_free(rdata); -} - - -// XXX: this comes from aes2501 driver but it is unused here -static void read_regs(struct fp_img_dev *dev, aes1610_read_regs_cb callback, - void *user_data) -{ - /* FIXME: regwrite is dynamic because of asynchronity. is this really - * required? */ - struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite)); - struct aes1610_read_regs *rdata = g_malloc(sizeof(*rdata)); - - fp_dbg(""); - //regwrite->reg = AES1610_REG_CTRL2; - //regwrite->value = AES1610_CTRL2_READ_REGS; - rdata->dev = dev; - rdata->callback = callback; - rdata->user_data = user_data; - rdata->regwrite = regwrite; - - //aes_write_regv(dev, (const struct aes_regwrite *) regwrite, 1, - // read_regs_rq_cb, rdata); -} - -/* Read the value of a specific register from a register dump */ -static int regval_from_dump(unsigned char *data, uint8_t target) -{ - if (*data != FIRST_AES1610_REG) { - fp_err("not a register dump"); - return -EILSEQ; - } - - if (!(FIRST_AES1610_REG <= target && target <= LAST_AES1610_REG)) { - fp_err("out of range"); - return -EINVAL; - } - - target -= FIRST_AES1610_REG; - target *= 2; - return data[target + 1]; -} - static void generic_write_regv_cb(struct fp_img_dev *dev, int result, void *user_data) { @@ -217,8 +120,6 @@ static void generic_write_regv_cb(struct fp_img_dev *dev, int result, fpi_ssm_mark_aborted(ssm, result); } - - /* read the specified number of bytes from the IN endpoint but throw them * away, then increment the SSM */ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) @@ -246,25 +147,6 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) /****** IMAGE PROCESSING ******/ -static int sum_histogram_values(unsigned char *data, uint8_t threshold) -{ - int r = 0; - int i; - uint16_t *histogram = (uint16_t *)(data + 1); - - if (*data != 0xde) - return -EILSEQ; - - if (threshold > 0x0f) - return -EINVAL; - - /* FIXME endianness */ - for (i = threshold; i < 16; i++) - r += histogram[i]; - - return r; -} - /* find overlapping parts of frames */ static unsigned int find_overlap(unsigned char *first_frame, unsigned char *second_frame, unsigned int *min_error) @@ -416,15 +298,6 @@ static const struct aes_regwrite finger_det_reqs[] = { { 0x81, 0x04 } }; -static const struct aes_regwrite finger_det_none[] = { - { 0x80, 0x01 }, - { 0x82, 0x00 }, - { 0x86, 0x00 }, - { 0xB1, 0x28 }, - { 0x1D, 0x00 } -}; - - static void start_finger_detection(struct fp_img_dev *dev); static void finger_det_data_cb(struct libusb_transfer *transfer) @@ -461,12 +334,6 @@ out: libusb_free_transfer(transfer); } - -static void finger_det_none_cb(struct fp_img_dev *dev, int result, void *user_data){ - fpi_imgdev_report_finger_status(dev, FALSE); - start_finger_detection(dev); -} - static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, void *user_data) { struct libusb_transfer *transfer; @@ -824,17 +691,6 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) } /* FIXME: would preallocating strip buffers be a decent optimization? */ - //stripdata = g_malloc(128 * 4); - //memcpy(stripdata, data + 1, 128 * 4); - //aesdev->strips = g_slist_prepend(aesdev->strips, stripdata); - //aesdev->strips_len++; - - /*threshold = regval_from_dump(data + 1 + 128*8 + 1 + 16*2 + 1 + 8, - 0x97); - if (threshold < 0) { - fpi_ssm_mark_aborted(ssm, threshold); - goto out; - }*/ sum = 0; for (i = 516; i < 530; i++) @@ -985,26 +841,9 @@ static const struct aes_regwrite stop_reader[] = { enum activate_states { WRITE_INIT, -// READ_DATA, -// READ_REGS, ACTIVATE_NUM_STATES, }; -/* this come from aes2501 and is unused here -void activate_read_regs_cb(struct fp_img_dev *dev, int status, - unsigned char *regs, void *user_data) -{ - struct fpi_ssm *ssm = user_data; - struct aes1610_dev *aesdev = dev->priv; - - if (status != 0) { - fpi_ssm_mark_aborted(ssm, status); - } else { - fpi_ssm_next_state(ssm); - } -} -*/ - static void activate_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; @@ -1016,14 +855,6 @@ static void activate_run_state(struct fpi_ssm *ssm) fp_dbg("write init"); aes_write_regv(dev, init, G_N_ELEMENTS(init), generic_write_regv_cb, ssm); break; -/* case READ_DATA: - fp_dbg("read data"); - generic_read_ignore_data(ssm, 20); - break; - case READ_REGS: - fp_dbg("read regs"); - read_regs(dev, activate_read_regs_cb, ssm); - break;*/ } } From 9e92d4cf2c8ae4fad0b49576b0b6f8f4e5f2daa1 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 6 Nov 2012 09:30:40 +0100 Subject: [PATCH 26/49] examples: Fix compile-time warnings A few signedness problems. --- examples/img_capture_continuous.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/img_capture_continuous.c b/examples/img_capture_continuous.c index 701fd699..b30f2b1d 100644 --- a/examples/img_capture_continuous.c +++ b/examples/img_capture_continuous.c @@ -29,7 +29,7 @@ #define FORMAT 0x32595559 static int adaptor = -1; -static unsigned char *framebuffer = NULL; +static char *framebuffer = NULL; static Display *display = NULL; static Window window=(Window)NULL; @@ -50,7 +50,7 @@ static int connection = -1; u = u > 255 ? 255 : u;\ v = v > 255 ? 255 : v -static void grey2yuy2 (unsigned char *grey, unsigned char *YUV, int num) { +static void grey2yuy2 (unsigned char *grey, char *YUV, int num) { int i, j; int y0, y1, u0, u1, v0, v1; int gval; @@ -86,7 +86,7 @@ static void display_frame(struct fp_img *img) static void QueryXv() { - int num_adaptors; + unsigned int num_adaptors; int num_formats; XvImageFormatValues *formats = NULL; int i,j; From 39902374ce0f7ca21cf3412a7295ad82198ef053 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 3 Nov 2012 18:30:43 +0300 Subject: [PATCH 27/49] aes2550: Harden against low finger pressure Stop scan only after 3rd heartbeat message https://bugs.freedesktop.org/show_bug.cgi?id=56782 --- libfprint/drivers/aes2550.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 92c988ed..f0d60c40 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -59,6 +59,7 @@ struct aes2550_dev { GSList *strips; size_t strips_len; gboolean deactivating; + int heartbeat_cnt; }; /****** IMAGE PROCESSING ******/ @@ -369,6 +370,7 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; + struct aes2550_dev *aesdev = ssm->priv; unsigned char *data = transfer->buffer; int r; @@ -390,14 +392,21 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) fpi_ssm_mark_aborted(ssm, -EPROTO); goto out; } + aesdev->heartbeat_cnt = 0; fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); break; case AES2550_HEARTBEAT_SIZE: if (data[0] == AES2550_HEARTBEAT_MAGIC) { - /* No data for a long time, looks like finger was removed (or no movement) */ - /* assemble image and submit it to library */ - fp_dbg("Got heartbeat => last frame"); - fpi_ssm_next_state(ssm); + /* No data for a long time => finger was removed or there's no movement */ + aesdev->heartbeat_cnt++; + if (aesdev->heartbeat_cnt == 3) { + /* Got 3 heartbeat message, that's enough to consider that finger was removed, + * assemble image and submit it to the library */ + fp_dbg("Got 3 heartbeats => finger removed"); + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); + } } break; default: @@ -498,6 +507,7 @@ static void start_capture(struct fp_img_dev *dev) return; } + aesdev->heartbeat_cnt = 0; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); fp_dbg(""); ssm->priv = dev; From b307dd1a6abef8f87062d35dcbe2f2c22b959638 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 10 Nov 2012 18:21:19 +0300 Subject: [PATCH 28/49] aes2550: fix bug introduced by last commit ssm->priv is not aesdev, but fp_img_dev https://bugs.freedesktop.org/show_bug.cgi?id=56782 --- libfprint/drivers/aes2550.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index f0d60c40..6d68696d 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -370,7 +370,8 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct aes2550_dev *aesdev = ssm->priv; + struct fp_img_dev *dev = ssm->priv; + struct aes2550_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; int r; From ed2c75842a4542b0dbd9e4f188a40057bb537ea6 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 10 Nov 2012 18:22:32 +0300 Subject: [PATCH 29/49] upektc: Port to asynchronous model https://bugs.freedesktop.org/show_bug.cgi?id=56955 --- configure.ac | 5 +- libfprint/Makefile.am | 6 +- libfprint/core.c | 4 +- libfprint/drivers/upektc.c | 724 +++++++++++++++++++----------------- libfprint/drivers/upektc.h | 737 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1130 insertions(+), 346 deletions(-) create mode 100644 libfprint/drivers/upektc.h diff --git a/configure.ac b/configure.ac index 90cb0f61..66806df4 100644 --- a/configure.ac +++ b/configure.ac @@ -58,8 +58,7 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do ;; upektc) AC_DEFINE([ENABLE_UPEKTC], [], [Build UPEK TouchChip driver]) - enable_upektc="no" - # Driver not ported + enable_upektc="yes" ;; upeksonly) AC_DEFINE([ENABLE_UPEKSONLY], [], [Build UPEK TouchStrip sensor-only driver]) @@ -112,7 +111,7 @@ done AM_CONDITIONAL([ENABLE_UPEKTS], [test "$enable_upekts" = "yes"]) AM_CONDITIONAL([ENABLE_UPEKE2], [test "$enable_upeke2" = "yes"]) -#AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" = "yes"]) +AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" = "yes"]) AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" = "yes"]) AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" = "yes"]) AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" = "yes"]) diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 5ecf0622..7c5f182e 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 9916faa3..01a9cfa6 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 e115537f..f3610516 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 + * Copyright (C) 2012 Vasily Khoruzhick * * 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 #include - -#include #include - #include +#include "upektc.h" -#define SENSOR_FULL_IMAGE 59904 -#define WAIT_COUNT 5 +#define EP_IN (2 | LIBUSB_ENDPOINT_IN) +#define EP_OUT (3 | LIBUSB_ENDPOINT_OUT) +#define BULK_TIMEOUT 4000 -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 +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; - } - - if ( !nLen ) { - return 0; - } - - nRet = libusb_bulk_transfer(dev->udev, &msg2, &transferred, 1003); - if ( ( transferred == nLen ) && ( pnBuffer != NULL ) ) { - memcpy( pnBuffer, anBuf, nLen ); - return transferred; - } - - return nRet; + 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); } -/** - * \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 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; - nSum = 0; + 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); +} - for ( nIndex = 0; nIndex < SENSOR_FULL_IMAGE; nIndex++ ) { - if ( ( uint8 ) pnImage[ nIndex ] < 160 ) { - nSum++; +static void read_init_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + 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); +} + +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; + } + + 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); + + r = libusb_submit_transfer(transfer); + if (r < 0) { + g_free(data); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, r); + } + } + break; + } +} + +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 (!ssm->error) + start_finger_detection(dev); + fpi_ssm_free(ssm); +} + + +/****** FINGER PRESENCE DETECTION ******/ + +static int finger_present(unsigned char *img, size_t len) +{ + int i, sum; + + sum = 0; + + for (i = 0; i < len; i++) { + if (img[i] < 160) { + sum++; } } - return nSum < 500 ? 0 : 1; + fp_dbg("finger_present: sum is %d\n", sum); + return sum < SUM_THRESHOLD ? 0 : 1; } -/** - * \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); +static void finger_det_data_cb(struct libusb_transfer *transfer) +{ + struct fp_img_dev *dev = transfer->user_data; + unsigned char *data = transfer->buffer; - /* 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; + 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, "\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 ( 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - 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 ( 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - 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 ( 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - /* enable sensor */ - if ( askScanner( dev, anInitCommand, 0x00, NULL ) < 0 ) { - return -52; + 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); } +out: + g_free(data); + libusb_free_transfer(transfer); +} + +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; + } + + transfer = libusb_alloc_transfer(0); + if (!transfer) { + fpi_imgdev_session_error(dev, -ENOMEM); + goto exit_free_transfer; + } + + data = g_malloc(IMAGE_SIZE); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, IMAGE_SIZE, + finger_det_data_cb, dev, BULK_TIMEOUT); + + 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); +} + +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 (upekdev->deactivating) { + complete_deactivation(dev); + return; + } + + 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); + } +} + +/****** CAPTURE ******/ + +enum capture_states { + CAPTURE_WRITE_CMD, + CAPTURE_READ_DATA, + CAPTURE_NUM_STATES, +}; + +static void capture_cmd_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +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; + } + + 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); +} + +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; + } + + data = g_malloc(IMAGE_SIZE); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, IMAGE_SIZE, + capture_read_data_cb, ssm, BULK_TIMEOUT); + + r = libusb_submit_transfer(transfer); + if (r < 0) { + g_free(data); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, r); + } + } + break; + }; +} + +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); +} + +static void start_capture(struct fp_img_dev *dev) +{ + struct upektc_dev *upekdev = dev->priv; + struct fpi_ssm *ssm; + + if (upekdev->deactivating) { + complete_deactivation(dev); + return; + } + + 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 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; } -static int DetectFinger( struct fp_img_dev *dev ) { - sint32 nRet = 0; - uint8 *pnData = NULL; +static void dev_deactivate(struct fp_img_dev *dev) +{ + struct upektc_dev *upekdev = dev->priv; - pnData = g_malloc( SENSOR_FULL_IMAGE ); - - nRet = askScanner( dev, anScanCommand, SENSOR_FULL_IMAGE, pnData ); - - if ( nRet != SENSOR_FULL_IMAGE ) { - nRet = 0; - goto end; - } - - nRet = ValidScan( pnData ); - -end: - g_free( pnData ); - - return nRet; + upekdev->deactivating = TRUE; } -static int awaitFingerOn( struct fp_img_dev *dev ) { - int nRet = 0; - int nCount = WAIT_COUNT; +static void complete_deactivation(struct fp_img_dev *dev) +{ + struct upektc_dev *upekdev = dev->priv; + fp_dbg(""); - /* wait until a finger is present */ - do { - nRet = DetectFinger( dev ); - } while ( nRet == 0 ); - - /* give user time to scan his full finger */ - while ( nCount-- ) { - nRet = DetectFinger( dev ); - } - - return nRet != 1 ? nRet : 0; + upekdev->deactivating = FALSE; + fpi_imgdev_deactivate_complete(dev); } -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_init(struct fp_img_dev *dev, unsigned long driver_data) +{ + /* TODO check that device has endpoints we're using */ + int r; - psImg = fpi_img_new_for_imgdev( dev ); - pnData = g_malloc( SENSOR_FULL_IMAGE ); - - 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; + r = libusb_claim_interface(dev->udev, 0); + if (r < 0) { + fp_err("could not claim interface 0"); + return r; } - g_free( pnData ); - - return nRet; + dev->priv = g_malloc0(sizeof(struct upektc_dev)); + fpi_imgdev_open_complete(dev, 0); + return 0; } -static int dev_init( struct fp_img_dev *dev, unsigned long driver_data ) { - int nResult; - - nResult = libusb_claim_interface(dev->udev, 0); - if ( nResult < 0 ) { - fp_err( "could not claim interface 0" ); - return nResult; - } - - nResult = SetupSensor( dev ); - - return nResult; -} - -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 00000000..a1980184 --- /dev/null +++ b/libfprint/drivers/upektc.h @@ -0,0 +1,737 @@ +/* + * UPEK TouchChip driver for libfprint + * Copyright (C) 2012 Vasily Khoruzhick + * + * 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 From ea6d5ba6d65aa7ed4b900b23263bc4d8abe4a868 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 10 Nov 2012 18:37:41 +0300 Subject: [PATCH 30/49] lib: Fix mess with driver IDs ID is just a some magic number to make fingerprint from one scanner model incompatible with another scanner model. Get rid of "magic", declare enum and use it. https://bugs.freedesktop.org/show_bug.cgi?id=56956 --- libfprint/drivers/aes1610.c | 4 +++- libfprint/drivers/aes2501.c | 4 +++- libfprint/drivers/aes2550.c | 4 +++- libfprint/drivers/aes4000.c | 4 +++- libfprint/drivers/driver_ids.h | 39 ++++++++++++++++++++++++++++++++++ libfprint/drivers/fdu2000.c | 4 +++- libfprint/drivers/upeke2.c | 4 +++- libfprint/drivers/upeksonly.c | 4 +++- libfprint/drivers/upektc.c | 4 +++- libfprint/drivers/upekts.c | 4 +++- libfprint/drivers/uru4000.c | 4 +++- libfprint/drivers/vcom5s.c | 4 +++- libfprint/drivers/vfs101.c | 4 +++- libfprint/drivers/vfs301.c | 4 +++- 14 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 libfprint/drivers/driver_ids.h diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 20bbe695..96e87b36 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -32,6 +32,8 @@ #include #include +#include "driver_ids.h" + static void start_capture(struct fp_img_dev *dev); static void complete_deactivation(struct fp_img_dev *dev); static int adjust_gain(unsigned char *buffer, int status); @@ -935,7 +937,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver aes1610_driver = { .driver = { - .id = 6, + .id = AES1610_ID, .name = FP_COMPONENT, .full_name = "AuthenTec AES1610", .id_table = id_table, diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 1b827376..246d45e6 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -30,7 +30,9 @@ #include #include + #include "aes2501.h" +#include "driver_ids.h" static void start_capture(struct fp_img_dev *dev); static void complete_deactivation(struct fp_img_dev *dev); @@ -963,7 +965,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver aes2501_driver = { .driver = { - .id = 4, + .id = AES2501_ID, .name = FP_COMPONENT, .full_name = "AuthenTec AES2501", .id_table = id_table, diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 6d68696d..9c2eb69f 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -30,7 +30,9 @@ #include #include + #include "aes2550.h" +#include "driver_ids.h" static void start_capture(struct fp_img_dev *dev); static void complete_deactivation(struct fp_img_dev *dev); @@ -735,7 +737,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver aes2550_driver = { .driver = { - .id = 4, + .id = AES2550_ID, .name = FP_COMPONENT, .full_name = "AuthenTec AES2550/AES2810", .id_table = id_table, diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index 02dc9e8d..7fefde21 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -27,6 +27,8 @@ #include #include +#include "driver_ids.h" + #define CTRL_TIMEOUT 1000 #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) @@ -249,7 +251,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver aes4000_driver = { .driver = { - .id = 3, + .id = AES4000_ID, .name = FP_COMPONENT, .full_name = "AuthenTec AES4000", .id_table = id_table, diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h new file mode 100644 index 00000000..f5f22b09 --- /dev/null +++ b/libfprint/drivers/driver_ids.h @@ -0,0 +1,39 @@ +/* + * Driver IDs + * Copyright (C) 2012 Vasily Khoruzhick + * + * 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 __DRIVER_IDS +#define __DRIVER_IDS + +enum { + UPEKTS_ID = 1, + URU4000_ID = 2, + AES4000_ID = 3, + AES2501_ID = 4, + UPEKTC_ID = 5, + AES1610_ID = 6, + FDU2000_ID = 7, + VCOM5S_ID = 8, + UPEKSONLY_ID = 9, + VFS101_ID = 10, + VFS301_ID = 11, + AES2550_ID = 12, + UPEKE2_ID = 13, +}; + +#endif diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c index c9afb0bf..ebd71031 100644 --- a/libfprint/drivers/fdu2000.c +++ b/libfprint/drivers/fdu2000.c @@ -26,6 +26,8 @@ #define FP_COMPONENT "fdu2000" #include +#include "driver_ids.h" + #ifndef HAVE_MEMMEM gpointer memmem(const gpointer haystack, size_t haystack_len, const gpointer needle, size_t needle_len) { @@ -305,7 +307,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver fdu2000_driver = { .driver = { - .id = 7, + .id = FDU2000_ID, .name = FP_COMPONENT, .full_name = "Secugen FDU 2000", .id_table = id_table, diff --git a/libfprint/drivers/upeke2.c b/libfprint/drivers/upeke2.c index 94bc8ae4..ed8f43d1 100644 --- a/libfprint/drivers/upeke2.c +++ b/libfprint/drivers/upeke2.c @@ -37,6 +37,8 @@ #include +#include "driver_ids.h" + #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) #define TIMEOUT 5000 @@ -1456,7 +1458,7 @@ static const struct usb_id id_table[] = { }; struct fp_driver upeke2_driver = { - .id = 1, + .id = UPEKE2_ID, .name = FP_COMPONENT, .full_name = "UPEK Eikon 2", .id_table = id_table, diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 50df8ca0..84f864b4 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -30,6 +30,8 @@ #include +#include "driver_ids.h" + #define CTRL_TIMEOUT 1000 #define IMG_WIDTH 288 #define NUM_BULK_TRANSFERS 24 @@ -1267,7 +1269,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver upeksonly_driver = { .driver = { - .id = 9, + .id = UPEKSONLY_ID, .name = FP_COMPONENT, .full_name = "UPEK TouchStrip Sensor-Only", .id_table = id_table, diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index f3610516..a254a140 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -24,7 +24,9 @@ #include #include #include + #include "upektc.h" +#include "driver_ids.h" #define EP_IN (2 | LIBUSB_ENDPOINT_IN) #define EP_OUT (3 | LIBUSB_ENDPOINT_OUT) @@ -446,7 +448,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver upektc_driver = { .driver = { - .id = 5, + .id = UPEKTC_ID, .name = FP_COMPONENT, .full_name = "UPEK TouchChip", .id_table = id_table, diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index a67cd943..b347949b 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -35,6 +35,8 @@ #include +#include "driver_ids.h" + #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) #define TIMEOUT 5000 @@ -1464,7 +1466,7 @@ static const struct usb_id id_table[] = { }; struct fp_driver upekts_driver = { - .id = 1, + .id = UPEKTS_ID, .name = FP_COMPONENT, .full_name = "UPEK TouchStrip", .id_table = id_table, diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index f42b6095..eb76b928 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -30,6 +30,8 @@ #include +#include "driver_ids.h" + #define EP_INTR (1 | LIBUSB_ENDPOINT_IN) #define EP_DATA (2 | LIBUSB_ENDPOINT_IN) #define USB_RQ 0x04 @@ -1359,7 +1361,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver uru4000_driver = { .driver = { - .id = 2, + .id = URU4000_ID, .name = FP_COMPONENT, .full_name = "Digital Persona U.are.U 4000/4000B/4500", .id_table = id_table, diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 0bc5724e..4b442b23 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -34,6 +34,8 @@ #include +#include "driver_ids.h" + #define CTRL_IN 0xc0 #define CTRL_OUT 0x40 #define CTRL_TIMEOUT 1000 @@ -368,7 +370,7 @@ static const struct usb_id id_table[] = { struct fp_img_driver vcom5s_driver = { .driver = { - .id = 8, + .id = VCOM5S_ID, .name = FP_COMPONENT, .full_name = "Veridicom 5thSense", .id_table = id_table, diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index c2d9a1ca..95e654f4 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -25,6 +25,8 @@ #include +#include "driver_ids.h" + /* Input-Output usb endpoint */ #define EP_IN(n) (n | LIBUSB_ENDPOINT_IN) #define EP_OUT(n) (n | LIBUSB_ENDPOINT_OUT) @@ -1549,7 +1551,7 @@ struct fp_img_driver vfs101_driver = /* Driver specification */ .driver = { - .id = 10, + .id = VFS101_ID, .name = FP_COMPONENT, .full_name = "Validity VFS101", .id_table = id_table, diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index a27a945b..c0e36123 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -34,6 +34,8 @@ #include +#include "driver_ids.h" + /************************** GENERIC STUFF *************************************/ /* Callback of asynchronous sleep */ @@ -285,7 +287,7 @@ struct fp_img_driver vfs301_driver = /* Driver specification */ .driver = { - .id = 11, + .id = VFS301_ID, .name = FP_COMPONENT, .full_name = "Validity VFS301", .id_table = id_table, From 45ac0eefb0b19a2e37df4065dbf4efeda461edca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Fri, 16 Nov 2012 18:38:52 +0100 Subject: [PATCH 31/49] uru4000: Fix image capture error on ARM http://www.mail-archive.com/fprint@lists.freedesktop.org/msg00294.html --- libfprint/drivers/uru4000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index eb76b928..541245a2 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -689,8 +689,8 @@ static void imaging_run_state(struct fpi_ssm *ssm) fp_dbg("hw header lines %d", img->num_lines); if (img->num_lines >= IMAGE_HEIGHT || - urudev->img_transfer->actual_length != img->num_lines * IMAGE_WIDTH + 64) { - fp_err("bad captured image (%d lines) or size mismatch %d != %d", + urudev->img_transfer->actual_length < img->num_lines * IMAGE_WIDTH + 64) { + fp_err("bad captured image (%d lines) or size mismatch %d < %d", img->num_lines, urudev->img_transfer->actual_length, img->num_lines * IMAGE_WIDTH + 64); From b2a53a459cc4294dec049d8d7f1b92ebb704f983 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 16 Nov 2012 13:28:15 -0500 Subject: [PATCH 32/49] autogen.sh: Honor NOCONFIGURE=1 See http://people.gnome.org/~walters/docs/build-api.txt --- autogen.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 5499285b..e4366b30 100755 --- a/autogen.sh +++ b/autogen.sh @@ -4,5 +4,7 @@ aclocal || exit 1 autoheader || exit 1 autoconf || exit 1 automake -a -c || exit 1 -./configure --enable-maintainer-mode --enable-examples-build \ +if test -z "$NOCONFIGURE"; then + exec ./configure --enable-maintainer-mode --enable-examples-build \ --enable-x11-examples-build --enable-debug-log $* +fi From 5b20892dd43ca67071b1e113dd3b2c8c2b310168 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 22 Nov 2012 00:19:59 +0300 Subject: [PATCH 33/49] Thanks to Greg and Martin from AuthenTec https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- THANKS | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS b/THANKS index ea754c12..1286933e 100644 --- a/THANKS +++ b/THANKS @@ -8,3 +8,4 @@ Toby Howard (University of Manchester) Seemant Kulleen Pavel Herrman Bastien Nocera +Greg Kerr and Martin Konecny from AuthenTec Inc - hardware donations (AES2550 device), datasheets for AES2550 and AES2810 From 8c5f2e6434275603da6a5eb21468a43497692575 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 17 Nov 2012 15:32:25 +0300 Subject: [PATCH 34/49] aes: unify image processing code for AuthenTec devices Move overlap detection and assembling code into aeslib to prevent code duplication https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- libfprint/aeslib.c | 111 +++++++++++++++++++++++++++++ libfprint/aeslib.h | 3 + libfprint/drivers/aes1610.c | 138 +++--------------------------------- libfprint/drivers/aes2501.c | 124 +++----------------------------- libfprint/drivers/aes2550.c | 124 +++----------------------------- 5 files changed, 144 insertions(+), 356 deletions(-) diff --git a/libfprint/aeslib.c b/libfprint/aeslib.c index da9be012..0b01d316 100644 --- a/libfprint/aeslib.c +++ b/libfprint/aeslib.c @@ -20,6 +20,7 @@ #define FP_COMPONENT "aeslib" #include +#include #include #include @@ -171,3 +172,113 @@ void aes_assemble_image(unsigned char *input, size_t width, size_t height, } } +/* find overlapping parts of frames */ +static unsigned int find_overlap(unsigned char *first_frame, + unsigned char *second_frame, unsigned int *min_error, + unsigned int frame_width, unsigned int frame_height) +{ + unsigned int dy; + unsigned int not_overlapped_height = 0; + /* 255 is highest brightness value for an 8bpp image */ + *min_error = 255 * frame_width * frame_height; + for (dy = 0; dy < frame_height; dy++) { + /* Calculating difference (error) between parts of frames */ + unsigned int i; + unsigned int error = 0; + for (i = 0; i < frame_width * (frame_height - dy); i++) { + /* Using ? operator to avoid abs function */ + error += first_frame[i] > second_frame[i] ? + (first_frame[i] - second_frame[i]) : + (second_frame[i] - first_frame[i]); + } + + /* Normalize error */ + error *= 15; + error /= i; + if (error < *min_error) { + *min_error = error; + not_overlapped_height = dy; + } + first_frame += frame_width; + } + + return not_overlapped_height; +} + +/* assemble a series of frames into a single image */ +static unsigned int assemble(GSList *list_entry, size_t num_stripes, + unsigned int frame_width, unsigned int frame_height, + unsigned char *output, gboolean reverse, unsigned int *errors_sum) +{ + uint8_t *assembled = output; + int frame; + uint32_t image_height = frame_height; + unsigned int min_error, frame_size = frame_width * frame_height; + *errors_sum = 0; + + if (reverse) + output += (num_stripes - 1) * frame_size; + for (frame = 0; frame < num_stripes; frame++) { + aes_assemble_image(list_entry->data, frame_width, frame_height, output); + + if (reverse) + output -= frame_size; + else + output += frame_size; + list_entry = g_slist_next(list_entry); + } + + /* Detecting where frames overlaped */ + output = assembled; + for (frame = 1; frame < num_stripes; frame++) { + int not_overlapped; + + output += frame_size; + not_overlapped = find_overlap(assembled, output, &min_error, + frame_width, frame_height); + *errors_sum += min_error; + image_height += not_overlapped; + assembled += frame_width * not_overlapped; + memcpy(assembled, output, frame_size); + } + return image_height; +} + +struct fp_img *aes_assemble(GSList *stripes, size_t stripes_len, + unsigned int frame_width, unsigned int frame_height) +{ + size_t final_size; + struct fp_img *img; + unsigned int frame_size = frame_width * frame_height; + unsigned int errors_sum, r_errors_sum; + + BUG_ON(stripes_len == 0); + + /* create buffer big enough for max image */ + img = fpi_img_new(stripes_len * frame_size); + + img->flags = FP_IMG_COLORS_INVERTED; + img->height = assemble(stripes, stripes_len, + frame_width, frame_height, + img->data, FALSE, &errors_sum); + img->height = assemble(stripes, stripes_len, + frame_width, frame_height, + img->data, TRUE, &r_errors_sum); + + if (r_errors_sum > errors_sum) { + img->height = assemble(stripes, stripes_len, + frame_width, frame_height, + img->data, FALSE, &errors_sum); + img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; + fp_dbg("normal scan direction"); + } else { + fp_dbg("reversed scan direction"); + } + + /* now that overlap has been removed, resize output image buffer */ + final_size = img->height * frame_width; + img = fpi_img_resize(img, final_size); + img->width = frame_width; + + return img; +} diff --git a/libfprint/aeslib.h b/libfprint/aeslib.h index 3c65dae9..e366262f 100644 --- a/libfprint/aeslib.h +++ b/libfprint/aeslib.h @@ -36,5 +36,8 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs, void aes_assemble_image(unsigned char *input, size_t width, size_t height, unsigned char *output); +struct fp_img *aes_assemble(GSList *stripes, size_t stripes_len, + unsigned int frame_width, unsigned int frame_height); + #endif diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 96e87b36..c074137e 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -4,6 +4,7 @@ * Copyright (C) 2007 Cyrille Bagard * Copyright (C) 2007 Vasily Khoruzhick * Copyright (C) 2009 Guido Grazioli + * Copyright (C) 2012 Vasily Khoruzhick * * Based on code from libfprint aes2501 driver. * @@ -147,131 +148,6 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) } } -/****** IMAGE PROCESSING ******/ - -/* find overlapping parts of frames */ -static unsigned int find_overlap(unsigned char *first_frame, - unsigned char *second_frame, unsigned int *min_error) -{ - unsigned int dy; - unsigned int not_overlapped_height = 0; - *min_error = 255 * FRAME_SIZE; - for (dy = 0; dy < FRAME_HEIGHT; dy++) { - /* Calculating difference (error) between parts of frames */ - unsigned int i; - unsigned int error = 0; - for (i = 0; i < FRAME_WIDTH * (FRAME_HEIGHT - dy); i++) { - /* Using ? operator to avoid abs function */ - error += first_frame[i] > second_frame[i] ? - (first_frame[i] - second_frame[i]) : - (second_frame[i] - first_frame[i]); - } - - /* Normalize error */ - error *= 15; - error /= i; - if (error < *min_error) { - *min_error = error; - not_overlapped_height = dy; - } - first_frame += FRAME_WIDTH; - } - - return not_overlapped_height; -} - -/* assemble a series of frames into a single image */ -static unsigned int assemble(struct aes1610_dev *aesdev, unsigned char *output, - gboolean reverse, unsigned int *errors_sum) -{ - uint8_t *assembled = output; - int frame; - uint32_t image_height = FRAME_HEIGHT; - unsigned int min_error; - size_t num_strips = aesdev->strips_len; - GSList *list_entry = aesdev->strips; - *errors_sum = 0; - - if (num_strips < 1) - return 0; - - /* Rotating given data by 90 degrees - * Taken from document describing aes1610 image format - * TODO: move reversing detection here */ - - if (reverse) - output += (num_strips - 1) * FRAME_SIZE; - for (frame = 0; frame < num_strips; frame++) { - aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output); - - if (reverse) - output -= FRAME_SIZE; - else - output += FRAME_SIZE; - list_entry = g_slist_next(list_entry); - } - - /* Detecting where frames overlaped */ - output = assembled; - for (frame = 1; frame < num_strips; frame++) { - int not_overlapped; - - output += FRAME_SIZE; - not_overlapped = find_overlap(assembled, output, &min_error); - *errors_sum += min_error; - image_height += not_overlapped; - assembled += FRAME_WIDTH * not_overlapped; - memcpy(assembled, output, FRAME_SIZE); - } - return image_height; -} - -static void assemble_and_submit_image(struct fp_img_dev *dev) -{ - struct aes1610_dev *aesdev = dev->priv; - size_t final_size; - struct fp_img *img; - unsigned int errors_sum, r_errors_sum; - - fp_dbg(""); - - BUG_ON(aesdev->strips_len == 0); - - /* reverse list */ - aesdev->strips = g_slist_reverse(aesdev->strips); - - /* create buffer big enough for max image */ - img = fpi_img_new(aesdev->strips_len * FRAME_SIZE); - - img->flags = FP_IMG_COLORS_INVERTED; - img->height = assemble(aesdev, img->data, FALSE, &errors_sum); - img->height = assemble(aesdev, img->data, TRUE, &r_errors_sum); - - if (r_errors_sum > errors_sum) { - img->height = assemble(aesdev, img->data, FALSE, &errors_sum); - img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; - fp_dbg("normal scan direction"); - } else { - fp_dbg("reversed scan direction"); - } - - /* now that overlap has been removed, resize output image buffer */ - final_size = img->height * FRAME_WIDTH; - img = fpi_img_resize(img, final_size); - /* FIXME: ugly workaround */ - if (img->height < 12) - img->height = 12; - fpi_imgdev_image_captured(dev, img); - - /* free strips and strip list */ - g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); - g_slist_free(aesdev->strips); - aesdev->strips = NULL; - aesdev->strips_len = 0; - aesdev->blanks_count = 0; -} - - /****** FINGER PRESENCE DETECTION ******/ @@ -732,11 +608,19 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) /* stop capturing if MAX_FRAMES is reached */ if (aesdev->blanks_count > 10 || g_slist_length(aesdev->strips) >= MAX_FRAMES) { + struct fp_img *img; + fp_dbg("sending stop capture.... blanks=%d frames=%d", aesdev->blanks_count, g_slist_length(aesdev->strips)); /* send stop capture bits */ aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop), stub_capture_stop_cb, NULL); - /* assemble image and submit it to library */ - assemble_and_submit_image(dev); + aesdev->strips = g_slist_reverse(aesdev->strips); + img = aes_assemble(aesdev->strips, aesdev->strips_len, + FRAME_WIDTH, FRAME_HEIGHT); + g_slist_free_full(aesdev->strips, (GFunc) g_free); + aesdev->strips = NULL; + aesdev->strips_len = 0; + aesdev->blanks_count = 0; + fpi_imgdev_image_captured(dev, img); fpi_imgdev_report_finger_status(dev, FALSE); /* marking machine complete will re-trigger finger detection loop */ fpi_ssm_mark_completed(ssm); diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 246d45e6..ff03f174 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -248,119 +248,6 @@ static int sum_histogram_values(unsigned char *data, uint8_t threshold) return r; } -/* find overlapping parts of frames */ -static unsigned int find_overlap(unsigned char *first_frame, - unsigned char *second_frame, unsigned int *min_error) -{ - unsigned int dy; - unsigned int not_overlapped_height = 0; - *min_error = 255 * FRAME_SIZE; - for (dy = 0; dy < FRAME_HEIGHT; dy++) { - /* Calculating difference (error) between parts of frames */ - unsigned int i; - unsigned int error = 0; - for (i = 0; i < FRAME_WIDTH * (FRAME_HEIGHT - dy); i++) { - /* Using ? operator to avoid abs function */ - error += first_frame[i] > second_frame[i] ? - (first_frame[i] - second_frame[i]) : - (second_frame[i] - first_frame[i]); - } - - /* Normalize error */ - error *= 15; - error /= i; - if (error < *min_error) { - *min_error = error; - not_overlapped_height = dy; - } - first_frame += FRAME_WIDTH; - } - - return not_overlapped_height; -} - -/* assemble a series of frames into a single image */ -static unsigned int assemble(struct aes2501_dev *aesdev, unsigned char *output, - gboolean reverse, unsigned int *errors_sum) -{ - uint8_t *assembled = output; - int frame; - uint32_t image_height = FRAME_HEIGHT; - unsigned int min_error; - size_t num_strips = aesdev->strips_len; - GSList *list_entry = aesdev->strips; - *errors_sum = 0; - - /* Rotating given data by 90 degrees - * Taken from document describing aes2501 image format - * TODO: move reversing detection here */ - - if (reverse) - output += (num_strips - 1) * FRAME_SIZE; - for (frame = 0; frame < num_strips; frame++) { - aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output); - - if (reverse) - output -= FRAME_SIZE; - else - output += FRAME_SIZE; - list_entry = g_slist_next(list_entry); - } - - /* Detecting where frames overlaped */ - output = assembled; - for (frame = 1; frame < num_strips; frame++) { - int not_overlapped; - - output += FRAME_SIZE; - not_overlapped = find_overlap(assembled, output, &min_error); - *errors_sum += min_error; - image_height += not_overlapped; - assembled += FRAME_WIDTH * not_overlapped; - memcpy(assembled, output, FRAME_SIZE); - } - return image_height; -} - -static void assemble_and_submit_image(struct fp_img_dev *dev) -{ - struct aes2501_dev *aesdev = dev->priv; - size_t final_size; - struct fp_img *img; - unsigned int errors_sum, r_errors_sum; - - BUG_ON(aesdev->strips_len == 0); - - /* reverse list */ - aesdev->strips = g_slist_reverse(aesdev->strips); - - /* create buffer big enough for max image */ - img = fpi_img_new(aesdev->strips_len * FRAME_SIZE); - - img->flags = FP_IMG_COLORS_INVERTED; - img->height = assemble(aesdev, img->data, FALSE, &errors_sum); - img->height = assemble(aesdev, img->data, TRUE, &r_errors_sum); - - if (r_errors_sum > errors_sum) { - img->height = assemble(aesdev, img->data, FALSE, &errors_sum); - img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; - fp_dbg("normal scan direction"); - } else { - fp_dbg("reversed scan direction"); - } - - /* now that overlap has been removed, resize output image buffer */ - final_size = img->height * FRAME_WIDTH; - img = fpi_img_resize(img, final_size); - fpi_imgdev_image_captured(dev, img); - - /* free strips and strip list */ - g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); - g_slist_free(aesdev->strips); - aesdev->strips = NULL; -} - - /****** FINGER PRESENCE DETECTION ******/ static const struct aes_regwrite finger_det_reqs[] = { @@ -593,8 +480,15 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) if (sum == 0) { aesdev->no_finger_cnt++; if (aesdev->no_finger_cnt == 3) { - /* assemble image and submit it to library */ - assemble_and_submit_image(dev); + struct fp_img *img; + + aesdev->strips = g_slist_reverse(aesdev->strips); + img = aes_assemble(aesdev->strips, aesdev->strips_len, + FRAME_WIDTH, FRAME_HEIGHT); + g_slist_free_full(aesdev->strips, (GFunc) g_free); + aesdev->strips = NULL; + aesdev->strips_len = 0; + fpi_imgdev_image_captured(dev, img); fpi_imgdev_report_finger_status(dev, FALSE); /* marking machine complete will re-trigger finger detection loop */ fpi_ssm_mark_completed(ssm); diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 9c2eb69f..2ffe8529 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -64,119 +64,6 @@ struct aes2550_dev { int heartbeat_cnt; }; -/****** IMAGE PROCESSING ******/ - -/* find overlapping parts of frames */ -static unsigned int find_overlap(unsigned char *first_frame, - unsigned char *second_frame, unsigned int *min_error) -{ - unsigned int dy; - unsigned int not_overlapped_height = 0; - /* 255 is highest brightness value for an 8bpp image */ - *min_error = 255 * FRAME_SIZE; - for (dy = 0; dy < FRAME_HEIGHT; dy++) { - /* Calculating difference (error) between parts of frames */ - unsigned int i; - unsigned int error = 0; - for (i = 0; i < FRAME_WIDTH * (FRAME_HEIGHT - dy); i++) { - /* Using ? operator to avoid abs function */ - error += first_frame[i] > second_frame[i] ? - (first_frame[i] - second_frame[i]) : - (second_frame[i] - first_frame[i]); - } - - /* Normalize error */ - error *= 15; - error /= i; - if (error < *min_error) { - *min_error = error; - not_overlapped_height = dy; - } - first_frame += FRAME_WIDTH; - } - - return not_overlapped_height; -} - -/* assemble a series of frames into a single image */ -static unsigned int assemble(struct aes2550_dev *aesdev, unsigned char *output, - gboolean reverse, unsigned int *errors_sum) -{ - uint8_t *assembled = output; - int frame; - uint32_t image_height = FRAME_HEIGHT; - unsigned int min_error; - size_t num_strips = aesdev->strips_len; - GSList *list_entry = aesdev->strips; - *errors_sum = 0; - - if (reverse) - output += (num_strips - 1) * FRAME_SIZE; - for (frame = 0; frame < num_strips; frame++) { - aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output); - - if (reverse) - output -= FRAME_SIZE; - else - output += FRAME_SIZE; - list_entry = g_slist_next(list_entry); - } - - /* Detecting where frames overlaped */ - output = assembled; - for (frame = 1; frame < num_strips; frame++) { - int not_overlapped; - - output += FRAME_SIZE; - not_overlapped = find_overlap(assembled, output, &min_error); - *errors_sum += min_error; - image_height += not_overlapped; - assembled += FRAME_WIDTH * not_overlapped; - memcpy(assembled, output, FRAME_SIZE); - } - return image_height; -} - -static void assemble_and_submit_image(struct fp_img_dev *dev) -{ - struct aes2550_dev *aesdev = dev->priv; - size_t final_size; - struct fp_img *img; - unsigned int errors_sum, r_errors_sum; - - BUG_ON(aesdev->strips_len == 0); - - /* reverse list */ - aesdev->strips = g_slist_reverse(aesdev->strips); - - /* create buffer big enough for max image */ - img = fpi_img_new(aesdev->strips_len * FRAME_SIZE); - - img->flags = FP_IMG_COLORS_INVERTED; - img->height = assemble(aesdev, img->data, FALSE, &errors_sum); - img->height = assemble(aesdev, img->data, TRUE, &r_errors_sum); - - if (r_errors_sum > errors_sum) { - img->height = assemble(aesdev, img->data, FALSE, &errors_sum); - img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; - fp_dbg("normal scan direction"); - } else { - fp_dbg("reversed scan direction"); - } - - /* now that overlap has been removed, resize output image buffer */ - final_size = img->height * FRAME_WIDTH; - img = fpi_img_resize(img, final_size); - fpi_imgdev_image_captured(dev, img); - - /* free strips and strip list */ - g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); - g_slist_free(aesdev->strips); - aesdev->strips = NULL; - aesdev->strips_len = 0; -} - - /****** FINGER PRESENCE DETECTION ******/ static unsigned char finger_det_reqs[] = { @@ -356,10 +243,19 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = ssm->priv; + struct aes2550_dev *aesdev = dev->priv; if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (transfer->length == transfer->actual_length)) { - assemble_and_submit_image(dev); + struct fp_img *img; + + aesdev->strips = g_slist_reverse(aesdev->strips); + img = aes_assemble(aesdev->strips, aesdev->strips_len, + FRAME_WIDTH, FRAME_HEIGHT); + g_slist_free_full(aesdev->strips, (GFunc) g_free); + aesdev->strips = NULL; + aesdev->strips_len = 0; + fpi_imgdev_image_captured(dev, img); fpi_imgdev_report_finger_status(dev, FALSE); /* marking machine complete will re-trigger finger detection loop */ fpi_ssm_mark_completed(ssm); From bc497f1b263d6d0e7efafba1568a79b644ecc875 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 18 Nov 2012 11:30:34 +0300 Subject: [PATCH 35/49] aeslib: prevent integer overflow AuthenTec devices send 4bpp images, but current code assumes 3bpp for some reason. https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- libfprint/aeslib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/aeslib.c b/libfprint/aeslib.c index 0b01d316..00ddfd91 100644 --- a/libfprint/aeslib.c +++ b/libfprint/aeslib.c @@ -165,8 +165,8 @@ void aes_assemble_image(unsigned char *input, size_t width, size_t height, for (column = 0; column < width; column++) { for (row = 0; row < height; row += 2) { - output[width * row + column] = (*input & 0x07) * 36; - output[width * (row + 1) + column] = ((*input & 0x70) >> 4) * 36; + output[width * row + column] = (*input & 0x0f) * 17; + output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17; input++; } } From 22d204cc68a244baacb079d434fdf227addca272 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 22 Nov 2012 10:12:38 +0300 Subject: [PATCH 36/49] lib: Split fpi_im_resize factor into width/height https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- libfprint/drivers/aes4000.c | 2 +- libfprint/fp_internal.h | 2 +- libfprint/gdkpixbuf.c | 6 +++--- libfprint/imagemagick.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index 7fefde21..6ff32a27 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -155,7 +155,7 @@ static void img_cb(struct libusb_transfer *transfer) /* FIXME: this is an ugly hack to make the image big enough for NBIS * to process reliably */ - img = fpi_im_resize(tmp, ENLARGE_FACTOR); + img = fpi_im_resize(tmp, ENLARGE_FACTOR, ENLARGE_FACTOR); fp_img_free(tmp); fpi_imgdev_image_captured(dev, img); diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 7d2cf893..eaa11d4b 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -362,7 +362,7 @@ int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, struct fp_print_data *new_print); int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, struct fp_print_data **gallery, int match_threshold, size_t *match_offset); -struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int factor); +struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor); /* polling and timeouts */ diff --git a/libfprint/gdkpixbuf.c b/libfprint/gdkpixbuf.c index ea2d5bcd..4de6151c 100644 --- a/libfprint/gdkpixbuf.c +++ b/libfprint/gdkpixbuf.c @@ -22,10 +22,10 @@ #include "fp_internal.h" -struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int factor) +struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor) { - int new_width = img->width * factor; - int new_height = img->height * factor; + int new_width = img->width * w_factor; + int new_height = img->height * h_factor; GdkPixbuf *orig, *resized; struct fp_img *newimg; guchar *pixels; diff --git a/libfprint/imagemagick.c b/libfprint/imagemagick.c index ed6a1cad..68e7146f 100644 --- a/libfprint/imagemagick.c +++ b/libfprint/imagemagick.c @@ -22,14 +22,14 @@ #include "fp_internal.h" -struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int factor) +struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor) { Image *mimg; Image *resized; ExceptionInfo exception; MagickBooleanType ret; - int new_width = img->width * factor; - int new_height = img->height * factor; + int new_width = img->width * w_factor; + int new_height = img->height * h_factor; struct fp_img *newimg; /* It is possible to implement resizing using a simple algorithm, however From c1da647aedfb604704670d0a0fab4033e067e6d4 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 25 Nov 2012 20:47:01 +0300 Subject: [PATCH 37/49] lib: add AES1660/AES2660 common routines https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- configure.ac | 6 + libfprint/Makefile.am | 5 + libfprint/drivers/aesx660.c | 637 ++++++++++++++++++++++++++++++++++++ libfprint/drivers/aesx660.h | 117 +++++++ 4 files changed, 765 insertions(+) create mode 100644 libfprint/drivers/aesx660.c create mode 100644 libfprint/drivers/aesx660.h diff --git a/configure.ac b/configure.ac index 66806df4..43d19a33 100644 --- a/configure.ac +++ b/configure.ac @@ -121,6 +121,7 @@ AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"]) AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"]) +AM_CONDITIONAL([REQUIRE_AESX660], [test "$require_aesX660" = "yes"]) AM_CONDITIONAL([ENABLE_VFS101], [test "$enable_vfs101" = "yes"]) AM_CONDITIONAL([ENABLE_VFS301], [test "$enable_vfs301" = "yes"]) @@ -325,6 +326,11 @@ if test x$require_aeslib != xno ; then else AC_MSG_NOTICE([ aeslib helper functions disabled]) fi +if test x$require_aesX660 != xno ; then + AC_MSG_NOTICE([** aesX660 common routines enabled]) +else + AC_MSG_NOTICE([ aesX660 common routines disabled]) +fi AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] [examples/Makefile] [doc/Makefile]) AC_OUTPUT diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 7c5f182e..aa32357f 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -31,6 +31,7 @@ EXTRA_DIST = \ $(VFS101_SRC) \ $(VFS301_SRC) \ aeslib.c aeslib.h \ + aesx660.c aesx660.h \ imagemagick.c \ gdkpixbuf.c \ 60-fprint-autosuspend.rules @@ -158,6 +159,10 @@ if REQUIRE_AESLIB OTHER_SRC += aeslib.c aeslib.h endif +if REQUIRE_AESX660 +OTHER_SRC += drivers/aesx660.c drivers/aesx660.h +endif + libfprint_la_SOURCES = \ fp_internal.h \ async.c \ diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c new file mode 100644 index 00000000..ff4f50c5 --- /dev/null +++ b/libfprint/drivers/aesx660.c @@ -0,0 +1,637 @@ +/* + * AuthenTec AES1660/AES2660 common routines + * Copyright (C) 2007-2008 Daniel Drake + * Copyright (C) 2007 Cyrille Bagard + * Copyright (C) 2007-2008,2012 Vasily Khoruzhick + * + * Based on AES2550 driver + * + * 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 + */ + +#define FP_COMPONENT "aesX660" + +#include + +#include +#include + +#include + +#include +#include + +#include "aesx660.h" + +static void start_capture(struct fp_img_dev *dev); +static void complete_deactivation(struct fp_img_dev *dev); + +#define EP_IN (1 | LIBUSB_ENDPOINT_IN) +#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) +#define BULK_TIMEOUT 4000 +#define FRAME_HEIGHT 8 + +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +static void aesX660_send_cmd_timeout(struct fpi_ssm *ssm, const unsigned char *cmd, + size_t cmd_len, libusb_transfer_cb_fn callback, int timeout) +{ + struct fp_img_dev *dev = ssm->priv; + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + int r; + + if (!transfer) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + return; + } + + libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, + (unsigned char *)cmd, cmd_len, + callback, ssm, timeout); + r = libusb_submit_transfer(transfer); + if (r < 0) { + fp_dbg("failed to submit transfer\n"); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, -ENOMEM); + } +} + +static void aesX660_send_cmd(struct fpi_ssm *ssm, const unsigned char *cmd, + size_t cmd_len, libusb_transfer_cb_fn callback) +{ + return aesX660_send_cmd_timeout(ssm, cmd, cmd_len, callback, BULK_TIMEOUT); +} + +static void aesX660_read_response(struct fpi_ssm *ssm, size_t buf_len, + libusb_transfer_cb_fn callback) +{ + struct fp_img_dev *dev = ssm->priv; + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + unsigned char *data; + int r; + + if (!transfer) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + return; + } + + data = g_malloc(buf_len); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, + data, buf_len, + callback, ssm, BULK_TIMEOUT); + + r = libusb_submit_transfer(transfer); + if (r < 0) { + fp_dbg("Failed to submit rx transfer: %d\n", r); + g_free(data); + libusb_free_transfer(transfer); + fpi_ssm_mark_aborted(ssm, r); + } +} + +static void aesX660_send_cmd_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + fpi_ssm_next_state(ssm); + } else { + fp_dbg("tx transfer status: %d, actual_len: %.4x\n", + transfer->status, transfer->actual_length); + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +static void aesX660_read_calibrate_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + unsigned char *data = transfer->buffer; + + if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) || + (transfer->length != transfer->actual_length)) { + fpi_ssm_mark_aborted(ssm, -EIO); + goto out; + } + /* Calibrate response was read correctly? */ + if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_CALIBRATE_RESPONSE) { + fp_dbg("Bogus calibrate response: %.2x\n", data[0]); + fpi_ssm_mark_aborted(ssm, -EPROTO); + goto out; + } + + fpi_ssm_next_state(ssm); +out: + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +/****** FINGER PRESENCE DETECTION ******/ + +enum finger_det_states { + FINGER_DET_SEND_LED_CMD, + FINGER_DET_SEND_FD_CMD, + FINGER_DET_READ_FD_DATA, + FINGER_DET_SET_IDLE, + FINGER_DET_NUM_STATES, +}; + +static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + unsigned char *data = transfer->buffer; + + aesdev->fd_data_transfer = NULL; + + if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { + fp_dbg("Cancelling transfer...\n"); + fpi_ssm_next_state(ssm); + goto out; + } + + if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) || + (transfer->length != transfer->actual_length)) { + fp_dbg("Failed to read FD data\n"); + fpi_ssm_mark_aborted(ssm, -EIO); + goto out; + } + + if (data[AESX660_RESPONSE_TYPE_OFFSET] != AESX660_FINGER_DET_RESPONSE) { + fp_dbg("Bogus FD response: %.2x\n", data[0]); + fpi_ssm_mark_aborted(ssm, -EPROTO); + goto out; + } + + if (data[AESX660_FINGER_PRESENT_OFFSET] == AESX660_FINGER_PRESENT || aesdev->deactivating) { + /* Finger present or we're deactivating... */ + fpi_ssm_next_state(ssm); + } else { + fp_dbg("Wait for finger returned %.2x as result\n", + data[AESX660_FINGER_PRESENT_OFFSET]); + fpi_ssm_jump_to_state(ssm, FINGER_DET_SEND_FD_CMD); + } +out: + g_free(data); + libusb_free_transfer(transfer); +} + +static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + fpi_ssm_mark_completed(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +static void finger_det_sm_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + int err = ssm->error; + + fp_dbg("Finger detection completed"); + fpi_imgdev_report_finger_status(dev, TRUE); + fpi_ssm_free(ssm); + + if (aesdev->deactivating) + complete_deactivation(dev); + else if (err) + fpi_imgdev_session_error(dev, err); + else { + fpi_imgdev_report_finger_status(dev, TRUE); + start_capture(dev); + } +} + +static void finger_det_run_state(struct fpi_ssm *ssm) +{ + switch (ssm->cur_state) { + case FINGER_DET_SEND_LED_CMD: + aesX660_send_cmd(ssm, led_blink_cmd, sizeof(led_blink_cmd), + aesX660_send_cmd_cb); + break; + case FINGER_DET_SEND_FD_CMD: + aesX660_send_cmd_timeout(ssm, wait_for_finger_cmd, sizeof(wait_for_finger_cmd), + aesX660_send_cmd_cb, 0); + break; + case FINGER_DET_READ_FD_DATA: + /* Should return 4 byte of response */ + aesX660_read_response(ssm, 4, finger_det_read_fd_data_cb); + break; + case FINGER_DET_SET_IDLE: + aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd), + finger_det_set_idle_cmd_cb); + break; + } +} + +static void start_finger_detection(struct fp_img_dev *dev) +{ + struct fpi_ssm *ssm; + struct aesX660_dev *aesdev = dev->priv; + + if (aesdev->deactivating) { + complete_deactivation(dev); + return; + } + + ssm = fpi_ssm_new(dev->dev, finger_det_run_state, FINGER_DET_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, finger_det_sm_complete); +} + +/****** CAPTURE ******/ + +enum capture_states { + CAPTURE_SEND_LED_CMD, + CAPTURE_SEND_CAPTURE_CMD, + CAPTURE_READ_STRIPE_DATA, + CAPTURE_SET_IDLE, + CAPTURE_NUM_STATES, +}; + +/* Returns number of processed bytes */ +static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) +{ + unsigned char *stripdata; + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + + stripdata = g_malloc(aesdev->frame_width * FRAME_HEIGHT / 2); /* 4 bits per pixel */ + if (!stripdata) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + return 1; + } + + fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET], + data[AESX660_LAST_FRAME_OFFSET]); + + if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) { + memcpy(stripdata, data + AESX660_IMAGE_OFFSET, aesdev->frame_width * FRAME_HEIGHT / 2); + + aesdev->strips = g_slist_prepend(aesdev->strips, stripdata); + aesdev->strips_len++; + return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT); + } else { + return 0; + } + +} + +static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + struct fp_img *img, *tmp; + + aesdev->strips = g_slist_reverse(aesdev->strips); + tmp = aes_assemble(aesdev->strips, aesdev->strips_len, + aesdev->frame_width, FRAME_HEIGHT); + g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); + g_slist_free(aesdev->strips); + aesdev->strips = NULL; + aesdev->strips_len = 0; + if (aesdev->h_scale_factor > 1) { + img = fpi_im_resize(tmp, aesdev->h_scale_factor, 1); + fp_img_free(tmp); + } else { + img = tmp; + tmp = NULL; + } + fpi_imgdev_image_captured(dev, img); + fpi_imgdev_report_finger_status(dev, FALSE); + fpi_ssm_mark_completed(ssm); + } else { + fpi_ssm_mark_aborted(ssm, -EIO); + } + libusb_free_transfer(transfer); +} + +static void capture_read_stripe_data_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + unsigned char *data = transfer->buffer; + int finger_missing = 0; + size_t copied, actual_len = transfer->actual_length; + + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + fpi_ssm_mark_aborted(ssm, -EIO); + goto out; + } + + fp_dbg("Got %d bytes of data", actual_len); + do { + copied = min(aesdev->buffer_max - aesdev->buffer_size, actual_len); + memcpy(aesdev->buffer + aesdev->buffer_size, + data, + copied); + actual_len -= copied; + data += copied; + aesdev->buffer_size += copied; + fp_dbg("Copied %.4x bytes into internal buffer", + copied); + if (aesdev->buffer_size == aesdev->buffer_max) { + if (aesdev->buffer_max == AESX660_HEADER_SIZE) { + aesdev->buffer_max = aesdev->buffer[AESX660_RESPONSE_SIZE_LSB_OFFSET] + + (aesdev->buffer[AESX660_RESPONSE_SIZE_MSB_OFFSEt] << 8) + AESX660_HEADER_SIZE; + fp_dbg("Got frame, type %.2x size %.4x", + aesdev->buffer[AESX660_RESPONSE_TYPE_OFFSET], + aesdev->buffer_max); + continue; + } else { + finger_missing |= process_stripe_data(ssm, aesdev->buffer); + aesdev->buffer_max = AESX660_HEADER_SIZE; + aesdev->buffer_size = 0; + } + } + } while (actual_len); + + fp_dbg("finger %s\n", finger_missing ? "missing" : "present"); + + if (finger_missing) { + fpi_ssm_next_state(ssm); + } else { + fpi_ssm_jump_to_state(ssm, CAPTURE_READ_STRIPE_DATA); + } +out: + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +static void capture_run_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + + switch (ssm->cur_state) { + case CAPTURE_SEND_LED_CMD: + aesX660_send_cmd(ssm, led_solid_cmd, sizeof(led_solid_cmd), + aesX660_send_cmd_cb); + break; + case CAPTURE_SEND_CAPTURE_CMD: + aesdev->buffer_size = 0; + aesdev->buffer_max = AESX660_HEADER_SIZE; + aesX660_send_cmd(ssm, aesdev->start_imaging_cmd, + aesdev->start_imaging_cmd_len, + aesX660_send_cmd_cb); + break; + case CAPTURE_READ_STRIPE_DATA: + aesX660_read_response(ssm, AESX660_BULK_TRANSFER_SIZE, + capture_read_stripe_data_cb); + break; + case CAPTURE_SET_IDLE: + fp_dbg("Got %d frames\n", aesdev->strips_len); + aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd), + capture_set_idle_cmd_cb); + break; + } +} + +static void capture_sm_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + int err = ssm->error; + + fp_dbg("Capture completed"); + fpi_ssm_free(ssm); + + if (aesdev->deactivating) + complete_deactivation(dev); + else if (err) + fpi_imgdev_session_error(dev, err); + else + start_finger_detection(dev); +} + +static void start_capture(struct fp_img_dev *dev) +{ + struct aesX660_dev *aesdev = dev->priv; + struct fpi_ssm *ssm; + + if (aesdev->deactivating) { + complete_deactivation(dev); + return; + } + + ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + fp_dbg(""); + ssm->priv = dev; + fpi_ssm_start(ssm, capture_sm_complete); +} + +/****** INITIALIZATION/DEINITIALIZATION ******/ + +enum activate_states { + ACTIVATE_SET_IDLE, + ACTIVATE_SEND_READ_ID_CMD, + ACTIVATE_READ_ID, + ACTIVATE_SEND_CALIBRATE_CMD, + ACTIVATE_READ_CALIBRATE_DATA, + ACTIVATE_SEND_INIT_CMD, + ACTIVATE_READ_INIT_RESPONSE, + ACTIVATE_NUM_STATES, +}; + +static void activate_read_id_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + unsigned char *data = transfer->buffer; + + if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) || + (transfer->length != transfer->actual_length)) { + fp_dbg("read_id cmd failed\n"); + fpi_ssm_mark_aborted(ssm, -EIO); + goto out; + } + /* ID was read correctly */ + if (data[0] == 0x07) { + fp_dbg("Sensor device id: %.2x%2x, bcdDevice: %.2x.%.2x, init status: %.2x\n", + data[4], data[3], data[5], data[6], data[7]); + } else { + fp_dbg("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]); + fpi_ssm_mark_aborted(ssm, -EPROTO); + goto out; + } + + switch (aesdev->init_seq_idx) { + case 0: + aesdev->init_seq = aesdev->init_seqs[0]; + aesdev->init_seq_len = aesdev->init_seqs_len[0]; + aesdev->init_seq_idx = 1; + aesdev->init_cmd_idx = 0; + /* Do calibration only after 1st init sequence */ + fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_INIT_CMD); + break; + case 1: + aesdev->init_seq = aesdev->init_seqs[1]; + aesdev->init_seq_len = aesdev->init_seqs_len[1]; + aesdev->init_seq_idx = 2; + aesdev->init_cmd_idx = 0; + fpi_ssm_next_state(ssm); + break; + default: + fp_dbg("Failed to init device! init status: %.2x\n", data[7]); + fpi_ssm_mark_aborted(ssm, -EPROTO); + break; + + } + +out: + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +static void activate_read_init_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + unsigned char *data = transfer->buffer; + + fp_dbg("read_init_cb\n"); + + if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) || + (transfer->length != transfer->actual_length)) { + fp_dbg("read_init transfer status: %d, actual_len: %d\n", transfer->status, transfer->actual_length); + fpi_ssm_mark_aborted(ssm, -EIO); + goto out; + } + /* ID was read correctly */ + if (data[0] != 0x42 || data[3] != 0x01) { + fp_dbg("Bogus read init response: %.2x %.2x\n", data[0], + data[3]); + fpi_ssm_mark_aborted(ssm, -EPROTO); + goto out; + } + aesdev->init_cmd_idx++; + if (aesdev->init_cmd_idx == aesdev->init_seq_len) { + if (aesdev->init_seq_idx < 2) + fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_READ_ID_CMD); + else + fpi_ssm_mark_completed(ssm); + goto out; + } + + fpi_ssm_jump_to_state(ssm, ACTIVATE_SEND_INIT_CMD); +out: + g_free(transfer->buffer); + libusb_free_transfer(transfer); +} + +static void activate_run_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct aesX660_dev *aesdev = dev->priv; + + switch (ssm->cur_state) { + case ACTIVATE_SET_IDLE: + aesdev->init_seq_idx = 0; + fp_dbg("Activate: set idle\n"); + aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd), + aesX660_send_cmd_cb); + break; + case ACTIVATE_SEND_READ_ID_CMD: + fp_dbg("Activate: read ID\n"); + aesX660_send_cmd(ssm, read_id_cmd, sizeof(read_id_cmd), + aesX660_send_cmd_cb); + break; + case ACTIVATE_READ_ID: + /* Should return 8-byte response */ + aesX660_read_response(ssm, 8, activate_read_id_cb); + break; + case ACTIVATE_SEND_INIT_CMD: + fp_dbg("Activate: send init seq #%d cmd #%d\n", + aesdev->init_seq_idx, + aesdev->init_cmd_idx); + aesX660_send_cmd(ssm, + aesdev->init_seq[aesdev->init_cmd_idx].cmd, + aesdev->init_seq[aesdev->init_cmd_idx].len, + aesX660_send_cmd_cb); + break; + case ACTIVATE_READ_INIT_RESPONSE: + fp_dbg("Activate: read init response\n"); + /* Should return 4-byte response */ + aesX660_read_response(ssm, 4, activate_read_init_cb); + break; + case ACTIVATE_SEND_CALIBRATE_CMD: + aesX660_send_cmd(ssm, calibrate_cmd, sizeof(calibrate_cmd), + aesX660_send_cmd_cb); + break; + case ACTIVATE_READ_CALIBRATE_DATA: + /* Should return 4-byte response */ + aesX660_read_response(ssm, 4, aesX660_read_calibrate_data_cb); + break; + } +} + +static void activate_sm_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + int err = ssm->error; + fp_dbg("status %d", err); + fpi_imgdev_activate_complete(dev, err); + fpi_ssm_free(ssm); + + if (!err) + start_finger_detection(dev); +} + +int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +{ + struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + ACTIVATE_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, activate_sm_complete); + return 0; +} + +void aesX660_dev_deactivate(struct fp_img_dev *dev) +{ + struct aesX660_dev *aesdev = dev->priv; + + if (aesdev->fd_data_transfer) + libusb_cancel_transfer(aesdev->fd_data_transfer); + + aesdev->deactivating = TRUE; +} + +static void complete_deactivation(struct fp_img_dev *dev) +{ + struct aesX660_dev *aesdev = dev->priv; + fp_dbg(""); + + aesdev->deactivating = FALSE; + g_slist_free(aesdev->strips); + aesdev->strips = NULL; + aesdev->strips_len = 0; + fpi_imgdev_deactivate_complete(dev); +} diff --git a/libfprint/drivers/aesx660.h b/libfprint/drivers/aesx660.h new file mode 100644 index 00000000..b53ad51b --- /dev/null +++ b/libfprint/drivers/aesx660.h @@ -0,0 +1,117 @@ +/* + * AuthenTec AES1660/AES2660 common definitions + * Copyright (c) 2012 Vasily Khoruzhick + * + * 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 __AESX660_H +#define __AESX660_H + +#define AESX660_HEADER_SIZE 3 +#define AESX660_RESPONSE_TYPE_OFFSET 0x00 +#define AESX660_RESPONSE_SIZE_LSB_OFFSET 0x01 +#define AESX660_RESPONSE_SIZE_MSB_OFFSEt 0x02 + +#define AESX660_CALIBRATE_RESPONSE 0x06 +#define AESX660_FINGER_DET_RESPONSE 0x40 +#define AESX660_FINGER_PRESENT_OFFSET 0x03 +#define AESX660_FINGER_PRESENT 0x01 + +#define AESX660_IMAGE_OK_OFFSET 0x03 +#define AESX660_IMAGE_OK 0x0d +#define AESX660_LAST_FRAME_OFFSET 0x04 +#define AESX660_LAST_FRAME_BIT 0x01 + +#define AESX660_IMAGE_OFFSET 43 +#define AESX660_BULK_TRANSFER_SIZE 4096 + +struct aesX660_dev { + GSList *strips; + size_t strips_len; + gboolean deactivating; + struct aesX660_cmd *init_seq; + size_t init_seq_len; + unsigned int init_cmd_idx; + unsigned int init_seq_idx; + struct libusb_transfer *fd_data_transfer; + unsigned char *buffer; + size_t buffer_size; + size_t buffer_max; + + /* Device-specific stuff */ + int h_scale_factor; + struct aesX660_cmd *init_seqs[2]; + size_t init_seqs_len[2]; + unsigned char *start_imaging_cmd; + size_t start_imaging_cmd_len; + unsigned int frame_width; +}; + +struct aesX660_cmd { + const unsigned char *cmd; + size_t len; +}; + +/* 0x77 cmd seems to control LED, this sequence + * makes LED blink + */ +static const unsigned char led_blink_cmd[] = { +0x77, 0x18, 0x00, +0x00, 0x3f, 0x00, 0xff, 0x00, +0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00, +0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xf3, +0x01, 0x00, 0x7f +}; + +/* This sequence makes LED light solid + */ +static const unsigned char led_solid_cmd[] = { +0x77, 0x18, 0x00, 0x00, 0x3f, 0x00, 0xff, 0x00, +0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00, +0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7f +}; + +static const unsigned char wait_for_finger_cmd[] = { +0x20, +0x40, 0x04, 0x00, 0x02, 0x1e, 0x00, 0x32 +}; + +/* 0x40 cmd response + * +static const unsigned char pkt1371[] = { +0x40, 0x01, 0x00, 0x01 +}; +*/ + +static const unsigned char set_idle_cmd[] = { + 0x0d, /* Reset or "set idle"? */ +}; + +static const unsigned char read_id_cmd[] = { + 0x44, 0x02, 0x00, 0x08, 0x00, /* Max transfer size is 8 */ + 0x07, /* Read ID? */ +}; + +static const unsigned char calibrate_cmd[] = { + 0x44, 0x02, 0x00, 0x04, 0x00, + 0x06, +}; + +int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state); +void aesX660_dev_deactivate(struct fp_img_dev *dev); + +#endif From 313bfede7781540dfad831a520a5ffa254945533 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 25 Nov 2012 20:50:11 +0300 Subject: [PATCH 38/49] lib: add AES1660 driver https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- configure.ac | 15 +- libfprint/Makefile.am | 6 + libfprint/core.c | 3 + libfprint/drivers/aes1660.c | 126 ++ libfprint/drivers/aes1660.h | 1990 ++++++++++++++++++++++++++++++++ libfprint/drivers/driver_ids.h | 1 + libfprint/fp_internal.h | 3 + 7 files changed, 2143 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/aes1660.c create mode 100644 libfprint/drivers/aes1660.h diff --git a/configure.ac b/configure.ac index 43d19a33..fdcbd8d7 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) AC_SUBST(lt_age) -all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes2550 aes4000 vfs101 vfs301" +all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes4000 vfs101 vfs301" require_imaging='no' require_aeslib='no' @@ -35,6 +35,7 @@ enable_vcom5s='no' enable_uru4000='no' enable_fdu2000='no' enable_aes1610='no' +enable_aes1660='no' enable_aes2501='no' enable_aes2550='no' enable_aes4000='no' @@ -92,6 +93,12 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do require_aeslib="yes" enable_aes1610="yes" ;; + aes1660) + AC_DEFINE([ENABLE_AES1660], [], [Build AuthenTec AES1660 driver]) + require_aeslib="yes" + require_aesX660="yes" + enable_aes1660="yes" + ;; aes4000) AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver]) require_aeslib="yes" @@ -117,6 +124,7 @@ AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" = "yes"]) AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" = "yes"]) AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" = "yes"]) AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" = "yes"]) +AM_CONDITIONAL([ENABLE_AES1660], [test "$enable_aes1660" = "yes"]) AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"]) AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) @@ -296,6 +304,11 @@ if test x$enable_aes1610 != xno ; then else AC_MSG_NOTICE([ aes1610 driver disabled]) fi +if test x$enable_aes1660 != xno ; then + AC_MSG_NOTICE([** aes1660 driver enabled]) +else + AC_MSG_NOTICE([ aes1660 driver disabled]) +fi if test x$enable_aes2501 != xno ; then AC_MSG_NOTICE([** aes2501 driver enabled]) else diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index aa32357f..ea495ebe 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -8,6 +8,7 @@ UPEKTC_SRC = drivers/upektc.c UPEKSONLY_SRC = drivers/upeksonly.c URU4000_SRC = drivers/uru4000.c AES1610_SRC = drivers/aes1610.c +AES1660_SRC = drivers/aes1660.c drivers/aes1660.h AES2501_SRC = drivers/aes2501.c drivers/aes2501.h AES2550_SRC = drivers/aes2550.c drivers/aes2550.h AES4000_SRC = drivers/aes4000.c @@ -23,6 +24,7 @@ EXTRA_DIST = \ $(UPEKSONLY_SRC) \ $(URU4000_SRC) \ $(AES1610_SRC) \ + $(AES1660_SRC) \ $(AES2501_SRC) \ $(AES2550_SRC) \ $(AES4000_SRC) \ @@ -123,6 +125,10 @@ if ENABLE_AES1610 DRIVER_SRC += $(AES1610_SRC) endif +if ENABLE_AES1660 +DRIVER_SRC += $(AES1660_SRC) +endif + if ENABLE_AES2501 DRIVER_SRC += $(AES2501_SRC) endif diff --git a/libfprint/core.c b/libfprint/core.c index 01a9cfa6..ddab4aa3 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -371,6 +371,9 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_AES1610 &aes1610_driver, #endif +#ifdef ENABLE_AES1660 + &aes1660_driver, +#endif #ifdef ENABLE_VFS101 &vfs101_driver, #endif diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c new file mode 100644 index 00000000..e647ea56 --- /dev/null +++ b/libfprint/drivers/aes1660.c @@ -0,0 +1,126 @@ +/* + * AuthenTec AES1660 driver for libfprint + * Copyright (C) 2012 Vasily Khoruzhick + * + * 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 + */ + +#define FP_COMPONENT "aes1660" + +#include + +#include +#include + +#include + +#include + +#include "aesx660.h" +#include "aes1660.h" +#include "driver_ids.h" + +#define FRAME_WIDTH 128 +#define SCALE_FACTOR 2 + +static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) +{ + /* TODO check that device has endpoints we're using */ + int r; + struct aesX660_dev *aesdev; + + r = libusb_claim_interface(dev->udev, 0); + if (r < 0) { + fp_err("could not claim interface 0"); + return r; + } + + dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev)); + if (!aesdev) + return -ENOMEM; + + aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE); + if (!aesdev->buffer) { + g_free(aesdev); + dev->priv = NULL; + return -ENOMEM; + } + + aesdev->h_scale_factor = SCALE_FACTOR; + aesdev->init_seqs[0] = aes1660_init_1; + aesdev->init_seqs_len[0] = array_n_elements(aes1660_init_1); + aesdev->init_seqs[1] = aes1660_init_2; + aesdev->init_seqs_len[1] = array_n_elements(aes1660_init_2); + aesdev->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd; + aesdev->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd); + aesdev->frame_width = FRAME_WIDTH; + + fpi_imgdev_open_complete(dev, 0); + return 0; +} + +static void dev_deinit(struct fp_img_dev *dev) +{ + struct aesX660_dev *aesdev = dev->priv; + g_free(aesdev->buffer); + g_free(aesdev); + libusb_release_interface(dev->udev, 0); + fpi_imgdev_close_complete(dev); +} + +static const struct usb_id id_table[] = { + { .vendor = 0x08ff, .product = 0x1660 }, + { .vendor = 0x08ff, .product = 0x1680 }, + { .vendor = 0x08ff, .product = 0x1681 }, + { .vendor = 0x08ff, .product = 0x1682 }, + { .vendor = 0x08ff, .product = 0x1683 }, + { .vendor = 0x08ff, .product = 0x1684 }, + { .vendor = 0x08ff, .product = 0x1685 }, + { .vendor = 0x08ff, .product = 0x1686 }, + { .vendor = 0x08ff, .product = 0x1687 }, + { .vendor = 0x08ff, .product = 0x1688 }, + { .vendor = 0x08ff, .product = 0x1689 }, + { .vendor = 0x08ff, .product = 0x168a }, + { .vendor = 0x08ff, .product = 0x168b }, + { .vendor = 0x08ff, .product = 0x168c }, + { .vendor = 0x08ff, .product = 0x168d }, + { .vendor = 0x08ff, .product = 0x168e }, + { .vendor = 0x08ff, .product = 0x168f }, + { 0, 0, 0, }, +}; + +struct fp_img_driver aes1660_driver = { + .driver = { + .id = AES1660_ID, + .name = FP_COMPONENT, + .full_name = "AuthenTec AES1660", + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + .flags = 0, + .img_height = -1, + .img_width = FRAME_WIDTH * SCALE_FACTOR, + + /* temporarily lowered until we sort out image processing code + * binarized scan quality is good, minutiae detection is accurate, + * it's just that we get fewer minutiae than other scanners (less scanning + * area) */ + .bz3_threshold = 25, + + .open = dev_init, + .close = dev_deinit, + .activate = aesX660_dev_activate, + .deactivate = aesX660_dev_deactivate, +}; diff --git a/libfprint/drivers/aes1660.h b/libfprint/drivers/aes1660.h new file mode 100644 index 00000000..ccfb0bce --- /dev/null +++ b/libfprint/drivers/aes1660.h @@ -0,0 +1,1990 @@ +/* + * AuthenTec AES1660 driver for libfprint + * Copyright (c) 2012 Vasily Khoruzhick + * Based on USB logs from Andreas Loos + * + * 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 __AES1660_H +#define __AES1660_H + +#define AES1660_FRAME_SIZE 0x244 + +/* First init sequence, 0x07 cmd returns following before INIT1: + * { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x00 } + */ + +/* INIT1 */ +static const unsigned char pkt107[] = { +0x44, 0x02, 0x00, 0x04, 0x00, +0x0d, 0x23, +0x42, 0xca, 0x00, +0x00, 0x20, 0x23, +0xff, 0x3f, 0x1d, 0xc1, 0x2e, 0xa3, 0xbf, 0xc2, +0x2e, 0x00, 0xdf, 0xff, 0x2d, 0x02, 0x5a, 0xbf, +0x22, 0xc1, 0x2e, 0xa3, 0xbf, 0x02, 0xcf, 0x0f, +0x1c, 0x10, 0x18, 0x26, 0x83, 0xc8, 0x46, 0x00, +0x5b, 0x01, 0x0c, 0xa2, 0x32, 0xa8, 0xcf, 0xf1, +0x1c, 0x0c, 0x18, 0xa8, 0xaf, 0xaf, 0x31, 0x0a, +0x3a, 0x5d, 0xcf, 0x30, 0x1c, 0x05, 0x55, 0x5d, +0x41, 0x03, 0x5b, 0x5d, 0xcf, 0xfc, 0x1c, 0x01, +0x18, 0x5d, 0xaf, 0x02, 0x43, 0x00, 0x2e, 0x09, +0x5a, 0x0c, 0xef, 0x56, 0xaf, 0x2e, 0x23, 0x02, +0x2e, 0x0b, 0x87, 0x83, 0x23, 0x84, 0x23, 0x81, +0x23, 0x82, 0x23, 0x24, 0x23, 0x0a, 0xef, 0xbf, +0x22, 0x00, 0x2e, 0xa9, 0x8b, 0x57, 0x23, 0x3c, +0x23, 0xf9, 0x34, 0x6b, 0x81, 0x64, 0xef, 0x64, +0xaf, 0x09, 0x88, 0xdf, 0xef, 0x27, 0xff, 0xd6, +0xaf, 0xd7, 0xbf, 0x46, 0xef, 0x46, 0xaf, 0x2a, +0xef, 0x2a, 0xaf, 0x05, 0x81, 0x05, 0x27, 0x10, +0xef, 0x99, 0xaf, 0x9b, 0xaf, 0x04, 0xaf, 0x3d, +0x23, 0x44, 0xef, 0x20, 0xff, 0x1a, 0x27, 0x05, +0xef, 0x27, 0xff, 0x06, 0x27, 0x05, 0x27, 0x9c, +0xcf, 0xdf, 0x96, 0xfe, 0xef, 0x27, 0xff, 0x19, +0x27, 0x65, 0xdf, 0xe1, 0x22, 0x1c, 0x55, 0xe0, +0x97, 0xbf, 0x03, 0x19, 0x5e, 0xfe, 0x0c, 0x9f, +0x22, 0x0f, 0xff, 0xe1, 0x22, 0x10, 0x55, 0x20, +0x00, 0x0e, 0x52, 0x82, 0x03, 0x03, 0x53 +}; + +static const unsigned char pkt112[] = { +0x42, 0xca, 0x00, +0x64, 0x20, 0xfe, 0x0d, 0x7f, +0x20, 0xf6, 0x55, 0x08, 0x50, 0x5f, 0x90, 0x82, +0x01, 0x1f, 0x90, 0xc1, 0x97, 0xa0, 0x01, 0x82, +0x01, 0xdf, 0x21, 0x80, 0x03, 0x00, 0x5e, 0x3f, +0x20, 0x29, 0xbf, 0x03, 0x0c, 0x05, 0x27, 0x01, +0x0c, 0x10, 0xff, 0x29, 0xbf, 0x05, 0x27, 0x9a, +0xcf, 0xdf, 0x96, 0xe0, 0xef, 0x27, 0xff, 0x19, +0x27, 0xfe, 0x0c, 0x9f, 0x22, 0x00, 0xff, 0xe1, +0x22, 0x10, 0x55, 0x20, 0x00, 0x0e, 0x52, 0x82, +0x03, 0x03, 0x53, 0x02, 0x0d, 0x3f, 0x20, 0x0f, +0x1f, 0xf5, 0x55, 0x5f, 0x90, 0x82, 0x01, 0x1f, +0x90, 0xc1, 0x97, 0xa0, 0x01, 0x82, 0x01, 0xdf, +0x21, 0x80, 0x03, 0x02, 0x5e, 0x7f, 0x20, 0x00, +0x53, 0xbf, 0x22, 0x29, 0xcf, 0xbf, 0x03, 0x01, +0x5e, 0x5f, 0x20, 0xdf, 0x9f, 0x28, 0xbf, 0x03, +0x0c, 0x05, 0x27, 0x24, 0xcf, 0x10, 0xdf, 0xbf, +0x01, 0x06, 0x1e, 0xe1, 0x2f, 0xe6, 0x5c, 0xdf, +0x2d, 0x00, 0x5b, 0x9f, 0x22, 0xdf, 0x96, 0xc8, +0xef, 0x20, 0xff, 0x1d, 0x00, 0x00, 0x13, 0x1a, +0x27, 0x07, 0x27, 0x9b, 0x22, 0xdf, 0x96, 0xbb, +0xcf, 0x1a, 0x88, 0xbb, 0xcf, 0x1b, 0x88, 0x01, +0x0f, 0xbc, 0xcf, 0x15, 0x88, 0xbc, 0xcf, 0x16, +0x88, 0x01, 0x0f, 0xbd, 0xcf, 0x10, 0x88, 0xbd, +0xcf, 0x11, 0x88, 0x01, 0x0f, 0xbe, 0xcf, 0x0b, +0x88, 0xbe, 0xcf, 0x0c, 0x88, 0x01, 0x0c, 0xdd, +0x97, 0x25, 0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt116[] = { +0x42, 0xca, 0x00, +0xc8, 0x20, 0xff, 0x00, 0xab, +0x00, 0x72, 0x00, 0x4c, 0x00, 0x33, 0x00, 0x22, +0x00, 0x09, 0x88, 0xbf, 0x9d, 0x05, 0x27, 0x09, +0x27, 0x05, 0x88, 0xff, 0x97, 0x09, 0x27, 0xf6, +0x9f, 0x5f, 0x02, 0xbf, 0x9d, 0x05, 0x27, 0x0f, +0x1c, 0xc0, 0x9f, 0x8a, 0x80, 0x80, 0x10, 0x00, +0x13, 0x0f, 0x1d, 0xc1, 0x03, 0x00, 0x5f, 0x7f, +0x90, 0x05, 0x27, 0x53, 0x80, 0x2b, 0x0d, 0x05, +0x27, 0x9f, 0x22, 0x8f, 0xaf, 0x67, 0x2e, 0xe0, +0xdf, 0x04, 0x1e, 0x00, 0x52, 0x8f, 0x30, 0x67, +0x2e, 0xe1, 0xdf, 0xdf, 0x22, 0x00, 0x54, 0x8f, +0x30, 0x67, 0x2e, 0xfe, 0xdf, 0x04, 0x1e, 0x00, +0x52, 0x8f, 0x31, 0x67, 0x2e, 0xff, 0xdf, 0xdf, +0x22, 0x00, 0x54, 0x8f, 0x31, 0x8f, 0xcf, 0x03, +0x1c, 0x03, 0x1e, 0x00, 0x55, 0x0c, 0x27, 0x0d, +0x27, 0x4a, 0xcf, 0xdf, 0x96, 0x10, 0xcf, 0x5f, +0xdf, 0xbf, 0x03, 0x02, 0x5f, 0x5f, 0xcf, 0x10, +0xaf, 0x04, 0x50, 0x5e, 0xdf, 0xbf, 0x03, 0x01, +0x53, 0x5e, 0xcf, 0x10, 0xaf, 0x46, 0x88, 0x01, +0x2e, 0x1e, 0x80, 0xdd, 0x97, 0x0a, 0x40, 0x1c, +0x5a, 0x37, 0x43, 0x0b, 0x5b, 0xe2, 0xcf, 0x0f, +0x1c, 0x06, 0x1e, 0x07, 0x52, 0x62, 0xdf, 0x18, +0x1f, 0x07, 0x53, 0x04, 0x16, 0xe2, 0xaf, 0x04, +0x11, 0x62, 0xbf, 0x02, 0x50, 0x62, 0xcf, 0xdf, +0x22, 0x0e, 0x54, 0x0e, 0x88, 0x62, 0xdf, 0xbf, +0x03, 0x04, 0x53, 0x62, 0xaf +}; + +static const unsigned char pkt120[] = { +0x42, 0xca, 0x00, +0x2c, 0x21, 0xdf, 0x01, 0xe2, +0xcf, 0x3f, 0x00, 0xe2, 0xaf, 0x0e, 0x88, 0x4a, +0xdf, 0x3f, 0x00, 0x4a, 0xaf, 0x00, 0x2e, 0xc4, +0x8d, 0x05, 0x27, 0xff, 0xef, 0x4a, 0xdf, 0xbf, +0x01, 0x0a, 0x88, 0xa1, 0x27, 0x5f, 0x21, 0x7f, +0x20, 0xfb, 0x55, 0x05, 0x27, 0x62, 0xcf, 0x03, +0x88, 0x1f, 0x22, 0x7f, 0x20, 0xfc, 0x55, 0x05, +0x27, 0x10, 0xdf, 0x02, 0x1f, 0x02, 0x5e, 0x04, +0xff, 0x00, 0x2e, 0x0a, 0x50, 0x05, 0x1f, 0x02, +0x5e, 0x03, 0xff, 0x00, 0x2e, 0x05, 0x50, 0x06, +0x1f, 0x02, 0x5e, 0x02, 0xff, 0x00, 0x2e, 0x00, +0x50, 0x01, 0xff, 0x05, 0x27, 0x10, 0xcf, 0x60, +0xff, 0x3f, 0x00, 0x21, 0xff, 0x00, 0x13, 0x1a, +0x27, 0x07, 0x27, 0x05, 0x27, 0x01, 0x00, 0x02, +0x57, 0x42, 0x87, 0x52, 0x80, 0x92, 0x81, 0xd2, +0x6c, 0xe2, 0x80, 0xf2, 0x80, 0xf6, 0x7b, 0xfa, +0x7e, 0xfe, 0x8b, 0xf9, 0x45, 0x04, 0x5a, 0x40, +0xef, 0xf9, 0x44, 0x03, 0x5b, 0x80, 0xef, 0x01, +0x50, 0x41, 0x2e, 0x7e, 0xdf, 0x4d, 0xaf, 0x05, +0x27, 0x28, 0xff, 0x54, 0xef, 0x19, 0x27, 0x4d, +0x26, 0xe0, 0x2f, 0xfb, 0x54, 0x27, 0xff, 0xe0, +0xef, 0x1b, 0x27, 0x10, 0xef, 0x06, 0xaf, 0xfc, +0x97, 0xfc, 0x9f, 0x1c, 0x82, 0x1c, 0x82, 0x1a, +0x27, 0x4d, 0xdf, 0x6d, 0x80, 0x5f, 0x9f, 0x06, +0x25, 0xf5, 0x55, 0x05, 0x27, 0x26, 0x1f, 0x00, +0x5f, 0xbf, 0x22, 0xff, 0x96 +}; + +static const unsigned char pkt124[] = { +0x42, 0xac, 0x00, +0x90, 0x21, 0x99, 0xef, 0x21, +0xff, 0x1d, 0x00, 0x00, 0x13, 0x1a, 0x27, 0x07, +0x27, 0x1a, 0x27, 0xd6, 0x97, 0x05, 0x27, 0xa3, +0x01, 0xa4, 0x01, 0xa3, 0x01, 0x2e, 0x00, 0xb0, +0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0x00, 0xb4, +0x00, 0xb5, 0x00, 0xb6, 0x00, 0xb7, 0x00, 0xb8, +0x00, 0xb9, 0x00, 0xba, 0x00, 0x56, 0x00, 0xae, +0x00, 0x54, 0x01, 0x44, 0x01, 0x55, 0x01, 0x44, +0x01, 0xbb, 0x00, 0xbc, 0x00, 0xbd, 0x00, 0xbe, +0x00, 0x83, 0x00, 0x84, 0x00, 0x81, 0x00, 0x82, +0x00, 0x24, 0x00, 0x44, 0x01, 0xdb, 0x00, 0xdc, +0x00, 0xdd, 0x00, 0xde, 0x00, 0x04, 0x00, 0x9b, +0x00, 0x99, 0x00, 0x9e, 0x00, 0x10, 0xef, 0xe6, +0x81, 0x65, 0xaf, 0x10, 0xef, 0xe6, 0x81, 0x9c, +0xaf, 0x10, 0xef, 0xe6, 0x81, 0x9a, 0xaf, 0x05, +0x27, 0xe5, 0x31, 0x1d, 0x81, 0xe5, 0x39, 0x05, +0x27, 0xc8, 0x46, 0x0b, 0x5b, 0xd3, 0x45, 0xfd, +0x5a, 0xd3, 0x45, 0xfb, 0x5a, 0xd3, 0x45, 0xf9, +0x5a, 0x41, 0x2e, 0xa1, 0xdf, 0x9f, 0x28, 0x41, +0x2e, 0xa1, 0xbf, 0x00, 0x88, 0x05, 0x27, 0x9f, +0x22, 0xbf, 0x22, 0x1f, 0x20, 0xfd, 0x53, 0x3f, +0x20, 0x14, 0x1f, 0xfa, 0x55, 0x05, 0x27 +}; + +static const unsigned char pkt128[] = { +0x42, 0xca, 0x00, +0xe5, 0x21, 0x25, 0x85, 0x01, +0x1e, 0x17, 0x55, 0xdc, 0x8a, 0x41, 0x2e, 0x53, +0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, 0x96, 0xdf, +0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, 0x2e, 0x78, +0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, 0x22, 0x00, +0x54, 0xff, 0xef, 0x2e, 0xaf, 0x05, 0x27, 0x07, +0x80, 0x9f, 0x22, 0xff, 0xaf, 0x00, 0x2e, 0x5d, +0x89, 0x05, 0x27, 0x03, 0x1e, 0x3c, 0x55, 0xaf, +0x8a, 0xa1, 0xcf, 0xfe, 0x1c, 0xa1, 0xaf, 0x05, +0x81, 0x47, 0x81, 0x76, 0x88, 0xff, 0x96, 0xdf, +0x96, 0xa1, 0xcf, 0x01, 0x18, 0xa1, 0xaf, 0x05, +0x81, 0x64, 0xef, 0xbf, 0x22, 0xbd, 0x80, 0x47, +0x81, 0x6b, 0x88, 0xff, 0x96, 0xdf, 0x96, 0x9b, +0x22, 0x14, 0x1e, 0x03, 0x53, 0xff, 0x22, 0x01, +0x55, 0x00, 0x20, 0x0a, 0x50, 0xc3, 0x97, 0xc4, +0x9f, 0x81, 0x01, 0x42, 0x01, 0x03, 0x52, 0xfa, +0x1e, 0x03, 0x53, 0xff, 0x22, 0x01, 0x55, 0x00, +0x20, 0xf2, 0x50, 0x00, 0x2e, 0xf0, 0x8b, 0x03, +0xcf, 0x7f, 0x1c, 0xff, 0xaf, 0x05, 0xef, 0xff, +0xaf, 0x00, 0xef, 0xff, 0xaf, 0xdd, 0x97, 0xff, +0xaf, 0xc2, 0x97, 0xff, 0xaf, 0xc3, 0x97, 0xff, +0xaf, 0xc0, 0x97, 0xff, 0xaf, 0xc1, 0x97, 0xff, +0xaf, 0x04, 0x0c, 0x00, 0x2e, 0x5d, 0x89, 0x05, +0x27, 0x06, 0x1e, 0x00, 0x55, 0x0f, 0x27, 0x0a, +0x1e, 0x07, 0x55, 0x00, 0x88, 0x66, 0x76, 0x3b, +0x30, 0x07, 0x35, 0xff, 0xff +}; + +static const unsigned char pkt133[] = { +0x42, 0xc2, 0x00, +0x49, 0x22, 0xc2, 0xbf, 0x0d, +0x27, 0x0c, 0x27, 0x0d, 0x1e, 0x02, 0x55, 0x28, +0x85, 0xf5, 0x5b, 0x7b, 0x76, 0x12, 0x1e, 0x07, +0x55, 0xdc, 0xef, 0x05, 0xff, 0x1a, 0x27, 0x56, +0xdf, 0x3f, 0x20, 0x6d, 0x80, 0x3c, 0xaf, 0x05, +0x27, 0x13, 0x1e, 0x01, 0x55, 0x3c, 0x23, 0x05, +0x27, 0x23, 0x1e, 0x0c, 0x55, 0x00, 0xef, 0x02, +0xff, 0x19, 0x27, 0xbf, 0x22, 0x20, 0xef, 0x7f, +0x9f, 0x5f, 0x20, 0xfc, 0x55, 0xf0, 0x81, 0x9f, +0x22, 0x41, 0x2e, 0xa3, 0xbf, 0x05, 0x27, 0x30, +0x1e, 0x0e, 0x55, 0x7e, 0xef, 0xff, 0xaf, 0x02, +0xef, 0xff, 0xaf, 0x00, 0xef, 0xff, 0xaf, 0xff, +0xef, 0x17, 0xff, 0x1a, 0x27, 0x07, 0x27, 0xff, +0xaf, 0xff, 0xbf, 0x00, 0x2e, 0x5d, 0x89, 0x05, +0x27, 0xcb, 0x74, 0xc9, 0xcf, 0xf3, 0x1c, 0x04, +0x18, 0xc9, 0xaf, 0x39, 0x81, 0x10, 0xff, 0xff, +0xef, 0xc1, 0x2e, 0x7c, 0xbf, 0x41, 0x2e, 0x7b, +0xbf, 0x02, 0xef, 0x41, 0x2e, 0x7a, 0xbf, 0xc9, +0x31, 0x18, 0xef, 0xc0, 0xaf, 0x04, 0x27, 0x41, +0x2e, 0x7a, 0xdf, 0xdf, 0x2d, 0x08, 0x5b, 0x01, +0xef, 0x41, 0x2e, 0x7a, 0xbf, 0xc0, 0x23, 0x18, +0xef, 0xc1, 0xaf, 0xcb, 0xcf, 0xcc, 0xdf, 0x05, +0x27, 0xc9, 0x30, 0x01, 0xef, 0x41, 0x2e, 0x7a, +0xbf, 0xc0, 0x23, 0x18, 0xef, 0xc1, 0xaf, 0x9f, +0x22, 0xbf, 0x22, 0x05, 0x27 +}; + +static const unsigned char pkt136[] = { +0x42, 0xca, 0x00, +0xa9, 0x22, 0x25, 0x85, 0x44, +0x1e, 0x01, 0x55, 0xe2, 0x2f, 0x7d, 0x50, 0x49, +0x1e, 0x02, 0x55, 0xe2, 0x2f, 0x79, 0x50, 0x05, +0x27, 0x4a, 0x1e, 0x01, 0x55, 0xe2, 0x2f, 0x74, +0x50, 0x4e, 0x1e, 0x01, 0x55, 0x00, 0x2e, 0xbb, +0x79, 0x4f, 0x1e, 0x00, 0x55, 0x7d, 0x78, 0x55, +0x1e, 0x00, 0x55, 0x05, 0x27, 0x58, 0x1e, 0x0d, +0x55, 0x02, 0x44, 0x01, 0x5a, 0x00, 0x2e, 0x07, +0x78, 0xfe, 0xcf, 0x75, 0xaf, 0xfe, 0xdf, 0x76, +0xbf, 0x41, 0x2e, 0xa4, 0xdf, 0xdf, 0x29, 0x41, +0x2e, 0xa4, 0xbf, 0x05, 0x27, 0x59, 0x1e, 0x02, +0x55, 0xfe, 0xcf, 0x10, 0xaf, 0x2b, 0x7e, 0x63, +0x1e, 0x1a, 0x55, 0x28, 0x85, 0xe2, 0x2f, 0x50, +0x5b, 0x0c, 0xef, 0x20, 0x80, 0xe2, 0x2f, 0x4c, +0x5a, 0xf0, 0xef, 0x00, 0xff, 0x19, 0x27, 0x08, +0xef, 0x06, 0xaf, 0xfe, 0xcf, 0x5f, 0x9f, 0x06, +0x25, 0xfb, 0x55, 0xfe, 0xcf, 0xfe, 0xcf, 0x41, +0x2e, 0x40, 0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x41, +0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x42, 0xbf, 0x05, +0x27, 0x64, 0x1e, 0x31, 0x55, 0xb0, 0xef, 0x00, +0xff, 0x19, 0x27, 0x0b, 0xef, 0x06, 0xaf, 0xfe, +0xcf, 0x5f, 0x9f, 0x06, 0x25, 0xfb, 0x55, 0xfe, +0xcf, 0x56, 0xaf, 0xfe, 0xcf, 0xae, 0xdf, 0x1f, +0x1c, 0xe0, 0x1d, 0x5f, 0x02, 0xae, 0xbf, 0xfe, +0xcf, 0x41, 0x2e, 0x54, 0xbf, 0xfe, 0xcf, 0x41, +0x2e, 0x77, 0xbf, 0xfe, 0xcf +}; + +static const unsigned char pkt140[] = { +0x42, 0xca, 0x00, +0x0d, 0x23, 0x41, 0x2e, 0x55, +0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x78, 0xbf, 0xfe, +0xcf, 0xbb, 0xaf, 0xfe, 0xcf, 0xbc, 0xaf, 0xfe, +0xcf, 0xbd, 0xaf, 0xfe, 0xcf, 0xbe, 0xaf, 0xfe, +0xcf, 0x83, 0xaf, 0xfe, 0xcf, 0x84, 0xaf, 0xfe, +0xcf, 0x81, 0xaf, 0xfe, 0xcf, 0x82, 0xaf, 0xfe, +0xcf, 0x24, 0xaf, 0xfe, 0xcf, 0x02, 0x33, 0x05, +0x27, 0x66, 0x1e, 0x0b, 0x55, 0x60, 0xef, 0x21, +0xff, 0x1a, 0x27, 0x0b, 0xef, 0x06, 0xaf, 0xfe, +0xcf, 0xfe, 0xdf, 0x06, 0x27, 0x01, 0x0e, 0x06, +0x25, 0xf9, 0x55, 0x05, 0x27, 0x35, 0x74, 0xff, +0x96, 0xc6, 0x2e, 0x01, 0xdf, 0x3f, 0x2c, 0xdd, +0x9f, 0x05, 0x27, 0x01, 0xef, 0x20, 0x80, 0xe1, +0x2f, 0xeb, 0x5a, 0xfe, 0xcf, 0xdf, 0x22, 0xe7, +0x2f, 0x1e, 0x54, 0x01, 0xff, 0x05, 0xef, 0xff, +0x96, 0xdf, 0x96, 0x2d, 0xff, 0x8d, 0xef, 0x19, +0x27, 0x03, 0xcf, 0x7f, 0x1c, 0x5f, 0x9f, 0xdd, +0x97, 0x5f, 0x9f, 0xdd, 0x97, 0x5f, 0x9f, 0x05, +0xef, 0x06, 0xaf, 0x9f, 0x22, 0x5f, 0x9f, 0x06, +0x25, 0xfc, 0x55, 0x5f, 0x9f, 0x06, 0x25, 0xfc, +0x55, 0x20, 0xef, 0x08, 0xaf, 0x09, 0x23, 0x00, +0x2e, 0xd1, 0x8d, 0x67, 0x81, 0x03, 0xef, 0xfc, +0xaf, 0x86, 0xef, 0xaa, 0xaf, 0x08, 0xef, 0xe3, +0xaf, 0x9f, 0x22, 0xe2, 0xaf, 0x21, 0xef, 0x41, +0x2e, 0x47, 0xbf, 0x27, 0xef, 0xf4, 0xaf, 0x28, +0xff, 0xa7, 0xef, 0xe1, 0xbf +}; + +static const unsigned char pkt144[] = { +0x42, 0x88, 0x00, +0x71, 0x23, 0xe0, 0xaf, 0x08, +0xef, 0x10, 0xaf, 0x8c, 0x8d, 0x05, 0x81, 0x01, +0x2e, 0x54, 0x80, 0x01, 0x2e, 0x56, 0x80, 0x9b, +0x22, 0x9b, 0x22, 0x2d, 0xff, 0x95, 0xef, 0x19, +0x27, 0x28, 0xff, 0xa7, 0xef, 0x1a, 0x27, 0x80, +0xef, 0x06, 0xaf, 0xdc, 0x97, 0x5f, 0x9f, 0xdf, +0x22, 0x01, 0x54, 0x00, 0x2e, 0x66, 0x8a, 0x06, +0x25, 0xf7, 0x55, 0x2d, 0xff, 0x91, 0xef, 0x19, +0x27, 0xdd, 0x97, 0xdd, 0x9f, 0x5f, 0x9f, 0x7f, +0x9f, 0xfd, 0x0d, 0xdf, 0x22, 0x01, 0x55, 0xff, +0x22, 0x01, 0x54, 0x01, 0xef, 0x1f, 0x98, 0x2f, +0xef, 0x41, 0x2e, 0x47, 0xbf, 0x11, 0xef, 0xf4, +0xaf, 0x28, 0xff, 0xa7, 0xef, 0xe1, 0xbf, 0xe0, +0xaf, 0x01, 0x2e, 0x54, 0x80, 0x01, 0x2e, 0x56, +0x80, 0x9b, 0x22, 0x9b, 0x22, 0x2e, 0xff, 0x15, +0xef, 0x19, 0x27, 0x28, 0xff, 0xa7, 0xef, 0x1a, +0x27, 0x80, 0xef, 0x06, 0xaf, 0x00, 0x2e, 0x3c, +0x8a, 0x05, 0x27 +}; + +static const unsigned char pkt148[] = { +0x42, 0xca, 0x00, +0xb4, 0x23, 0x37, 0xcf, 0xdf, +0x96, 0x08, 0xcf, 0xdf, 0x96, 0x3d, 0xcf, 0xdf, +0x96, 0x00, 0x2e, 0xd4, 0x8d, 0xdd, 0x97, 0x3d, +0xaf, 0xdd, 0x97, 0x08, 0xaf, 0xdd, 0x97, 0x37, +0xaf, 0x03, 0xcf, 0x51, 0x1e, 0x00, 0x55, 0x44, +0x8b, 0xa0, 0xcf, 0xbf, 0x1c, 0xa0, 0xaf, 0x05, +0x81, 0xfb, 0x39, 0x08, 0x45, 0x00, 0x5a, 0xfb, +0x31, 0x0a, 0x42, 0x00, 0x5b, 0xa2, 0x39, 0x02, +0xcf, 0x5c, 0xaf, 0xe1, 0xef, 0x40, 0x2e, 0x95, +0xbf, 0x9f, 0x22, 0x25, 0xaf, 0x69, 0xaf, 0x6a, +0xaf, 0x16, 0xaf, 0x40, 0x2e, 0x96, 0xbf, 0x29, +0xaf, 0x02, 0x47, 0x06, 0x5a, 0x0a, 0x41, 0x04, +0x5a, 0x0a, 0xdf, 0x30, 0x1d, 0x30, 0x1f, 0x00, +0x54, 0x01, 0xef, 0x44, 0xaf, 0x09, 0xef, 0x60, +0xaf, 0x0a, 0x40, 0x06, 0x5a, 0x10, 0xcf, 0x27, +0xaf, 0xe2, 0x23, 0x6e, 0x23, 0x08, 0xef, 0xe3, +0xaf, 0x6f, 0xaf, 0x0d, 0x8d, 0x5d, 0xcf, 0x30, +0x1c, 0x00, 0x1e, 0x07, 0x55, 0xf8, 0xcf, 0x5f, +0x2b, 0x9f, 0x29, 0xf8, 0xaf, 0xa1, 0xcf, 0xc1, +0x1c, 0xa1, 0xaf, 0x09, 0x50, 0x10, 0x1e, 0x07, +0x55, 0xf8, 0xcf, 0x5f, 0x29, 0x9f, 0x2b, 0xf8, +0xaf, 0xa1, 0xcf, 0xc1, 0x1c, 0x08, 0x18, 0xa1, +0xaf, 0x41, 0x2e, 0xa4, 0xdf, 0xdf, 0x2d, 0x04, +0x5b, 0x75, 0xcf, 0xf4, 0xaf, 0x76, 0xcf, 0xf5, +0xaf, 0x00, 0x50, 0x0f, 0x88, 0xe2, 0x23, 0x08, +0xef, 0xe3, 0xaf, 0x81, 0x82 +}; + +static const unsigned char pkt152[] = { +0x42, 0x24, 0x00, +0x18, 0x24, 0x4d, 0xaf, 0xdf, +0x96, 0x64, 0xdf, 0x93, 0x82, 0x93, 0xbf, 0xdd, +0x97, 0x77, 0xff, 0x93, 0x82, 0x94, 0xbf, 0x9e, +0x23, 0xe4, 0x23, 0x05, 0x27, 0x14, 0xef, 0xf4, +0xaf, 0x00, 0xef, 0xf5, 0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt156[] = { +0x42, 0xca, 0x00, +0x29, 0x24, 0xfe, 0xcf, 0x58, +0xaf, 0xfe, 0xcf, 0xfe, 0xdf, 0x00, 0x2e, 0xa9, +0x8b, 0xfe, 0xcf, 0x3c, 0xaf, 0x07, 0x3d, 0x58, +0x40, 0x4a, 0x5a, 0x3c, 0x26, 0x48, 0x55, 0x37, +0x45, 0x46, 0x5a, 0xe0, 0x88, 0x44, 0x5a, 0x77, +0x88, 0x00, 0x2e, 0xd1, 0x8b, 0xfe, 0xef, 0x16, +0x80, 0x02, 0xcf, 0xdf, 0x96, 0x61, 0xef, 0xc0, +0xaf, 0x04, 0x27, 0xc1, 0x46, 0x04, 0x5b, 0xc0, +0x3e, 0x40, 0xef, 0xc1, 0xaf, 0x01, 0x2e, 0x94, +0x84, 0xd0, 0x41, 0x06, 0x5b, 0x2d, 0x88, 0xf3, +0x5b, 0x6c, 0x86, 0xdd, 0x97, 0x1f, 0x2d, 0x05, +0x5b, 0x03, 0x50, 0x01, 0x0c, 0x02, 0xcf, 0xc0, +0x1c, 0x00, 0x55, 0x05, 0x88, 0xc0, 0x23, 0x20, +0xef, 0xc1, 0xaf, 0x00, 0x2e, 0xf0, 0x8b, 0x05, +0x27, 0x9b, 0x22, 0x37, 0x45, 0x05, 0x5a, 0x41, +0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x04, 0x5b, 0x00, +0x28, 0x02, 0x50, 0x3b, 0x43, 0x00, 0x5b, 0x00, +0x28, 0xd3, 0xdf, 0xc6, 0x2e, 0x15, 0xbf, 0xd3, +0x3c, 0x40, 0xef, 0x09, 0x80, 0xdd, 0x97, 0xff, +0xaf, 0x00, 0x2e, 0x5d, 0x89, 0xc6, 0x2e, 0x15, +0xdf, 0x10, 0x1d, 0xd3, 0xcf, 0x3f, 0x02, 0xd3, +0xaf, 0x05, 0x27, 0xc1, 0x83, 0x07, 0x45, 0x05, +0x27, 0x3d, 0x23, 0x07, 0x3d, 0x02, 0xcf, 0xdf, +0x96, 0x2e, 0x88, 0x26, 0x88, 0xfe, 0xef, 0x16, +0x80, 0x05, 0xef, 0xc0, 0xaf, 0x04, 0x27, 0xd0, +0x41, 0x02, 0x5b, 0xee, 0x8f +}; + +static const unsigned char pkt160[] = { +0x42, 0xca, 0x00, +0x8d, 0x24, 0xfa, 0x5b, 0xbf, +0x50, 0x31, 0x82, 0x04, 0xef, 0xc1, 0xaf, 0x9b, +0x22, 0x41, 0x88, 0xdd, 0x97, 0xdf, 0x22, 0x02, +0x55, 0x58, 0x40, 0x02, 0x5a, 0x09, 0x50, 0x58, +0x40, 0x07, 0x5a, 0xdd, 0x97, 0x1f, 0x2d, 0xb8, +0x5a, 0x7a, 0x88, 0xb7, 0x5b, 0x9b, 0x22, 0xc7, +0x8f, 0xb4, 0x50, 0x75, 0x88, 0xdc, 0x5b, 0xb7, +0x8f, 0x58, 0x41, 0x01, 0x5b, 0x01, 0x0c, 0xad, +0x7f, 0xd6, 0x50, 0x41, 0x2e, 0x52, 0xdf, 0xed, +0x1c, 0x04, 0x18, 0x41, 0x2e, 0x52, 0xbf, 0x05, +0x27, 0x00, 0x2e, 0xb9, 0x8b, 0xae, 0xdf, 0xe0, +0x19, 0xae, 0xbf, 0x57, 0x40, 0x00, 0x5b, 0xa1, +0x32, 0x57, 0x43, 0x00, 0x5b, 0xae, 0x3f, 0x05, +0x81, 0x05, 0x27, 0x41, 0x2e, 0x52, 0xdf, 0x03, +0x18, 0x41, 0x2e, 0x52, 0xbf, 0x05, 0x27, 0xd3, +0xdf, 0xff, 0x96, 0x9b, 0x22, 0x0b, 0x88, 0xd3, +0x3c, 0x07, 0x80, 0xdd, 0x97, 0xff, 0xaf, 0x00, +0x2e, 0x5d, 0x89, 0xdd, 0x9f, 0x10, 0x1d, 0xd3, +0xcf, 0x3f, 0x02, 0xd3, 0xaf, 0x05, 0x27, 0x37, +0x45, 0x0e, 0x5a, 0x40, 0x88, 0x0c, 0x5a, 0xd7, +0x8f, 0x00, 0x2e, 0xd7, 0x8b, 0x00, 0x2e, 0xeb, +0x8b, 0x41, 0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x00, +0x5b, 0x00, 0x28, 0x00, 0x2e, 0xf0, 0x8b, 0x05, +0x27, 0xf9, 0xcf, 0xdf, 0x96, 0xf9, 0x3d, 0x00, +0x2e, 0xd1, 0x8d, 0x28, 0xff, 0xa7, 0xef, 0xe1, +0xbf, 0xe0, 0xaf, 0x09, 0xef +}; + +static const unsigned char pkt164[] = { +0x42, 0x6c, 0x00, +0xf1, 0x24, 0x10, 0xaf, 0x0e, +0x8c, 0x05, 0x81, 0x01, 0x2e, 0x54, 0x80, 0x01, +0x2e, 0x56, 0x80, 0x20, 0x82, 0x7b, 0x8c, 0x37, +0x82, 0x26, 0x37, 0x00, 0x5a, 0x0c, 0x50, 0xff, +0x96, 0xdf, 0x96, 0x79, 0xcf, 0x7a, 0xdf, 0xff, +0x96, 0xdf, 0x96, 0xc2, 0x97, 0xc3, 0x9f, 0x9d, +0x01, 0x5d, 0x01, 0x07, 0x53, 0xdd, 0x97, 0xdd, +0x9f, 0x79, 0xaf, 0x7a, 0xbf, 0x3b, 0x3b, 0xdd, +0x97, 0xf9, 0xaf, 0x05, 0x27, 0xff, 0x22, 0x01, +0x55, 0x32, 0x1e, 0xf3, 0x5f, 0x02, 0x0c, 0xf6, +0x8f, 0x3b, 0x33, 0x00, 0x28, 0x05, 0x27, 0x0d, +0x27, 0x3c, 0x26, 0x07, 0x54, 0x3c, 0xcf, 0x3d, +0xdf, 0x3f, 0x20, 0x3d, 0xbf, 0xdf, 0x03, 0x01, +0x52, 0x3d, 0x23, 0x0c, 0x27, 0x0d, 0x27 +}; + +static const unsigned char pkt168[] = { +0x42, 0x50, 0x00, +0x26, 0x25, 0x08, 0x44, 0x12, +0x5a, 0x07, 0x40, 0x01, 0x5b, 0x4f, 0x80, 0x00, +0x50, 0x53, 0x80, 0x27, 0x0d, 0x25, 0xcf, 0x1f, +0x98, 0x29, 0xcf, 0x09, 0x27, 0x28, 0xdf, 0x3f, +0x02, 0x5f, 0x98, 0x62, 0xcf, 0xdf, 0x98, 0xd9, +0x0d, 0x02, 0x0d, 0x00, 0x2e, 0xd5, 0x7f, 0x05, +0x27, 0x01, 0x0d, 0x41, 0x2e, 0x56, 0xdf, 0x5f, +0x9f, 0x41, 0x2e, 0x57, 0xdf, 0x5f, 0x9f, 0x41, +0x2e, 0x58, 0xdf, 0x5f, 0x9f, 0x41, 0x2e, 0x59, +0xdf, 0x5f, 0x9f, 0x06, 0x0d, 0x3b, 0xcf, 0x5f, +0x9f, 0x05, 0x27 +}; + +static const unsigned char pkt172[] = { +0x42, 0xca, 0x00, +0x4d, 0x25, 0x9b, 0x22, 0xbb, +0x89, 0x22, 0x88, 0x75, 0x88, 0x14, 0x86, 0x2b, +0x86, 0x2b, 0x86, 0x2b, 0x86, 0x2b, 0x86, 0xa0, +0x88, 0x2e, 0x89, 0x24, 0x89, 0x02, 0x33, 0x07, +0x80, 0xdd, 0x97, 0xff, 0xaf, 0x00, 0x2e, 0x5d, +0x89, 0x05, 0x27, 0x6c, 0xcf, 0x6d, 0xdf, 0xbf, +0x01, 0x6c, 0xaf, 0x6d, 0x26, 0x00, 0x2e, 0x33, +0x55, 0x00, 0x2e, 0x4e, 0x50, 0xdf, 0x96, 0xff, +0x96, 0x32, 0xff, 0x07, 0xef, 0x91, 0x81, 0x7f, +0x20, 0xfb, 0x55, 0xdd, 0x9f, 0xdd, 0x97, 0x05, +0x27, 0x9f, 0x22, 0x6b, 0xaf, 0x00, 0x2e, 0x6e, +0x8f, 0x00, 0xef, 0x41, 0x2e, 0x44, 0xbf, 0x7f, +0xef, 0x41, 0x2e, 0x45, 0xbf, 0x80, 0xef, 0x0a, +0xaf, 0x00, 0x2e, 0xd1, 0x8d, 0x88, 0x82, 0x8c, +0x82, 0x6b, 0xcf, 0x10, 0xaf, 0x02, 0x2e, 0x02, +0x81, 0x40, 0xef, 0x6d, 0xaf, 0x80, 0xef, 0x6c, +0xaf, 0x00, 0x2e, 0xc4, 0x8d, 0x05, 0x81, 0x01, +0x2e, 0x54, 0x80, 0x01, 0x2e, 0x56, 0x80, 0x7f, +0x89, 0xff, 0x2f, 0xca, 0x5a, 0x6c, 0xcf, 0x6d, +0xdf, 0x3f, 0x00, 0x6c, 0xaf, 0x6d, 0x26, 0x03, +0x54, 0x6d, 0xdf, 0x16, 0x82, 0x6d, 0xbf, 0xeb, +0x50, 0x6b, 0xcf, 0x08, 0x1e, 0x11, 0x5f, 0x6c, +0x24, 0x02, 0x53, 0xff, 0xef, 0x6c, 0xaf, 0x10, +0x50, 0x6c, 0x24, 0x02, 0x53, 0xff, 0xef, 0x6c, +0xaf, 0x0b, 0x50, 0x6b, 0xcf, 0x0a, 0x1e, 0x08, +0x55, 0x6c, 0x24, 0x02, 0x53 +}; + +static const unsigned char pkt176[] = { +0x42, 0xca, 0x00, +0xb1, 0x25, 0xff, 0xef, 0x6c, +0xaf, 0x03, 0x50, 0x6c, 0x24, 0x01, 0x53, 0xff, +0xef, 0x6c, 0xaf, 0x6b, 0xcf, 0xdf, 0x96, 0xb0, +0xef, 0x00, 0xff, 0x1d, 0x00, 0x00, 0x13, 0x1b, +0x27, 0x6c, 0xcf, 0x9f, 0x9d, 0x6b, 0xcf, 0x1f, +0x20, 0x6b, 0xaf, 0x0a, 0x1e, 0xbc, 0x5f, 0x05, +0x27, 0x0c, 0xef, 0x41, 0x2e, 0x76, 0xbf, 0x10, +0xef, 0x6d, 0xaf, 0xae, 0xcf, 0xe0, 0x1c, 0xae, +0xaf, 0x0b, 0x78, 0xcb, 0xcf, 0xcc, 0xdf, 0x0a, +0x1f, 0x07, 0x52, 0x01, 0x5e, 0x00, 0x1e, 0x04, +0x5f, 0xae, 0xcf, 0x6d, 0xdf, 0xbf, 0x01, 0xae, +0xaf, 0x03, 0x78, 0xae, 0xcf, 0x6d, 0xdf, 0x3f, +0x00, 0xae, 0xaf, 0x16, 0x82, 0x6d, 0xbf, 0x05, +0x81, 0x64, 0xef, 0xbf, 0x22, 0xbd, 0x80, 0x34, +0x81, 0x53, 0x81, 0x6d, 0x26, 0xe5, 0x55, 0xcb, +0xcf, 0xcc, 0xdf, 0x0a, 0x1f, 0x02, 0x5e, 0x04, +0x52, 0x00, 0x1e, 0x02, 0x5f, 0xae, 0xcf, 0x5f, +0x20, 0xae, 0xaf, 0x00, 0xef, 0x41, 0x2e, 0x76, +0xbf, 0x05, 0x27, 0x00, 0x2e, 0x6e, 0x8f, 0x02, +0x2e, 0x6b, 0x81, 0x00, 0x2e, 0xd1, 0x8d, 0x73, +0x23, 0x0a, 0xef, 0x10, 0xaf, 0x02, 0x2e, 0x02, +0x81, 0x80, 0xef, 0x00, 0x2e, 0xc4, 0x8d, 0x05, +0x81, 0x08, 0xef, 0x06, 0xaf, 0x01, 0x2e, 0x54, +0x80, 0x01, 0x2e, 0x56, 0x80, 0x06, 0x25, 0xf9, +0x55, 0xb3, 0x88, 0x40, 0xcf, 0xe0, 0xaf, 0x41, +0xdf, 0xe1, 0xbf, 0x41, 0x2e +}; + +static const unsigned char pkt180[] = { +0x42, 0xca, 0x00, +0x15, 0x26, 0x4e, 0xdf, 0xf7, +0x1c, 0x41, 0x2e, 0x4e, 0xbf, 0x01, 0x2e, 0x54, +0x80, 0x01, 0x2e, 0x56, 0x80, 0x4f, 0x82, 0x40, +0x2e, 0x8f, 0xdf, 0xdf, 0x22, 0xed, 0x55, 0x30, +0x88, 0x4e, 0x23, 0x4e, 0xcf, 0x31, 0x88, 0x37, +0x88, 0x3f, 0x9f, 0x4e, 0xcf, 0x2d, 0x88, 0x39, +0x88, 0x1f, 0x9f, 0x4e, 0x24, 0x4e, 0xcf, 0x04, +0x1e, 0xf3, 0x55, 0xf8, 0x0f, 0x08, 0xef, 0x06, +0xaf, 0xf6, 0x97, 0xbc, 0x03, 0x01, 0x5f, 0xff, +0x0f, 0xfc, 0x97, 0x06, 0x25, 0xf9, 0x55, 0xf8, +0x0f, 0x08, 0xff, 0x06, 0xbf, 0xf6, 0x9f, 0xdf, +0x01, 0xa1, 0x27, 0x7f, 0x21, 0x3f, 0x9f, 0x06, +0x25, 0xf8, 0x55, 0xf8, 0x0f, 0x04, 0xef, 0x06, +0xaf, 0xbb, 0xef, 0x00, 0xff, 0x1a, 0x27, 0xfc, +0x9f, 0xfc, 0x97, 0x09, 0x27, 0x5f, 0x02, 0x3f, +0x97, 0x06, 0x25, 0xf8, 0x55, 0x81, 0xcf, 0x24, +0xaf, 0x05, 0x27, 0x54, 0xef, 0x28, 0xff, 0x1b, +0x27, 0x05, 0x27, 0xdf, 0x96, 0x40, 0xcf, 0x41, +0xdf, 0x1d, 0x00, 0x00, 0x13, 0x19, 0x27, 0x05, +0x27, 0x0f, 0xff, 0x0b, 0x88, 0x40, 0x10, 0x00, +0x13, 0x8e, 0x81, 0x05, 0x27, 0xf0, 0xff, 0x05, +0x88, 0x04, 0x11, 0x3f, 0x22, 0xff, 0x97, 0x09, +0x27, 0x0f, 0x1c, 0x05, 0x27, 0xff, 0x96, 0x9b, +0x22, 0x9b, 0x22, 0x80, 0xef, 0x06, 0xaf, 0xe0, +0x97, 0x02, 0x03, 0xbf, 0x22, 0x00, 0x00, 0xc1, +0x00, 0x1f, 0x90, 0x7f, 0x90 +}; + +static const unsigned char pkt184[] = { +0x42, 0xca, 0x00, +0x79, 0x26, 0x04, 0x0d, 0x06, +0x25, 0xf5, 0x55, 0x03, 0x0c, 0x05, 0x27, 0x04, +0xef, 0x10, 0xaf, 0x02, 0x2e, 0x02, 0x81, 0x05, +0x81, 0xf7, 0xef, 0x16, 0x80, 0x6b, 0x81, 0x05, +0x27, 0x73, 0x23, 0x08, 0xef, 0x0b, 0xaf, 0x02, +0x2e, 0x6b, 0x81, 0x00, 0x2e, 0x6e, 0x8f, 0x00, +0x2e, 0xd1, 0x8d, 0x0a, 0xef, 0x10, 0xaf, 0x02, +0x2e, 0x02, 0x81, 0x88, 0x82, 0x02, 0x2e, 0x9f, +0x80, 0x80, 0xef, 0x00, 0x2e, 0xc4, 0x8d, 0x05, +0x81, 0x0b, 0xcf, 0x06, 0xaf, 0x01, 0x2e, 0x54, +0x80, 0x01, 0x2e, 0x56, 0x80, 0x06, 0x25, 0xf9, +0x55, 0x1f, 0x88, 0x20, 0x82, 0x02, 0x2e, 0x76, +0x81, 0xf7, 0xef, 0x16, 0x80, 0x81, 0xcf, 0x72, +0xaf, 0x02, 0x2e, 0x6b, 0x81, 0x02, 0x2e, 0xc0, +0x81, 0x08, 0xef, 0x02, 0x2e, 0x51, 0x80, 0x08, +0xef, 0x02, 0x2e, 0x7a, 0x80, 0x01, 0x2e, 0x89, +0x81, 0x2d, 0xcf, 0xdf, 0x96, 0x2c, 0xcf, 0xdf, +0x96, 0x2a, 0xcf, 0x2b, 0xdf, 0x9d, 0x01, 0x5d, +0x01, 0x83, 0xaf, 0x84, 0xbf, 0xc8, 0xef, 0x0b, +0xaf, 0x05, 0x27, 0x0a, 0xef, 0x73, 0x43, 0x02, +0x5b, 0x73, 0xcf, 0x09, 0x27, 0x0f, 0x1c, 0x81, +0xaf, 0x73, 0xcf, 0x09, 0x27, 0x30, 0x1c, 0xfc, +0xdf, 0xcf, 0x1d, 0x5f, 0x02, 0xfc, 0xbf, 0x81, +0xcf, 0x10, 0xaf, 0x02, 0x2e, 0x02, 0x81, 0x88, +0x82, 0x02, 0x2e, 0x9f, 0x80, 0x40, 0xef, 0x6b, +0xaf, 0x80, 0xef, 0x82, 0xaf +}; + +static const unsigned char pkt188[] = { +0x42, 0x9a, 0x00, +0xdd, 0x26, 0x00, 0x2e, 0xc4, +0x8d, 0x05, 0x81, 0x01, 0x2e, 0x54, 0x80, 0x01, +0x2e, 0x56, 0x80, 0x20, 0x82, 0x02, 0x2e, 0xe6, +0x80, 0x0a, 0x5b, 0x73, 0x43, 0x18, 0x5a, 0x81, +0xcf, 0x5e, 0xdf, 0xbf, 0x03, 0x14, 0x5f, 0x5f, +0x20, 0x81, 0xaf, 0xdf, 0x22, 0x10, 0x54, 0xde, +0x50, 0x40, 0x2e, 0x8f, 0xdf, 0x1f, 0x2c, 0x0c, +0x5a, 0x5f, 0x2c, 0x09, 0x5b, 0x82, 0xcf, 0x6b, +0xdf, 0x3f, 0x00, 0x82, 0xaf, 0x6b, 0x26, 0xe8, +0x54, 0x6b, 0xdf, 0x16, 0x82, 0x6b, 0xbf, 0xd9, +0x50, 0x05, 0x27, 0x82, 0xcf, 0x6b, 0xdf, 0xbf, +0x01, 0x82, 0xaf, 0x6b, 0x26, 0xf4, 0x55, 0xdc, +0x50, 0x88, 0x82, 0x8c, 0x82, 0x9f, 0x22, 0xbb, +0xaf, 0xbc, 0xaf, 0xbd, 0xaf, 0xbe, 0xaf, 0x05, +0x27, 0xf9, 0x44, 0x08, 0x5a, 0xc1, 0x2e, 0x81, +0xdf, 0x01, 0x1f, 0x0e, 0x52, 0x0c, 0x5e, 0xc1, +0x2e, 0x80, 0xdf, 0xfe, 0x1f, 0x09, 0x52, 0xc1, +0x2e, 0x81, 0xdf, 0x03, 0x1f, 0x05, 0x52, 0x03, +0x5e, 0xc1, 0x2e, 0x80, 0xdf, 0xfc, 0x1f, 0x00, +0x52, 0x0c, 0x27, 0x0d, 0x27 +}; + +static const unsigned char pkt192[] = { +0x42, 0x7e, 0x00, +0x29, 0x27, 0x53, 0x80, 0x01, +0x0d, 0xf5, 0x97, 0xff, 0x0d, 0x1f, 0x99, 0x49, +0xcf, 0x5f, 0x99, 0x08, 0x44, 0x00, 0x2e, 0x32, +0x5a, 0x0b, 0x0d, 0x44, 0xcf, 0x0c, 0x41, 0x00, +0x5b, 0x1f, 0x20, 0x44, 0xaf, 0x5f, 0x9f, 0x04, +0x0d, 0x11, 0xcf, 0x5f, 0x9f, 0x12, 0xcf, 0x5f, +0x9f, 0x1c, 0xcf, 0x5f, 0x9f, 0x1d, 0xcf, 0x5f, +0x9f, 0x4d, 0xcf, 0x5f, 0x9f, 0x49, 0xcf, 0x5f, +0x9f, 0x06, 0x0d, 0xe0, 0x97, 0x0f, 0x1c, 0x5f, +0x9f, 0x0a, 0xcf, 0x5f, 0x9f, 0x09, 0xcf, 0x5f, +0x9f, 0x78, 0xcf, 0x5f, 0x9f, 0x9f, 0xcf, 0x5f, +0x9f, 0x92, 0xcf, 0x5f, 0x9f, 0x19, 0xcf, 0x5f, +0x9f, 0x02, 0x0d, 0x85, 0xcf, 0x5f, 0x9f, 0x44, +0xdf, 0x02, 0x2e, 0x8c, 0x81, 0x5f, 0x9f, 0x4d, +0xcf, 0x5f, 0x9f, 0x01, 0x0d, 0x6a, 0xcf, 0x09, +0x27, 0x69, 0xdf, 0x3f, 0x02, 0x5f, 0x9f, 0x05, +0x27 +}; + +static const unsigned char pkt196[] = { +0x42, 0xca, 0x00, +0x67, 0x27, 0x00, 0x2e, 0xf5, +0x88, 0x39, 0x81, 0x84, 0x88, 0x05, 0xcf, 0xdf, +0x22, 0x33, 0x55, 0x04, 0xcf, 0x2a, 0x1e, 0x30, +0x55, 0xfe, 0xdf, 0xfe, 0xcf, 0x00, 0x1f, 0x1b, +0x55, 0x00, 0x1e, 0x0d, 0x54, 0xc6, 0x2e, 0x00, +0xdf, 0x3f, 0x20, 0xbf, 0x03, 0x14, 0x55, 0xc6, +0x2e, 0x01, 0xdf, 0x3f, 0x2c, 0x10, 0x5b, 0x46, +0x2e, 0x00, 0xbf, 0x00, 0x2e, 0xdb, 0x88, 0x09, +0x78, 0x00, 0xef, 0x46, 0x2e, 0x00, 0xbf, 0x46, +0x2e, 0x01, 0xdf, 0x1f, 0x28, 0x46, 0x2e, 0x01, +0xbf, 0x00, 0x2e, 0xbc, 0x88, 0x13, 0x88, 0x05, +0x27, 0x46, 0x2e, 0x01, 0xdf, 0x1f, 0x2a, 0x46, +0x2e, 0x01, 0xbf, 0x41, 0x2e, 0xb6, 0xdf, 0x01, +0xff, 0xab, 0xef, 0x19, 0x27, 0x42, 0xff, 0x7f, +0x98, 0x9f, 0x98, 0x24, 0x28, 0x2a, 0x85, 0x24, +0x2a, 0x05, 0x27, 0x2c, 0x85, 0x05, 0x27, 0xfd, +0x0c, 0x00, 0x2e, 0xab, 0x88, 0x14, 0xef, 0x00, +0x2e, 0xef, 0x88, 0x32, 0x88, 0x3a, 0x88, 0x34, +0x88, 0x38, 0x88, 0x32, 0x88, 0x36, 0x88, 0x30, +0x88, 0x34, 0x88, 0x2e, 0x88, 0x32, 0x88, 0x46, +0x2e, 0x00, 0xdf, 0x1f, 0x9f, 0xe2, 0xef, 0x1f, +0x90, 0xe0, 0xff, 0x7f, 0x90, 0x0e, 0xef, 0x00, +0x2e, 0xe7, 0x88, 0x80, 0xef, 0x1f, 0x9f, 0x9f, +0x22, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, +0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x01, 0xef, 0x1f, +0x9f, 0xb8, 0xef, 0x1f, 0x9f +}; + +static const unsigned char pkt200[] = { +0x42, 0x66, 0x00, +0xcb, 0x27, 0x00, 0x2e, 0xab, +0x88, 0x40, 0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, +0x55, 0x03, 0x0c, 0x01, 0x2e, 0x6e, 0x86, 0x01, +0x2e, 0x05, 0x86, 0x00, 0x2e, 0xb5, 0x88, 0x00, +0x2e, 0xb1, 0x88, 0x14, 0xef, 0x00, 0x2e, 0xb7, +0x88, 0x05, 0x27, 0x40, 0xef, 0x28, 0xff, 0x1a, +0x27, 0x05, 0x27, 0x16, 0x27, 0x04, 0x10, 0x00, +0x13, 0x1a, 0x27, 0x05, 0x27, 0xd9, 0x9f, 0x3f, +0x9f, 0xd8, 0x9f, 0x3f, 0x9f, 0xd7, 0x9f, 0x3f, +0x9f, 0xd6, 0x9f, 0x3f, 0x9f, 0x05, 0x27, 0x7f, +0xef, 0x28, 0xff, 0x46, 0x2e, 0x1d, 0xbf, 0xc6, +0x2e, 0x1c, 0xbf, 0x93, 0xef, 0x28, 0xff, 0x46, +0x2e, 0x1f, 0xbf, 0xc6, 0x2e, 0x1e, 0xbf, 0x05, +0x27 +}; + +static const unsigned char pkt204[] = { +0x42, 0xca, 0x00, +0xfd, 0x27, 0xfd, 0x0c, 0x00, +0x2e, 0xf5, 0x88, 0x0d, 0x84, 0x05, 0xcf, 0xdf, +0x22, 0x00, 0x2e, 0x98, 0x55, 0x04, 0xcf, 0x14, +0x1e, 0x00, 0x2e, 0x94, 0x55, 0x00, 0x2e, 0xab, +0x88, 0xbb, 0xef, 0x1f, 0x90, 0x91, 0xff, 0x7f, +0x90, 0x14, 0xef, 0x00, 0x2e, 0xe7, 0x88, 0x14, +0xef, 0x00, 0x2e, 0xef, 0x88, 0x33, 0xef, 0x1f, +0x90, 0x71, 0xff, 0x7f, 0x90, 0x18, 0xef, 0x00, +0x2e, 0xe7, 0x88, 0x00, 0x2e, 0xab, 0x88, 0x40, +0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, 0x55, 0x01, +0x2e, 0x6e, 0x86, 0x01, 0x2e, 0x05, 0x86, 0x00, +0x2e, 0xab, 0x88, 0x7a, 0x88, 0x0a, 0xef, 0x00, +0x2e, 0xb7, 0x88, 0x76, 0x88, 0x00, 0xff, 0x80, +0xef, 0x19, 0x27, 0x0a, 0xef, 0xdc, 0x9f, 0x7f, +0x9f, 0x5f, 0x20, 0xfb, 0x55, 0x0d, 0x84, 0x6c, +0x88, 0x0a, 0xef, 0x00, 0x2e, 0xb7, 0x88, 0x68, +0x88, 0x0a, 0xef, 0xdc, 0x9f, 0x7f, 0x9f, 0x5f, +0x20, 0xfb, 0x55, 0x5e, 0x88, 0xa4, 0x8f, 0x9e, +0x8f, 0xa2, 0x8f, 0x9c, 0x8f, 0xa0, 0x8f, 0x9a, +0x8f, 0x9e, 0x8f, 0x98, 0x8f, 0x9c, 0x8f, 0x9d, +0xef, 0x1f, 0x90, 0xda, 0xff, 0x7f, 0x90, 0x0f, +0xef, 0x00, 0x2e, 0xe7, 0x88, 0x80, 0xef, 0x1f, +0x9f, 0x9f, 0x22, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, +0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x03, +0xef, 0x1f, 0x9f, 0xb8, 0xef, 0x1f, 0x9f, 0x00, +0x2e, 0xab, 0x88, 0x40, 0xef +}; + +static const unsigned char pkt208[] = { +0x42, 0xca, 0x00, +0x61, 0x28, 0xfc, 0x9f, 0x5f, +0x20, 0xfc, 0x55, 0x01, 0x2e, 0x05, 0x86, 0x00, +0x2e, 0xb5, 0x88, 0x72, 0x88, 0x7c, 0x8f, 0x76, +0x8f, 0x7a, 0x8f, 0x74, 0x8f, 0x78, 0x8f, 0x72, +0x8f, 0x76, 0x8f, 0x70, 0x8f, 0x74, 0x8f, 0x68, +0x88, 0x14, 0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, +0x55, 0x01, 0xff, 0xab, 0xef, 0x19, 0x27, 0x60, +0x88, 0x11, 0xff, 0xbf, 0x90, 0x51, 0xff, 0xc2, +0x97, 0xdf, 0x01, 0x7f, 0x98, 0xfc, 0x9f, 0xbf, +0x98, 0x24, 0x28, 0xc2, 0x9f, 0x7f, 0x20, 0xbf, +0x90, 0xf4, 0x55, 0x24, 0x2a, 0x1d, 0x88, 0x72, +0xef, 0xff, 0xaf, 0x14, 0xef, 0xff, 0xaf, 0x00, +0xef, 0xff, 0xaf, 0x00, 0xff, 0x80, 0xef, 0x19, +0x27, 0x14, 0xff, 0xfd, 0x97, 0xff, 0xaf, 0x7f, +0x20, 0xfb, 0x55, 0x00, 0x2e, 0x5f, 0x89, 0x03, +0x0c, 0x02, 0x2e, 0xdd, 0x81, 0x05, 0x27, 0x2c, +0x85, 0x05, 0x27, 0x40, 0xef, 0x28, 0xff, 0x1a, +0x27, 0x05, 0x27, 0x02, 0xef, 0x06, 0xff, 0x1a, +0x27, 0x05, 0x27, 0x01, 0xff, 0xab, 0xef, 0x19, +0x27, 0x08, 0xef, 0x1f, 0x98, 0xe4, 0x29, 0x00, +0xff, 0xff, 0x96, 0x20, 0xff, 0xff, 0x96, 0x00, +0xff, 0xff, 0x96, 0x40, 0xff, 0xff, 0x96, 0x00, +0xff, 0xff, 0x96, 0x60, 0xff, 0xff, 0x96, 0x00, +0xff, 0xff, 0x96, 0x00, 0xff, 0xff, 0x96, 0x01, +0xff, 0xff, 0x96, 0x20, 0xff, 0xff, 0x96, 0x00, +0xff, 0xff, 0x96, 0x02, 0xff +}; + +static const unsigned char pkt212[] = { +0x42, 0x38, 0x00, +0xc5, 0x28, 0xff, 0x96, 0x02, +0xff, 0xff, 0x96, 0x82, 0xff, 0xff, 0x96, 0x02, +0xff, 0xff, 0x96, 0x05, 0x88, 0x46, 0x2e, 0x01, +0xdf, 0x9f, 0x28, 0x46, 0x2e, 0x01, 0xbf, 0x05, +0x27, 0x0f, 0xef, 0x5f, 0x98, 0xdd, 0x9f, 0xbf, +0x98, 0x24, 0x28, 0x5f, 0x20, 0xf9, 0x55, 0x24, +0x2a, 0x05, 0x27, 0x7f, 0xef, 0x28, 0xff, 0x1b, +0x27, 0x05, 0x27 +}; + +static const unsigned char pkt216[] = { +0x42, 0xca, 0x00, +0xe0, 0x28, 0xe1, 0x97, 0xe2, +0x9f, 0x46, 0x2e, 0x28, 0xbf, 0xc6, 0x2e, 0x29, +0xbf, 0xad, 0x88, 0x0a, 0x5b, 0xe9, 0x97, 0xea, +0x9f, 0x4f, 0xaf, 0x50, 0xbf, 0x46, 0x2e, 0x28, +0xdf, 0xc6, 0x2e, 0x29, 0xdf, 0x10, 0x10, 0x00, +0x13, 0x01, 0x78, 0x03, 0x10, 0x00, 0x13, 0xff, +0x96, 0xdf, 0x96, 0xd6, 0xcf, 0xd7, 0xdf, 0x0f, +0x1d, 0x01, 0x10, 0x00, 0x13, 0xff, 0x96, 0xdf, +0x96, 0xc8, 0xdf, 0xc7, 0xcf, 0x1f, 0x1d, 0xff, +0x96, 0xdf, 0x96, 0xc2, 0x97, 0xc3, 0x9f, 0x9d, +0x01, 0x5d, 0x01, 0xf5, 0x52, 0xc3, 0x03, 0x02, +0x5e, 0xf2, 0x52, 0x82, 0x03, 0xf0, 0x52, 0x02, +0x0c, 0xf8, 0x43, 0x03, 0x5b, 0x08, 0x44, 0x01, +0x5a, 0x00, 0x2e, 0xf3, 0x8f, 0x7f, 0x88, 0x6d, +0x5b, 0x41, 0x2e, 0xaf, 0xdf, 0xdf, 0x29, 0x41, +0x2e, 0xaf, 0xbf, 0x46, 0x2e, 0x28, 0xdf, 0xc6, +0x2e, 0x29, 0xdf, 0x03, 0x16, 0x00, 0x15, 0x46, +0x2e, 0x28, 0xbf, 0xc6, 0x2e, 0x29, 0xbf, 0x15, +0x27, 0xff, 0x96, 0xdf, 0x96, 0x8d, 0x88, 0x94, +0x88, 0xcd, 0x88, 0x01, 0xff, 0xab, 0xef, 0x19, +0x27, 0x6b, 0x88, 0xbf, 0x22, 0x3f, 0x98, 0x05, +0xff, 0x7f, 0x98, 0xdd, 0x9f, 0xbf, 0x98, 0x24, +0x28, 0x04, 0xff, 0x7f, 0x98, 0xdd, 0x9f, 0xbf, +0x98, 0x24, 0x28, 0x66, 0xff, 0xbf, 0x99, 0x12, +0xff, 0x7f, 0x99, 0xdd, 0x97, 0xdd, 0x9f, 0x19, +0x27, 0xe0, 0x97, 0xff, 0xaf +}; + +static const unsigned char pkt220[] = { +0x42, 0xca, 0x00, +0x44, 0x29, 0x46, 0x2e, 0x28, +0xdf, 0xc6, 0x2e, 0x29, 0xdf, 0x13, 0x10, 0x00, +0x13, 0xff, 0xaf, 0xff, 0xbf, 0xe3, 0x97, 0xff, +0xaf, 0xe4, 0x97, 0xff, 0xaf, 0xe5, 0x97, 0xff, +0xaf, 0xef, 0x88, 0x06, 0x0d, 0xdd, 0x97, 0xdd, +0x9f, 0x46, 0x2e, 0x28, 0xdf, 0xc6, 0x2e, 0x29, +0xdf, 0x06, 0xaf, 0x4e, 0xbf, 0xff, 0x22, 0x11, +0x54, 0x15, 0x27, 0x1a, 0x27, 0x01, 0xff, 0xab, +0xef, 0x19, 0x27, 0xdc, 0x97, 0xdf, 0x99, 0x28, +0x28, 0x0f, 0x27, 0x68, 0x2c, 0xfd, 0x5b, 0xe9, +0x97, 0xff, 0xaf, 0x6a, 0x28, 0x06, 0x25, 0xf4, +0x53, 0x4e, 0x25, 0xf2, 0x55, 0xdc, 0x97, 0xdf, +0x99, 0x28, 0x28, 0x0f, 0x27, 0x68, 0x2c, 0xfd, +0x5b, 0xe9, 0x97, 0xff, 0xaf, 0x6a, 0x28, 0x06, +0x25, 0xf4, 0x55, 0x41, 0x2e, 0xaf, 0xdf, 0xdf, +0x2b, 0x41, 0x2e, 0xaf, 0xbf, 0xbf, 0x22, 0xbf, +0x99, 0x7f, 0x99, 0x05, 0x27, 0xdd, 0x97, 0xdd, +0x9f, 0x06, 0xaf, 0x4e, 0xbf, 0xff, 0x22, 0x05, +0x54, 0xfd, 0x97, 0xff, 0xaf, 0x06, 0x25, 0xfb, +0x53, 0x4e, 0x25, 0xf9, 0x55, 0xfd, 0x97, 0xff, +0xaf, 0x06, 0x25, 0xfb, 0x55, 0x05, 0x27, 0xff, +0x96, 0xc6, 0x2e, 0x01, 0xdf, 0xbf, 0x2c, 0xdd, +0x9f, 0x05, 0x27, 0xc6, 0x2e, 0x28, 0xdf, 0x0f, +0x1d, 0x04, 0x55, 0x0b, 0x88, 0xff, 0x96, 0x10, +0xef, 0xdf, 0x96, 0x06, 0x50, 0x06, 0x88, 0x3f, +0x20, 0xff, 0x96, 0xc6, 0x2e +}; + +static const unsigned char pkt224[] = { +0x42, 0xca, 0x00, +0xa8, 0x29, 0x28, 0xdf, 0x0f, +0x1d, 0xff, 0x96, 0x05, 0x27, 0x46, 0x2e, 0x28, +0xdf, 0xf0, 0x1c, 0x09, 0x27, 0xdf, 0x9f, 0x46, +0x2e, 0x29, 0xdf, 0x0f, 0x1c, 0x09, 0x27, 0x5f, +0x02, 0x05, 0x27, 0x78, 0x88, 0x6f, 0x88, 0x0a, +0xef, 0xdc, 0x9f, 0x3f, 0x9f, 0x5f, 0x20, 0xfb, +0x55, 0x05, 0x27, 0x9f, 0x22, 0x41, 0x2e, 0xab, +0xbf, 0x50, 0xef, 0xdf, 0x96, 0x3a, 0xef, 0xdf, +0x96, 0x29, 0x88, 0x68, 0x88, 0x0a, 0xef, 0xfc, +0x9f, 0xc1, 0x2e, 0xad, 0xbf, 0xc1, 0x2e, 0xac, +0xdf, 0x3f, 0x20, 0xc1, 0x2e, 0xac, 0xbf, 0x6a, +0x88, 0x5f, 0x20, 0xf4, 0x55, 0x5b, 0xef, 0xdf, +0x96, 0x50, 0xcf, 0xdf, 0x96, 0x17, 0x88, 0x5c, +0xef, 0xdf, 0x96, 0x4f, 0xcf, 0xdf, 0x96, 0x12, +0x88, 0x5d, 0xef, 0xdf, 0x96, 0x9f, 0x22, 0xdf, +0x96, 0x0d, 0x88, 0x5e, 0xef, 0xdf, 0x96, 0x46, +0x2e, 0x29, 0xdf, 0xdf, 0x96, 0x07, 0x88, 0x5f, +0xef, 0xdf, 0x96, 0x46, 0x2e, 0x28, 0xdf, 0xdf, +0x96, 0x01, 0x88, 0x0f, 0x27, 0x05, 0x27, 0xdd, +0x97, 0x41, 0x2e, 0xad, 0xbf, 0xdd, 0x97, 0x41, +0x2e, 0xac, 0xbf, 0x44, 0x88, 0x05, 0x27, 0x9f, +0x22, 0x41, 0x2e, 0xab, 0xbf, 0x10, 0xef, 0xdf, +0x96, 0x02, 0xef, 0xdf, 0x96, 0xef, 0x8f, 0x2e, +0x88, 0x0a, 0xef, 0xfc, 0x9f, 0xc1, 0x2e, 0xad, +0xbf, 0xc1, 0x2e, 0xac, 0xdf, 0x3f, 0x20, 0xc1, +0x2e, 0xac, 0xbf, 0x30, 0x88 +}; + +static const unsigned char pkt228[] = { +0x42, 0x9a, 0x00, +0x0c, 0x2a, 0x5f, 0x20, 0xf4, +0x55, 0x1b, 0xef, 0xdf, 0x96, 0x50, 0xcf, 0xdf, +0x96, 0xdd, 0x8f, 0x1c, 0xef, 0xdf, 0x96, 0x4f, +0xcf, 0xdf, 0x96, 0xd8, 0x8f, 0x1d, 0xef, 0xdf, +0x96, 0x9f, 0x22, 0xdf, 0x96, 0xd3, 0x8f, 0x1e, +0xef, 0xdf, 0x96, 0x9f, 0x22, 0xdf, 0x96, 0xce, +0x8f, 0x1f, 0xef, 0xdf, 0x96, 0x01, 0xef, 0xdf, +0x96, 0xc9, 0x8f, 0x0f, 0x27, 0x05, 0x27, 0x02, +0xef, 0x06, 0xff, 0x1a, 0x27, 0x05, 0x27, 0x02, +0xef, 0x06, 0xff, 0x1a, 0x27, 0x05, 0x27, 0xdf, +0x96, 0xff, 0x96, 0x7b, 0xef, 0x00, 0xff, 0x1b, +0x27, 0xdd, 0x9f, 0xdd, 0x97, 0x05, 0x27, 0x01, +0xff, 0xab, 0xef, 0x1b, 0x27, 0x05, 0x27, 0xdf, +0x96, 0x81, 0xef, 0x41, 0x2e, 0xaf, 0xbf, 0xdd, +0x97, 0x05, 0x27, 0x3a, 0xef, 0xff, 0xaf, 0xea, +0x8f, 0x0a, 0xef, 0xfc, 0x9f, 0xff, 0xbf, 0x5f, +0x20, 0xfb, 0x55, 0x50, 0xcf, 0xff, 0xaf, 0x4f, +0xcf, 0xff, 0xaf, 0x9f, 0x22, 0xff, 0xaf, 0x46, +0x2e, 0x29, 0xdf, 0xff, 0xaf, 0x46, 0x2e, 0x28, +0xdf, 0xff, 0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt232[] = { +0x42, 0x18, 0x00, +0x58, 0x2a, 0xd3, 0x45, 0x03, +0x5a, 0x0f, 0x27, 0xd3, 0x45, 0x00, 0x5a, 0x05, +0x27, 0xd0, 0x41, 0xf7, 0x5b, 0xc1, 0x83, 0xf5, +0x50, 0x05, 0x27 +}; + +static const unsigned char pkt236[] = { +0x42, 0x22, 0x00, +0x63, 0x2a, 0xc8, 0x46, 0x0c, +0x5b, 0xd3, 0x45, 0xfd, 0x5a, 0xd3, 0x45, 0xfb, +0x5a, 0xd3, 0x45, 0xf9, 0x5a, 0x41, 0x2e, 0xa1, +0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, 0xbf, 0x02, +0x2e, 0xdd, 0x81, 0x05, 0x27 +}; + +static const unsigned char pkt240[] = { +0x42, 0x50, 0x00, +0x73, 0x2a, 0x07, 0x3d, 0x02, +0x5b, 0x6c, 0x86, 0xc2, 0x23, 0xd3, 0x3c, 0x02, +0x44, 0xd8, 0x2f, 0x1d, 0x5a, 0x02, 0x45, 0xd8, +0x2f, 0x7e, 0x5b, 0x58, 0x23, 0x3c, 0x26, 0x02, +0x55, 0x02, 0x2e, 0x31, 0x84, 0x01, 0x50, 0x02, +0x2e, 0x80, 0x84, 0x07, 0x45, 0xea, 0x5a, 0x41, +0x2e, 0x53, 0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, +0x96, 0xdf, 0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, +0x2e, 0x78, 0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, +0x22, 0x00, 0x54, 0xff, 0xef, 0x2e, 0xaf, 0xd8, +0x2f, 0x62, 0x50 +}; + +static const unsigned char pkt244[] = { +0x67, 0x05, 0x00, 0x00, 0x02, 0x2e, 0x00, 0x70, +0x67, 0x05, 0x00, 0x01, 0x02, 0x2e, 0xe5, 0x71, +0x67, 0x05, 0x00, 0x02, 0x02, 0x2e, 0xa9, 0x72, +0x67, 0x05, 0x00, 0x08, 0x02, 0x2e, 0xb4, 0x73, +0x67, 0x05, 0x00, 0x07, 0x02, 0x2e, 0x29, 0x74, +0x67, 0x05, 0x00, 0x0d, 0x02, 0x2e, 0x26, 0x75, +0x67, 0x05, 0x00, 0x03, 0x02, 0x2e, 0x4d, 0x75, +0x67, 0x05, 0x00, 0x0e, 0x02, 0x2e, 0x29, 0x77, +0x5a, 0x05, 0x00, 0x00, 0xaa, 0x08, 0x67, 0x27, +0x5a, 0x05, 0x00, 0x01, 0xf4, 0x08, 0xfd, 0x27, +0x67, 0x05, 0x00, 0x09, 0x02, 0x2e, 0xe0, 0x78, +0x5a, 0x05, 0x00, 0x02, 0x82, 0x09, 0x58, 0x2a, +0x5a, 0x05, 0x00, 0x03, 0x78, 0x09, 0x63, 0x2a, +0x5a, 0x05, 0x00, 0x04, 0xe1, 0x02, 0x73, 0x2a, +0x0d, +0x42, 0x04, 0x00, 0x73, 0x2a, 0x07, 0x3d +}; + +struct aesX660_cmd aes1660_init_1[] = { + { .cmd = pkt107, .len = sizeof(pkt107) }, + { .cmd = pkt112, .len = sizeof(pkt112) }, + { .cmd = pkt116, .len = sizeof(pkt116) }, + { .cmd = pkt120, .len = sizeof(pkt120) }, + { .cmd = pkt124, .len = sizeof(pkt124) }, + { .cmd = pkt128, .len = sizeof(pkt128) }, + { .cmd = pkt133, .len = sizeof(pkt133) }, + { .cmd = pkt136, .len = sizeof(pkt136) }, + { .cmd = pkt140, .len = sizeof(pkt140) }, + { .cmd = pkt144, .len = sizeof(pkt144) }, + { .cmd = pkt148, .len = sizeof(pkt148) }, + { .cmd = pkt152, .len = sizeof(pkt152) }, + { .cmd = pkt156, .len = sizeof(pkt156) }, + { .cmd = pkt160, .len = sizeof(pkt160) }, + { .cmd = pkt164, .len = sizeof(pkt164) }, + { .cmd = pkt168, .len = sizeof(pkt168) }, + { .cmd = pkt172, .len = sizeof(pkt172) }, + { .cmd = pkt176, .len = sizeof(pkt176) }, + { .cmd = pkt180, .len = sizeof(pkt180) }, + { .cmd = pkt184, .len = sizeof(pkt184) }, + { .cmd = pkt188, .len = sizeof(pkt188) }, + { .cmd = pkt192, .len = sizeof(pkt192) }, + { .cmd = pkt196, .len = sizeof(pkt196) }, + { .cmd = pkt200, .len = sizeof(pkt200) }, + { .cmd = pkt204, .len = sizeof(pkt204) }, + { .cmd = pkt208, .len = sizeof(pkt208) }, + { .cmd = pkt212, .len = sizeof(pkt212) }, + { .cmd = pkt216, .len = sizeof(pkt216) }, + { .cmd = pkt220, .len = sizeof(pkt220) }, + { .cmd = pkt224, .len = sizeof(pkt224) }, + { .cmd = pkt228, .len = sizeof(pkt228) }, + { .cmd = pkt232, .len = sizeof(pkt232) }, + { .cmd = pkt236, .len = sizeof(pkt236) }, + { .cmd = pkt240, .len = sizeof(pkt240) }, + { .cmd = pkt244, .len = sizeof(pkt244) }, +}; + +/* INIT1 is over, 0x07 cmd returns + * { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x23 } + */ + +/* Second init sequence + * INIT2 */ +static const unsigned char pkt433[] = { +0x0d, +0x23, +0x42, 0xca, 0x00, +0x00, 0x20, 0x23, +0xff, 0x3f, 0x1d, 0x40, 0x19, 0xc1, 0x2e, 0xa3, +0xbf, 0xc2, 0x2e, 0x00, 0xdf, 0xff, 0x2d, 0x02, +0x5a, 0xbf, 0x22, 0xc1, 0x2e, 0xa3, 0xbf, 0x02, +0xcf, 0x0f, 0x1c, 0x10, 0x18, 0x26, 0x83, 0xc8, +0x46, 0x00, 0x5b, 0x01, 0x0c, 0x57, 0x23, 0x3c, +0x23, 0xf9, 0x34, 0x6b, 0x81, 0x64, 0xef, 0x64, +0xaf, 0xdf, 0xef, 0x27, 0xff, 0xd6, 0xaf, 0xd7, +0xbf, 0x46, 0xef, 0x46, 0xaf, 0x2a, 0xef, 0x2a, +0xaf, 0x05, 0x81, 0x05, 0x27, 0x9c, 0xcf, 0xdf, +0x96, 0xfe, 0xef, 0x27, 0xff, 0x19, 0x27, 0x65, +0xdf, 0xe1, 0x22, 0x1c, 0x55, 0xe0, 0x97, 0xbf, +0x03, 0x19, 0x5e, 0xfe, 0x0c, 0x9f, 0x22, 0x0f, +0xff, 0xe1, 0x22, 0x10, 0x55, 0x20, 0x00, 0x0e, +0x52, 0x82, 0x03, 0x03, 0x53, 0xfe, 0x0d, 0x7f, +0x20, 0xf6, 0x55, 0x08, 0x50, 0x5f, 0x90, 0x82, +0x01, 0x1f, 0x90, 0xc1, 0x97, 0xa0, 0x01, 0x82, +0x01, 0xdf, 0x21, 0x80, 0x03, 0x00, 0x5e, 0x3f, +0x20, 0x29, 0xbf, 0x03, 0x0c, 0x05, 0x27, 0x01, +0x0c, 0x10, 0xff, 0x29, 0xbf, 0x05, 0x27, 0x9a, +0xcf, 0xdf, 0x96, 0xe0, 0xef, 0x27, 0xff, 0x19, +0x27, 0xfe, 0x0c, 0x9f, 0x22, 0x00, 0xff, 0xe1, +0x22, 0x10, 0x55, 0x20, 0x00, 0x0e, 0x52, 0x82, +0x03, 0x03, 0x53, 0x02, 0x0d, 0x3f, 0x20, 0x0f, +0x1f, 0xf5, 0x55, 0x5f, 0x90, 0x82, 0x01, 0x1f, +0x90, 0xc1, 0x97, 0xa0, 0x01, 0x82, 0x01 +}; + +static const unsigned char pkt440[] = { +0x42, 0xca, 0x00, +0x64, 0x20, 0xdf, 0x21, 0x80, +0x03, 0x02, 0x5e, 0x7f, 0x20, 0x00, 0x53, 0xbf, +0x22, 0x29, 0xcf, 0xbf, 0x03, 0x01, 0x5e, 0x5f, +0x20, 0xdf, 0x9f, 0x28, 0xbf, 0x03, 0x0c, 0x05, +0x27, 0x24, 0xcf, 0x10, 0xdf, 0xbf, 0x01, 0x06, +0x1e, 0xe2, 0x2f, 0x13, 0x5c, 0xdf, 0x2d, 0x00, +0x5b, 0x9f, 0x22, 0xdf, 0x96, 0x9b, 0xef, 0x20, +0xff, 0x1d, 0x00, 0x00, 0x13, 0x1a, 0x27, 0x07, +0x27, 0x9b, 0x22, 0xdf, 0x96, 0xbb, 0xcf, 0x1a, +0x88, 0xbb, 0xcf, 0x1b, 0x88, 0x01, 0x0f, 0xbc, +0xcf, 0x15, 0x88, 0xbc, 0xcf, 0x16, 0x88, 0x01, +0x0f, 0xbd, 0xcf, 0x10, 0x88, 0xbd, 0xcf, 0x11, +0x88, 0x01, 0x0f, 0xbe, 0xcf, 0x0b, 0x88, 0xbe, +0xcf, 0x0c, 0x88, 0x01, 0x0c, 0xdd, 0x97, 0x25, +0xaf, 0x05, 0x27, 0xff, 0x00, 0xab, 0x00, 0x72, +0x00, 0x4c, 0x00, 0x33, 0x00, 0x22, 0x00, 0x09, +0x88, 0xbf, 0x9d, 0x05, 0x27, 0x09, 0x27, 0x05, +0x88, 0xff, 0x97, 0x09, 0x27, 0xf6, 0x9f, 0x5f, +0x02, 0xbf, 0x9d, 0x05, 0x27, 0x0f, 0x1c, 0xc0, +0x9f, 0x8a, 0x80, 0x80, 0x10, 0x00, 0x13, 0x0f, +0x1d, 0xc1, 0x03, 0x00, 0x5f, 0x7f, 0x90, 0x05, +0x27, 0x53, 0x80, 0x2b, 0x0d, 0x05, 0x27, 0x9f, +0x22, 0x8f, 0xaf, 0x67, 0x2e, 0xe0, 0xdf, 0x04, +0x1e, 0x00, 0x52, 0x8f, 0x30, 0x67, 0x2e, 0xe1, +0xdf, 0xdf, 0x22, 0x00, 0x54, 0x8f, 0x30, 0x67, +0x2e, 0xfe, 0xdf, 0x04, 0x1e +}; + +static const unsigned char pkt444[] = { +0x42, 0xca, 0x00, +0xc8, 0x20, 0x00, 0x52, 0x8f, +0x31, 0x67, 0x2e, 0xff, 0xdf, 0xdf, 0x22, 0x00, +0x54, 0x8f, 0x31, 0x8f, 0xcf, 0x03, 0x1c, 0x03, +0x1e, 0x00, 0x55, 0x0c, 0x27, 0x0d, 0x27, 0x4a, +0xcf, 0xdf, 0x96, 0x10, 0xcf, 0x5f, 0xdf, 0xbf, +0x03, 0x02, 0x5f, 0x5f, 0xcf, 0x10, 0xaf, 0x04, +0x50, 0x5e, 0xdf, 0xbf, 0x03, 0x01, 0x53, 0x5e, +0xcf, 0x10, 0xaf, 0x46, 0x88, 0x01, 0x2e, 0x1e, +0x80, 0xdd, 0x97, 0x0a, 0x40, 0x1c, 0x5a, 0x37, +0x43, 0x0b, 0x5b, 0xe2, 0xcf, 0x0f, 0x1c, 0x06, +0x1e, 0x07, 0x52, 0x62, 0xdf, 0x18, 0x1f, 0x07, +0x53, 0x04, 0x16, 0xe2, 0xaf, 0x04, 0x11, 0x62, +0xbf, 0x02, 0x50, 0x62, 0xcf, 0xdf, 0x22, 0x0e, +0x54, 0x0e, 0x88, 0x62, 0xdf, 0xbf, 0x03, 0x04, +0x53, 0x62, 0xaf, 0xdf, 0x01, 0xe2, 0xcf, 0x3f, +0x00, 0xe2, 0xaf, 0x0e, 0x88, 0x4a, 0xdf, 0x3f, +0x00, 0x4a, 0xaf, 0x00, 0x2e, 0xc4, 0x8d, 0x05, +0x27, 0xff, 0xef, 0x4a, 0xdf, 0xbf, 0x01, 0x0a, +0x88, 0xa1, 0x27, 0x5f, 0x21, 0x7f, 0x20, 0xfb, +0x55, 0x05, 0x27, 0x62, 0xcf, 0x03, 0x88, 0x1f, +0x22, 0x7f, 0x20, 0xfc, 0x55, 0x05, 0x27, 0x10, +0xdf, 0x02, 0x1f, 0x02, 0x5e, 0x04, 0xff, 0x00, +0x2e, 0x0a, 0x50, 0x05, 0x1f, 0x02, 0x5e, 0x03, +0xff, 0x00, 0x2e, 0x05, 0x50, 0x06, 0x1f, 0x02, +0x5e, 0x02, 0xff, 0x00, 0x2e, 0x00, 0x50, 0x01, +0xff, 0x05, 0x27, 0x10, 0xcf +}; + +static const unsigned char pkt448[] = { +0x42, 0xca, 0x00, +0x2c, 0x21, 0x33, 0xff, 0x3f, +0x00, 0x21, 0xff, 0x00, 0x13, 0x1a, 0x27, 0x07, +0x27, 0x05, 0x27, 0x01, 0x00, 0x02, 0x57, 0x42, +0x87, 0x52, 0x80, 0x92, 0x81, 0xd2, 0x6c, 0xe2, +0x80, 0xf2, 0x80, 0xf6, 0x7b, 0xfa, 0x7e, 0xfe, +0x8b, 0xf9, 0x45, 0x04, 0x5a, 0x40, 0xef, 0xf9, +0x44, 0x03, 0x5b, 0x80, 0xef, 0x01, 0x50, 0x41, +0x2e, 0x7e, 0xdf, 0x4d, 0xaf, 0x05, 0x27, 0x28, +0xff, 0x54, 0xef, 0x19, 0x27, 0x4d, 0x26, 0xe1, +0x2f, 0x28, 0x54, 0x27, 0xff, 0xe0, 0xef, 0x1b, +0x27, 0x10, 0xef, 0x06, 0xaf, 0xfc, 0x97, 0xfc, +0x9f, 0x1c, 0x82, 0x1c, 0x82, 0x1a, 0x27, 0x4d, +0xdf, 0x6d, 0x80, 0x5f, 0x9f, 0x06, 0x25, 0xf5, +0x55, 0x05, 0x27, 0x26, 0x1f, 0x00, 0x5f, 0xbf, +0x22, 0xff, 0x96, 0x6c, 0xef, 0x21, 0xff, 0x1d, +0x00, 0x00, 0x13, 0x1a, 0x27, 0x07, 0x27, 0x1a, +0x27, 0xd6, 0x97, 0x05, 0x27, 0xa3, 0x01, 0xa4, +0x01, 0xa3, 0x01, 0x2e, 0x00, 0xb0, 0x00, 0xb1, +0x00, 0xb2, 0x00, 0xb3, 0x00, 0xb4, 0x00, 0xb5, +0x00, 0xb6, 0x00, 0xb7, 0x00, 0xb8, 0x00, 0xb9, +0x00, 0xba, 0x00, 0x56, 0x00, 0xae, 0x00, 0x54, +0x01, 0x44, 0x01, 0x55, 0x01, 0x44, 0x01, 0xbb, +0x00, 0xbc, 0x00, 0xbd, 0x00, 0xbe, 0x00, 0x83, +0x00, 0x84, 0x00, 0x81, 0x00, 0x82, 0x00, 0x24, +0x00, 0x44, 0x01, 0xdb, 0x00, 0xdc, 0x00, 0xdd, +0x00, 0xde, 0x00, 0x04, 0x00 +}; + +static const unsigned char pkt452[] = { +0x42, 0x52, 0x00, +0x90, 0x21, 0x9b, 0x00, 0x99, +0x00, 0x9e, 0x00, 0x10, 0xef, 0xe6, 0x81, 0x65, +0xaf, 0x10, 0xef, 0xe6, 0x81, 0x9c, 0xaf, 0x10, +0xef, 0xe6, 0x81, 0x9a, 0xaf, 0x05, 0x27, 0xe5, +0x31, 0x1d, 0x81, 0xe5, 0x39, 0x05, 0x27, 0xc8, +0x46, 0x0b, 0x5b, 0xd3, 0x45, 0xfd, 0x5a, 0xd3, +0x45, 0xfb, 0x5a, 0xd3, 0x45, 0xf9, 0x5a, 0x41, +0x2e, 0xa1, 0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, +0xbf, 0x00, 0x88, 0x05, 0x27, 0x9f, 0x22, 0xbf, +0x22, 0x1f, 0x20, 0xfd, 0x53, 0x3f, 0x20, 0x14, +0x1f, 0xfa, 0x55, 0x05, 0x27 +}; + +static const unsigned char pkt456[] = { +0x42, 0xca, 0x00, +0xb8, 0x21, 0x25, 0x85, 0x01, +0x1e, 0x17, 0x55, 0x1b, 0x8a, 0x41, 0x2e, 0x53, +0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, 0x96, 0xdf, +0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, 0x2e, 0x78, +0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, 0x22, 0x00, +0x54, 0xff, 0xef, 0x2e, 0xaf, 0x05, 0x27, 0x07, +0x80, 0x9f, 0x22, 0xff, 0xaf, 0x00, 0x2e, 0x5d, +0x89, 0x05, 0x27, 0x06, 0x1e, 0x01, 0x55, 0x0f, +0x27, 0x01, 0x70, 0x0a, 0x1e, 0x0a, 0x55, 0x00, +0x88, 0x66, 0x76, 0x02, 0x46, 0x00, 0x5b, 0x08, +0x3b, 0x3b, 0x30, 0x07, 0x35, 0xff, 0xff, 0xc2, +0xbf, 0x0d, 0x27, 0x0c, 0x27, 0x0d, 0x1e, 0x02, +0x55, 0x28, 0x85, 0xf2, 0x5b, 0x7b, 0x76, 0x12, +0x1e, 0x07, 0x55, 0xdc, 0xef, 0x05, 0xff, 0x1a, +0x27, 0x56, 0xdf, 0x3f, 0x20, 0x6d, 0x80, 0x3c, +0xaf, 0x05, 0x27, 0x13, 0x1e, 0x01, 0x55, 0x3c, +0x23, 0x05, 0x27, 0x1f, 0x1e, 0x06, 0x55, 0x37, +0x35, 0x08, 0xef, 0x40, 0x2e, 0xf0, 0xbf, 0x40, +0x2e, 0xf6, 0xbf, 0x05, 0x27, 0x20, 0x1e, 0x06, +0x55, 0x37, 0x3d, 0x16, 0xef, 0x40, 0x2e, 0xf0, +0xbf, 0x40, 0x2e, 0xf6, 0xbf, 0x05, 0x27, 0x22, +0x1e, 0x19, 0x55, 0x21, 0xef, 0x08, 0xaf, 0x09, +0x23, 0x01, 0xef, 0x0b, 0xaf, 0x31, 0xef, 0x0a, +0xaf, 0x81, 0xcf, 0x10, 0xaf, 0xbf, 0x8e, 0x82, +0xcf, 0x4a, 0xaf, 0x00, 0x2e, 0xc4, 0x8d, 0x08, +0xef, 0x9b, 0xaf, 0x99, 0xaf +}; + +static const unsigned char pkt460[] = { +0x42, 0x34, 0x00, +0x1c, 0x22, 0x02, 0xcf, 0x0f, +0x1c, 0x40, 0x18, 0x37, 0x31, 0x02, 0xaf, 0xe2, +0x23, 0x08, 0xef, 0xe3, 0xaf, 0x05, 0x27, 0x23, +0x1e, 0x0c, 0x55, 0x00, 0xef, 0x02, 0xff, 0x19, +0x27, 0xbf, 0x22, 0x20, 0xef, 0x7f, 0x9f, 0x5f, +0x20, 0xfc, 0x55, 0xf0, 0x81, 0x9f, 0x22, 0x41, +0x2e, 0xa3, 0xbf, 0x05, 0x27, 0xcb, 0x74 +}; + +static const unsigned char pkt464[] = { +0x42, 0xca, 0x00, +0x35, 0x22, 0x25, 0x85, 0x44, +0x1e, 0x01, 0x55, 0xe2, 0x2f, 0xf1, 0x50, 0x49, +0x1e, 0x0d, 0x55, 0x37, 0x39, 0x01, 0xef, 0x72, +0x88, 0x00, 0x2e, 0x45, 0x8d, 0x6b, 0x81, 0x08, +0x42, 0x03, 0x5b, 0x3d, 0x23, 0x9f, 0x22, 0x00, +0x2e, 0xb2, 0x8b, 0xd3, 0x3b, 0x05, 0x27, 0x4a, +0x1e, 0x01, 0x55, 0xe2, 0x2f, 0xdd, 0x50, 0x4e, +0x1e, 0x01, 0x55, 0x00, 0x2e, 0xbb, 0x79, 0x55, +0x1e, 0x16, 0x55, 0x28, 0x85, 0xe2, 0x2f, 0xd4, +0x5b, 0x07, 0xef, 0x20, 0x80, 0xe2, 0x2f, 0xd0, +0x5a, 0xfe, 0xcf, 0x0a, 0xaf, 0xfe, 0xcf, 0xfe, +0xcf, 0x41, 0x2e, 0x44, 0xbf, 0xfe, 0xcf, 0x41, +0x2e, 0x45, 0xbf, 0xfe, 0xcf, 0x52, 0xaf, 0xfe, +0xcf, 0x53, 0xaf, 0xfe, 0xcf, 0x5a, 0xaf, 0x05, +0x27, 0x58, 0x1e, 0x0d, 0x55, 0x02, 0x44, 0x01, +0x5a, 0x00, 0x2e, 0x07, 0x78, 0xfe, 0xcf, 0x75, +0xaf, 0xfe, 0xdf, 0x76, 0xbf, 0x41, 0x2e, 0xa4, +0xdf, 0xdf, 0x29, 0x41, 0x2e, 0xa4, 0xbf, 0x05, +0x27, 0x59, 0x1e, 0x02, 0x55, 0xfe, 0xcf, 0x10, +0xaf, 0x54, 0x7e, 0x63, 0x1e, 0x1a, 0x55, 0x28, +0x85, 0xe2, 0x2f, 0xa6, 0x5b, 0x0c, 0xef, 0x20, +0x80, 0xe2, 0x2f, 0xa2, 0x5a, 0xf0, 0xef, 0x00, +0xff, 0x19, 0x27, 0x08, 0xef, 0x06, 0xaf, 0xfe, +0xcf, 0x5f, 0x9f, 0x06, 0x25, 0xfb, 0x55, 0xfe, +0xcf, 0xfe, 0xcf, 0x41, 0x2e, 0x40, 0xbf, 0xfe, +0xcf, 0x41, 0x2e, 0x41, 0xbf +}; + +static const unsigned char pkt468[] = { +0x42, 0x46, 0x00, +0x99, 0x22, 0xfe, 0xcf, 0x41, +0x2e, 0x42, 0xbf, 0x05, 0x27, 0x66, 0x1e, 0x0b, +0x55, 0x33, 0xef, 0x21, 0xff, 0x1a, 0x27, 0x0b, +0xef, 0x06, 0xaf, 0xfe, 0xcf, 0xfe, 0xdf, 0x06, +0x27, 0x01, 0x0e, 0x06, 0x25, 0xf9, 0x55, 0x05, +0x27, 0x35, 0x74, 0xff, 0x96, 0xc6, 0x2e, 0x01, +0xdf, 0x3f, 0x2c, 0xdd, 0x9f, 0x05, 0x27, 0xf9, +0x35, 0xc1, 0x2e, 0x4e, 0xdf, 0x0f, 0x1d, 0x09, +0x27, 0x5f, 0x02, 0xc1, 0x2e, 0x4e, 0xbf, 0x05, +0x27 +}; + +static const unsigned char pkt472[] = { +0x42, 0xca, 0x00, +0xbb, 0x22, 0x09, 0x46, 0x0b, +0x5b, 0x08, 0x31, 0xf2, 0xcf, 0x0b, 0xaf, 0x15, +0xef, 0xf4, 0xaf, 0x30, 0xef, 0x0a, 0xaf, 0x44, +0xef, 0xfa, 0xaf, 0x10, 0xef, 0xf8, 0xaf, 0x5c, +0x88, 0x37, 0xcf, 0xdf, 0x96, 0x08, 0xcf, 0xdf, +0x96, 0x3d, 0xcf, 0xdf, 0x96, 0x00, 0x2e, 0xd4, +0x8d, 0xdd, 0x97, 0x3d, 0xaf, 0xdd, 0x97, 0x08, +0xaf, 0xdd, 0x97, 0x37, 0xaf, 0xa0, 0xcf, 0xbf, +0x1c, 0xa0, 0xaf, 0x05, 0x81, 0xfb, 0x39, 0x08, +0x45, 0x00, 0x5a, 0xfb, 0x31, 0x0a, 0x42, 0x00, +0x5b, 0xa2, 0x39, 0x02, 0xcf, 0x5c, 0xaf, 0xe1, +0xef, 0x40, 0x2e, 0x95, 0xbf, 0x9f, 0x22, 0x25, +0xaf, 0x69, 0xaf, 0x6a, 0xaf, 0x16, 0xaf, 0x40, +0x2e, 0x96, 0xbf, 0x29, 0xaf, 0x02, 0x47, 0x06, +0x5a, 0x0a, 0x41, 0x04, 0x5a, 0x0a, 0xdf, 0x30, +0x1d, 0x30, 0x1f, 0x00, 0x54, 0x01, 0xef, 0x44, +0xaf, 0x09, 0xef, 0x60, 0xaf, 0x08, 0x45, 0x0a, +0x40, 0x06, 0x5a, 0x10, 0xcf, 0x27, 0xaf, 0xe2, +0x23, 0x6e, 0x23, 0x08, 0xef, 0xe3, 0xaf, 0x6f, +0xaf, 0xce, 0x8d, 0x5d, 0xcf, 0x30, 0x1c, 0x00, +0x1e, 0x07, 0x55, 0xf8, 0xcf, 0x5f, 0x2b, 0x9f, +0x29, 0xf8, 0xaf, 0xa1, 0xcf, 0xc1, 0x1c, 0xa1, +0xaf, 0x09, 0x50, 0x10, 0x1e, 0x07, 0x55, 0xf8, +0xcf, 0x5f, 0x29, 0x9f, 0x2b, 0xf8, 0xaf, 0xa1, +0xcf, 0xc1, 0x1c, 0x08, 0x18, 0xa1, 0xaf, 0x41, +0x2e, 0xa4, 0xdf, 0xdf, 0x2d +}; + +static const unsigned char pkt476[] = { +0x42, 0x3a, 0x00, +0x1f, 0x23, 0x04, 0x5b, 0x75, +0xcf, 0xf4, 0xaf, 0x76, 0xcf, 0xf5, 0xaf, 0x00, +0x50, 0x0f, 0x88, 0xe2, 0x23, 0x08, 0xef, 0xe3, +0xaf, 0x81, 0x82, 0x4d, 0xaf, 0xdf, 0x96, 0x64, +0xdf, 0x93, 0x82, 0x93, 0xbf, 0xdd, 0x97, 0x77, +0xff, 0x93, 0x82, 0x94, 0xbf, 0x9e, 0x23, 0xe4, +0x23, 0x05, 0x27, 0x14, 0xef, 0xf4, 0xaf, 0x00, +0xef, 0xf5, 0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt480[] = { +0x42, 0xca, 0x00, +0x3b, 0x23, 0xfe, 0xcf, 0x58, +0xaf, 0xfe, 0xcf, 0xfe, 0xdf, 0x00, 0x2e, 0xa9, +0x8b, 0xfe, 0xcf, 0x3c, 0xaf, 0x07, 0x3d, 0x58, +0x40, 0x4a, 0x5a, 0x3c, 0x26, 0x48, 0x55, 0x37, +0x45, 0x46, 0x5a, 0xe0, 0x88, 0x44, 0x5a, 0x77, +0x88, 0x00, 0x2e, 0xd1, 0x8b, 0xfe, 0xef, 0x16, +0x80, 0x02, 0xcf, 0xdf, 0x96, 0x61, 0xef, 0xc0, +0xaf, 0x04, 0x27, 0xc1, 0x46, 0x04, 0x5b, 0xc0, +0x3e, 0x40, 0xef, 0xc1, 0xaf, 0x01, 0x2e, 0x94, +0x84, 0xd0, 0x41, 0x06, 0x5b, 0x2d, 0x88, 0xf3, +0x5b, 0x6c, 0x86, 0xdd, 0x97, 0x1f, 0x2d, 0x05, +0x5b, 0x03, 0x50, 0x01, 0x0c, 0x02, 0xcf, 0xc0, +0x1c, 0x00, 0x55, 0x05, 0x88, 0xc0, 0x23, 0x20, +0xef, 0xc1, 0xaf, 0x00, 0x2e, 0xf0, 0x8b, 0x05, +0x27, 0x9b, 0x22, 0x37, 0x45, 0x05, 0x5a, 0x41, +0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x04, 0x5b, 0x00, +0x28, 0x02, 0x50, 0x3b, 0x43, 0x00, 0x5b, 0x00, +0x28, 0xd3, 0xdf, 0xc6, 0x2e, 0x15, 0xbf, 0xd3, +0x3c, 0x40, 0xef, 0x09, 0x80, 0xdd, 0x97, 0xff, +0xaf, 0x00, 0x2e, 0x5d, 0x89, 0xc6, 0x2e, 0x15, +0xdf, 0x10, 0x1d, 0xd3, 0xcf, 0x3f, 0x02, 0xd3, +0xaf, 0x05, 0x27, 0xc1, 0x83, 0x07, 0x45, 0x05, +0x27, 0x3d, 0x23, 0x07, 0x3d, 0x02, 0xcf, 0xdf, +0x96, 0x2e, 0x88, 0x26, 0x88, 0xfe, 0xef, 0x16, +0x80, 0x05, 0xef, 0xc0, 0xaf, 0x04, 0x27, 0xd0, +0x41, 0x02, 0x5b, 0xee, 0x8f +}; + +static const unsigned char pkt484[] = { +0x42, 0xca, 0x00, +0x9f, 0x23, 0xfa, 0x5b, 0xbf, +0x50, 0x31, 0x82, 0x04, 0xef, 0xc1, 0xaf, 0x9b, +0x22, 0x41, 0x88, 0xdd, 0x97, 0xdf, 0x22, 0x02, +0x55, 0x58, 0x40, 0x02, 0x5a, 0x09, 0x50, 0x58, +0x40, 0x07, 0x5a, 0xdd, 0x97, 0x1f, 0x2d, 0xb8, +0x5a, 0x7a, 0x88, 0xb7, 0x5b, 0x9b, 0x22, 0xc7, +0x8f, 0xb4, 0x50, 0x75, 0x88, 0xdc, 0x5b, 0xb7, +0x8f, 0x58, 0x41, 0x01, 0x5b, 0x01, 0x0c, 0xad, +0x7f, 0xd6, 0x50, 0x41, 0x2e, 0x52, 0xdf, 0xed, +0x1c, 0x04, 0x18, 0x41, 0x2e, 0x52, 0xbf, 0x05, +0x27, 0x00, 0x2e, 0xb9, 0x8b, 0xae, 0xdf, 0xe0, +0x19, 0xae, 0xbf, 0x57, 0x40, 0x00, 0x5b, 0xa1, +0x32, 0x57, 0x43, 0x00, 0x5b, 0xae, 0x3f, 0x05, +0x81, 0x05, 0x27, 0x41, 0x2e, 0x52, 0xdf, 0x03, +0x18, 0x41, 0x2e, 0x52, 0xbf, 0x05, 0x27, 0xd3, +0xdf, 0xff, 0x96, 0x9b, 0x22, 0x0b, 0x88, 0xd3, +0x3c, 0x07, 0x80, 0xdd, 0x97, 0xff, 0xaf, 0x00, +0x2e, 0x5d, 0x89, 0xdd, 0x9f, 0x10, 0x1d, 0xd3, +0xcf, 0x3f, 0x02, 0xd3, 0xaf, 0x05, 0x27, 0x37, +0x45, 0x0e, 0x5a, 0x40, 0x88, 0x0c, 0x5a, 0xd7, +0x8f, 0x00, 0x2e, 0xd7, 0x8b, 0x00, 0x2e, 0xeb, +0x8b, 0x41, 0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x00, +0x5b, 0x00, 0x28, 0x00, 0x2e, 0xf0, 0x8b, 0x05, +0x27, 0xf9, 0xcf, 0xdf, 0x96, 0xf9, 0x3d, 0x00, +0x2e, 0xd1, 0x8d, 0x28, 0xff, 0xa7, 0xef, 0xe1, +0xbf, 0xe0, 0xaf, 0x09, 0xef +}; + +static const unsigned char pkt488[] = { +0x42, 0x6c, 0x00, +0x03, 0x24, 0x10, 0xaf, 0xcf, +0x8c, 0x05, 0x81, 0x01, 0x2e, 0x54, 0x80, 0x01, +0x2e, 0x56, 0x80, 0x20, 0x82, 0x3c, 0x8d, 0x37, +0x82, 0x26, 0x37, 0x00, 0x5a, 0x0c, 0x50, 0xff, +0x96, 0xdf, 0x96, 0x79, 0xcf, 0x7a, 0xdf, 0xff, +0x96, 0xdf, 0x96, 0xc2, 0x97, 0xc3, 0x9f, 0x9d, +0x01, 0x5d, 0x01, 0x07, 0x53, 0xdd, 0x97, 0xdd, +0x9f, 0x79, 0xaf, 0x7a, 0xbf, 0x3b, 0x3b, 0xdd, +0x97, 0xf9, 0xaf, 0x05, 0x27, 0xff, 0x22, 0x01, +0x55, 0x32, 0x1e, 0xf3, 0x5f, 0x02, 0x0c, 0xf6, +0x8f, 0x3b, 0x33, 0x00, 0x28, 0x05, 0x27, 0x0d, +0x27, 0x3c, 0x26, 0x07, 0x54, 0x3c, 0xcf, 0x3d, +0xdf, 0x3f, 0x20, 0x3d, 0xbf, 0xdf, 0x03, 0x01, +0x52, 0x3d, 0x23, 0x0c, 0x27, 0x0d, 0x27 +}; + +static const unsigned char pkt492[] = { +0x42, 0x9c, 0x00, +0x38, 0x24, 0x08, 0x44, 0x12, +0x5a, 0x07, 0x40, 0x01, 0x5b, 0x4f, 0x80, 0x00, +0x50, 0x53, 0x80, 0x27, 0x0d, 0x25, 0xcf, 0x1f, +0x98, 0x29, 0xcf, 0x09, 0x27, 0x28, 0xdf, 0x3f, +0x02, 0x5f, 0x98, 0x62, 0xcf, 0xdf, 0x98, 0xd9, +0x0d, 0x02, 0x0d, 0x00, 0x2e, 0xd5, 0x7f, 0x05, +0x27, 0x08, 0x44, 0x22, 0x5a, 0x07, 0x40, 0x01, +0x5b, 0x4f, 0x80, 0x00, 0x50, 0x53, 0x80, 0x0b, +0x0d, 0x07, 0x40, 0x1b, 0x5a, 0x44, 0xcf, 0x1f, +0x20, 0x44, 0xaf, 0x5f, 0x9f, 0xc1, 0x2e, 0x57, +0xdf, 0xff, 0x96, 0x41, 0x2e, 0x56, 0xdf, 0xdf, +0x96, 0x41, 0x2e, 0x58, 0xdf, 0xc1, 0x2e, 0x59, +0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, 0x96, 0xdf, +0x96, 0x40, 0x2e, 0x59, 0xdf, 0x5f, 0x9f, 0x50, +0xdf, 0x7f, 0x9f, 0x1d, 0x00, 0xdd, 0x00, 0x5f, +0x9f, 0x7f, 0x9f, 0x05, 0x27, 0x01, 0x0d, 0x41, +0x2e, 0x56, 0xdf, 0x5f, 0x9f, 0x41, 0x2e, 0x57, +0xdf, 0x5f, 0x9f, 0x41, 0x2e, 0x58, 0xdf, 0x5f, +0x9f, 0x41, 0x2e, 0x59, 0xdf, 0x5f, 0x9f, 0x06, +0x0d, 0x3b, 0xcf, 0x5f, 0x9f, 0x05, 0x27 +}; + +static const unsigned char pkt496[] = { +0x42, 0xca, 0x00, +0x85, 0x24, 0x02, 0x2e, 0x23, +0x80, 0x02, 0x2e, 0x4c, 0x80, 0x99, 0x88, 0x37, +0x41, 0xdd, 0x2f, 0xc1, 0x5a, 0x0a, 0x40, 0x11, +0x5a, 0x1f, 0x88, 0x41, 0x88, 0x4d, 0x88, 0x37, +0x42, 0x08, 0x5a, 0x09, 0x46, 0x0a, 0x5b, 0x23, +0x26, 0x08, 0x55, 0x22, 0xcf, 0xc6, 0x1e, 0x09, +0x52, 0x10, 0xcf, 0x27, 0xaf, 0x6e, 0x23, 0x08, +0xef, 0x6f, 0xaf, 0x62, 0x23, 0x6e, 0x26, 0x00, +0x55, 0x6e, 0x24, 0x05, 0x27, 0x67, 0x2e, 0xff, +0xdf, 0xdf, 0x22, 0x00, 0x2e, 0x25, 0x55, 0x67, +0x2e, 0xfe, 0xdf, 0xdf, 0x22, 0x00, 0x2e, 0x20, +0x55, 0x05, 0x27, 0x61, 0x23, 0x67, 0x2e, 0xff, +0xdf, 0xdf, 0x22, 0x00, 0x2e, 0x19, 0x55, 0x67, +0x2e, 0xfe, 0xdf, 0x65, 0xdf, 0xbf, 0x03, 0x00, +0x2e, 0x13, 0x5e, 0x3b, 0x43, 0x01, 0x5a, 0x3b, +0x41, 0x0e, 0x5a, 0x29, 0xdf, 0xff, 0x96, 0x25, +0xdf, 0x5d, 0x00, 0x10, 0x1f, 0x00, 0x2e, 0x08, +0x53, 0x07, 0x1f, 0x05, 0x53, 0x61, 0x24, 0x3b, +0x41, 0x02, 0x5a, 0x03, 0x1f, 0x00, 0x53, 0x61, +0x24, 0x05, 0x27, 0xff, 0xef, 0x61, 0xaf, 0x05, +0x27, 0x3b, 0x43, 0x09, 0x5b, 0x28, 0xdf, 0x6e, +0xbf, 0x70, 0xef, 0xbf, 0x22, 0x1a, 0x27, 0x29, +0xdf, 0x6e, 0xcf, 0xdf, 0x01, 0x6d, 0x80, 0x6f, +0xaf, 0x05, 0x27, 0x62, 0x26, 0x01, 0x54, 0x61, +0x47, 0x1d, 0x5b, 0x10, 0xdf, 0x27, 0xbf, 0x61, +0xcf, 0xdf, 0x22, 0x18, 0x54 +}; + +static const unsigned char pkt500[] = { +0x42, 0xca, 0x00, +0xe9, 0x24, 0x5f, 0x00, 0x00, +0x57, 0xbf, 0x22, 0x5f, 0xcf, 0xdf, 0x03, 0x00, +0x5f, 0x5f, 0xdf, 0x27, 0xbf, 0x61, 0xcf, 0xdf, +0x2d, 0x00, 0x2e, 0x19, 0x5a, 0x26, 0x88, 0xdf, +0x96, 0x6e, 0xdf, 0x09, 0x88, 0x6e, 0xbf, 0xc0, +0x97, 0x62, 0xdf, 0x05, 0x88, 0x62, 0xbf, 0x6f, +0xdf, 0xdd, 0x97, 0x06, 0x88, 0x6f, 0xaf, 0x05, +0x27, 0x8a, 0x80, 0x20, 0x10, 0x00, 0x13, 0x1c, +0x82, 0x05, 0x27, 0xdf, 0x96, 0x9f, 0x22, 0xd9, +0x81, 0x1a, 0x27, 0xdd, 0x9f, 0x6d, 0x80, 0x05, +0x27, 0x0c, 0x88, 0xdf, 0x96, 0x6f, 0xdf, 0xef, +0x8f, 0x6f, 0xbf, 0x6e, 0xdf, 0xc0, 0x97, 0xf0, +0x8f, 0x6e, 0xaf, 0x62, 0xdf, 0xdd, 0x97, 0xec, +0x8f, 0x62, 0xaf, 0x05, 0x27, 0x27, 0xcf, 0x61, +0x47, 0x00, 0x5b, 0x1f, 0x20, 0x09, 0x8c, 0xff, +0x97, 0x05, 0x27, 0x28, 0xdf, 0x06, 0x88, 0x2d, +0xbf, 0x2c, 0xaf, 0x29, 0xdf, 0x02, 0x88, 0x2b, +0xbf, 0x2a, 0xaf, 0x05, 0x27, 0xff, 0x96, 0x72, +0xcf, 0x01, 0x16, 0xdf, 0x96, 0x57, 0xef, 0x25, +0xff, 0x1d, 0x00, 0x00, 0x13, 0x1a, 0x27, 0x07, +0x27, 0xff, 0x96, 0xc1, 0x9f, 0x3f, 0x22, 0x01, +0x11, 0x8a, 0x80, 0xff, 0x96, 0xdf, 0x96, 0xc2, +0x97, 0xc3, 0x9f, 0x3f, 0x22, 0x01, 0x11, 0x8a, +0x80, 0x01, 0x00, 0xdf, 0x9f, 0xc0, 0x97, 0x04, +0x0c, 0xff, 0x96, 0xdf, 0x96, 0x72, 0xcf, 0x07, +0x1e, 0x04, 0x53, 0x03, 0x1e +}; + +static const unsigned char pkt504[] = { +0x42, 0x2a, 0x00, +0x4d, 0x25, 0x04, 0x53, 0xdd, +0x97, 0xdd, 0x9f, 0x05, 0x27, 0x00, 0x88, 0xd8, +0x71, 0xdd, 0x97, 0xdd, 0x9f, 0xd8, 0x81, 0x05, +0x27, 0x00, 0x04, 0x00, 0x02, 0x4e, 0x07, 0x8e, +0x03, 0x19, 0x02, 0x0c, 0x01, 0x32, 0x04, 0x1c, +0x02, 0x0e, 0x01, 0x87, 0x00 +}; + +static const unsigned char pkt508[] = { +0x42, 0x8c, 0x00, +0x61, 0x25, 0x53, 0x80, 0x01, +0x0d, 0xf5, 0x97, 0xff, 0x0d, 0x1f, 0x99, 0x49, +0xcf, 0x5f, 0x99, 0x08, 0x44, 0x00, 0x2e, 0x39, +0x5a, 0x0b, 0x0d, 0x44, 0xcf, 0x0c, 0x41, 0x00, +0x5b, 0x1f, 0x20, 0x44, 0xaf, 0x5f, 0x9f, 0x04, +0x0d, 0x47, 0xcf, 0x5f, 0x9f, 0x48, 0xcf, 0x5f, +0x9f, 0x1c, 0xcf, 0x5f, 0x9f, 0x1d, 0xcf, 0x5f, +0x9f, 0x1e, 0xcf, 0x5f, 0x9f, 0x49, 0xcf, 0x5f, +0x9f, 0x06, 0x0d, 0xe0, 0x97, 0x0f, 0x1c, 0x5f, +0x9f, 0x0a, 0xcf, 0x5f, 0x9f, 0x09, 0xcf, 0x5f, +0x9f, 0x2a, 0xcf, 0x5f, 0x9f, 0x2b, 0xcf, 0x5f, +0x9f, 0x2c, 0xcf, 0x5f, 0x9f, 0x2d, 0xcf, 0x5f, +0x9f, 0x02, 0x0d, 0x16, 0xcf, 0x5f, 0x9f, 0x44, +0xdf, 0x02, 0x2e, 0x5f, 0x81, 0x5f, 0x9f, 0x4d, +0xcf, 0x5f, 0x9f, 0x09, 0x46, 0x04, 0x5b, 0x90, +0xcf, 0x5f, 0x9f, 0x91, 0xcf, 0x5f, 0x9f, 0x05, +0x50, 0x01, 0x0d, 0x6a, 0xcf, 0x09, 0x27, 0x69, +0xdf, 0x3f, 0x02, 0x5f, 0x9f, 0x05, 0x27 +}; + +static const unsigned char pkt512[] = { +0x42, 0xca, 0x00, +0xa6, 0x25, 0x5c, 0x46, 0x00, +0x5b, 0xfb, 0x31, 0x2d, 0x8a, 0xa9, 0x89, 0xbe, +0x89, 0x06, 0x8a, 0x18, 0x89, 0x18, 0x89, 0x40, +0xcf, 0x41, 0xdf, 0x45, 0xaf, 0x46, 0xbf, 0x07, +0x38, 0x01, 0x5b, 0x01, 0x2e, 0xb7, 0x80, 0x3b, +0x40, 0x00, 0x2e, 0x42, 0x5b, 0x5c, 0x47, 0x00, +0x5a, 0xad, 0x89, 0x09, 0x46, 0x00, 0x5b, 0x75, +0x8d, 0xc9, 0x30, 0x41, 0x2e, 0x7a, 0xdf, 0x1f, +0x28, 0x41, 0x2e, 0x7a, 0xbf, 0xfb, 0x39, 0xfa, +0x33, 0xc8, 0x46, 0x10, 0x5b, 0xd0, 0x46, 0xfd, +0x5b, 0xd3, 0x45, 0xfd, 0x5a, 0xd3, 0x45, 0xfb, +0x5a, 0xd3, 0x45, 0xf9, 0x5a, 0xd3, 0x3c, 0x41, +0x2e, 0xa1, 0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, +0xbf, 0x02, 0x2e, 0xb0, 0x81, 0x0c, 0x78, 0x64, +0x81, 0xd3, 0x45, 0xe9, 0x5a, 0xd3, 0x3c, 0xc8, +0xcf, 0xdf, 0x22, 0x02, 0x55, 0xc7, 0xcf, 0xdf, +0x22, 0x02, 0x54, 0xd3, 0x33, 0xd3, 0x31, 0x64, +0x81, 0xf7, 0xef, 0x16, 0x80, 0xf8, 0xcf, 0x9f, +0x1c, 0xf8, 0xaf, 0xfb, 0x39, 0xfa, 0x33, 0x5c, +0x47, 0x03, 0x5a, 0x08, 0x43, 0xdc, 0x2f, 0xec, +0x5a, 0x02, 0x50, 0x3d, 0x23, 0xdc, 0x2f, 0xe8, +0x50, 0x02, 0xcf, 0x0f, 0x1c, 0x10, 0x18, 0x02, +0xaf, 0xe1, 0x72, 0x5c, 0x46, 0x01, 0x5a, 0x01, +0x2e, 0xcd, 0x80, 0xd0, 0x41, 0x00, 0x5b, 0xc1, +0x83, 0x52, 0x26, 0xe6, 0x2f, 0xbd, 0x55, 0x53, +0x26, 0xe6, 0x2f, 0xba, 0x55 +}; + +static const unsigned char pkt516[] = { +0x42, 0xca, 0x00, +0x0a, 0x26, 0x07, 0x3a, 0x00, +0x2e, 0x38, 0x7c, 0x02, 0x2e, 0x49, 0x81, 0x45, +0xcf, 0x46, 0xdf, 0x19, 0x27, 0xef, 0x88, 0x02, +0x89, 0x05, 0x27, 0x12, 0x82, 0x05, 0x27, 0x41, +0x8a, 0x10, 0x5b, 0x49, 0xef, 0xff, 0xaf, 0x05, +0xef, 0xff, 0xaf, 0x9f, 0x22, 0xff, 0xaf, 0x10, +0xef, 0xff, 0xaf, 0x22, 0xcf, 0xff, 0xaf, 0x23, +0xcf, 0xff, 0xaf, 0x9f, 0x22, 0xff, 0xaf, 0xff, +0xaf, 0x02, 0x2e, 0xa1, 0x81, 0x0c, 0x40, 0x29, +0x5b, 0x4a, 0x80, 0x0d, 0x34, 0x10, 0x5a, 0x49, +0xcf, 0x5f, 0x9d, 0x49, 0x38, 0x53, 0x80, 0x49, +0xcf, 0x5f, 0x9d, 0x4a, 0x80, 0x9f, 0x22, 0x1f, +0x9c, 0x5f, 0x9c, 0x1e, 0xcf, 0x1f, 0x9d, 0x48, +0xcf, 0x1d, 0xdf, 0xdf, 0x01, 0x9f, 0x22, 0x11, +0x50, 0xbb, 0x88, 0xf5, 0x97, 0x49, 0xaf, 0xd4, +0x89, 0x49, 0xcf, 0xf7, 0x1c, 0x5f, 0x9d, 0x44, +0xdf, 0x3f, 0x20, 0x44, 0xbf, 0xff, 0x9a, 0x02, +0x2e, 0x5f, 0x81, 0x20, 0x0d, 0x9f, 0x99, 0xe0, +0x0d, 0x1c, 0xcf, 0x1d, 0xdf, 0x9f, 0x9c, 0xff, +0x9c, 0x00, 0x2e, 0xe9, 0x8f, 0x0c, 0x41, 0x01, +0x5b, 0x00, 0x2e, 0xeb, 0x8f, 0x0c, 0x42, 0x04, +0x5b, 0xe4, 0x40, 0x01, 0x5a, 0xe4, 0x3a, 0x00, +0x50, 0xe4, 0x32, 0x0c, 0x43, 0x04, 0x5b, 0xe4, +0x42, 0x01, 0x5a, 0xe4, 0x30, 0x00, 0x50, 0xe4, +0x38, 0x0c, 0x44, 0x10, 0x5b, 0x18, 0x23, 0x1a, +0x23, 0x1b, 0x23, 0xe4, 0x42 +}; + +static const unsigned char pkt520[] = { +0x42, 0xca, 0x00, +0x6e, 0x26, 0x01, 0x5a, 0xe4, +0x38, 0x00, 0x50, 0xe4, 0x30, 0x4a, 0x80, 0x2b, +0x0d, 0x02, 0x2e, 0x9d, 0x81, 0xe4, 0x42, 0x01, +0x5a, 0xe4, 0x30, 0x00, 0x50, 0xe4, 0x38, 0x0c, +0x45, 0x00, 0x5b, 0x0f, 0x88, 0x0c, 0x46, 0x01, +0x5a, 0x01, 0x2e, 0xb7, 0x80, 0x0c, 0x43, 0x05, +0x5b, 0x0c, 0x45, 0x03, 0x5b, 0x0d, 0x45, 0x01, +0x5b, 0x0d, 0x37, 0x05, 0x27, 0x0c, 0x40, 0x00, +0x5b, 0x0d, 0x3f, 0x05, 0x27, 0x60, 0xcf, 0x0f, +0x1c, 0xdf, 0x9f, 0x0c, 0x1c, 0x12, 0x82, 0x03, +0x1d, 0x19, 0x82, 0x5f, 0x02, 0x60, 0xcf, 0xf0, +0x1c, 0x3f, 0x02, 0x60, 0xaf, 0x05, 0x27, 0x28, +0xff, 0x64, 0xef, 0x19, 0x27, 0x01, 0xff, 0x5a, +0xef, 0x1b, 0x27, 0x06, 0xef, 0x06, 0xaf, 0xfc, +0x97, 0x5f, 0x9f, 0x06, 0x25, 0xfb, 0x55, 0x05, +0x27, 0x10, 0xcf, 0x72, 0xaf, 0x0a, 0x40, 0x13, +0x5a, 0x27, 0xcf, 0x10, 0xaf, 0x07, 0x43, 0x08, +0x5b, 0x3b, 0x31, 0x02, 0x5b, 0x3b, 0x36, 0x3b, +0x43, 0x03, 0x5b, 0x6e, 0xcf, 0xe2, 0xaf, 0x6f, +0xcf, 0xe3, 0xaf, 0x02, 0x2e, 0xd5, 0x80, 0x07, +0x40, 0x02, 0x5a, 0x61, 0x26, 0x00, 0x55, 0x07, +0x33, 0x88, 0x82, 0x02, 0x43, 0xdb, 0x2f, 0xc7, +0x5b, 0x02, 0x2e, 0x72, 0x80, 0x05, 0x27, 0x05, +0x27, 0x05, 0x27, 0x0c, 0xcf, 0x03, 0x1c, 0x0b, +0x55, 0x0c, 0xcf, 0x0c, 0x1c, 0x0c, 0x1e, 0x07, +0x54, 0x08, 0x1e, 0x03, 0x55 +}; + +static const unsigned char pkt524[] = { +0x42, 0xca, 0x00, +0xd2, 0x26, 0x0c, 0x45, 0x01, +0x5b, 0x0d, 0x44, 0x01, 0x5b, 0x0e, 0x33, 0x05, +0x27, 0x0e, 0x3b, 0x05, 0x27, 0x0d, 0xcf, 0x06, +0x1c, 0x09, 0x55, 0x09, 0x46, 0x04, 0x5b, 0x15, +0x88, 0x02, 0x5a, 0xf2, 0xcf, 0x0b, 0xaf, 0x10, +0x50, 0x02, 0xef, 0x0c, 0xaf, 0x0d, 0x50, 0x0a, +0x41, 0x0b, 0x5b, 0x0c, 0x39, 0x0c, 0x46, 0x03, +0x5b, 0x4a, 0x80, 0x0e, 0x88, 0x29, 0x89, 0x00, +0x50, 0x0c, 0x31, 0x0c, 0x38, 0x01, 0x5b, 0x0d, +0x3f, 0x0d, 0x34, 0x05, 0x27, 0x23, 0x26, 0x02, +0x55, 0x22, 0xcf, 0xc8, 0x1e, 0x00, 0x5f, 0x0c, +0x27, 0x0d, 0x27, 0xf0, 0x97, 0x47, 0xaf, 0xf1, +0x97, 0x48, 0xaf, 0x05, 0x27, 0x46, 0x80, 0x08, +0x46, 0x0f, 0x5a, 0xde, 0xef, 0x5f, 0x9f, 0x10, +0xef, 0x5f, 0x9f, 0x00, 0xef, 0x5f, 0x9f, 0x28, +0xff, 0x54, 0xef, 0x1b, 0x27, 0x10, 0xef, 0x06, +0xaf, 0xfc, 0x97, 0x5f, 0x9f, 0x06, 0x25, 0xfb, +0x55, 0x62, 0x80, 0x05, 0x27, 0x46, 0x80, 0x08, +0x47, 0xfb, 0x5a, 0xdf, 0xef, 0x5f, 0x9f, 0x06, +0xef, 0x5f, 0x9f, 0x00, 0xef, 0x5f, 0x9f, 0x28, +0xff, 0x64, 0xef, 0x1b, 0x27, 0x06, 0xef, 0x06, +0xaf, 0xea, 0x50, 0x28, 0xff, 0x64, 0xef, 0x19, +0x27, 0x0f, 0xef, 0x6b, 0xdf, 0xff, 0x96, 0xbf, +0x22, 0xff, 0x96, 0x7b, 0x00, 0xc1, 0x03, 0x6b, +0xbf, 0x0c, 0x53, 0xdf, 0x96, 0xc2, 0x97, 0xbf, +0x01, 0x5f, 0x90, 0xdd, 0x97 +}; + +static const unsigned char pkt528[] = { +0x42, 0xca, 0x00, +0x36, 0x27, 0x5f, 0x20, 0x02, +0x1e, 0xf3, 0x53, 0x02, 0xef, 0x01, 0x0c, 0xdd, +0x9f, 0x6b, 0xbf, 0x15, 0x50, 0xdf, 0x96, 0xc2, +0x97, 0xdf, 0x01, 0xc1, 0x03, 0x05, 0x52, 0xdd, +0x97, 0x1f, 0x20, 0x6b, 0xdf, 0xe0, 0x01, 0x6b, +0xbf, 0x00, 0x50, 0xdd, 0x97, 0x02, 0x0c, 0x6b, +0xdf, 0x28, 0x1f, 0x01, 0x53, 0x28, 0xff, 0x6b, +0xbf, 0x68, 0x1f, 0x01, 0x5f, 0x68, 0xff, 0x6b, +0xbf, 0x05, 0x27, 0x01, 0x81, 0x50, 0x8f, 0xf1, +0x88, 0x05, 0x81, 0x00, 0x2e, 0x32, 0x8d, 0x01, +0x2e, 0x06, 0x80, 0x00, 0x2e, 0xd8, 0x8e, 0x5c, +0x47, 0x02, 0x5b, 0x00, 0x2e, 0x16, 0x8f, 0x01, +0x50, 0x00, 0x2e, 0x14, 0x8f, 0x08, 0xef, 0x0f, +0x80, 0x01, 0x2e, 0x54, 0x80, 0x05, 0x27, 0x07, +0x40, 0x01, 0x5b, 0x54, 0x23, 0x18, 0x50, 0x9c, +0x8e, 0x0d, 0xcf, 0x06, 0x1c, 0x08, 0x54, 0x14, +0x88, 0x02, 0x2e, 0x9d, 0x81, 0x01, 0x2e, 0x50, +0x82, 0x4f, 0x8f, 0x68, 0x88, 0x01, 0x2e, 0x44, +0x84, 0x5c, 0x8f, 0x54, 0x88, 0x09, 0x46, 0x02, +0x5b, 0x37, 0x82, 0x90, 0xaf, 0x91, 0xbf, 0x00, +0x2e, 0xe6, 0x8f, 0x90, 0x8e, 0x0c, 0x3e, 0xed, +0x5a, 0x05, 0x27, 0x37, 0x82, 0x4a, 0x82, 0x1c, +0x82, 0x1c, 0x82, 0x9d, 0xbf, 0xff, 0x97, 0x08, +0x10, 0x09, 0x27, 0x0f, 0x1c, 0x5c, 0x46, 0x03, +0x5b, 0x02, 0x1e, 0x04, 0x53, 0x02, 0xef, 0x02, +0x50, 0x03, 0x1e, 0x00, 0x53 +}; + +static const unsigned char pkt532[] = { +0x42, 0xca, 0x00, +0x9a, 0x27, 0x03, 0xef, 0x69, +0xaf, 0x53, 0x80, 0x1b, 0x0d, 0xe1, 0x97, 0x0f, +0x1c, 0x69, 0xdf, 0xdf, 0x01, 0x00, 0x53, 0x00, +0xff, 0xe0, 0x97, 0x8a, 0x80, 0x04, 0x10, 0x11, +0x82, 0x0f, 0x1e, 0x00, 0x5f, 0x0f, 0xef, 0x6a, +0xaf, 0xc1, 0x2e, 0x47, 0xdf, 0xf0, 0x1d, 0x5f, +0x02, 0xc1, 0x2e, 0x47, 0xbf, 0x10, 0x0d, 0x05, +0x27, 0x01, 0x2e, 0x56, 0x80, 0xf7, 0xef, 0x16, +0x80, 0x66, 0x80, 0x20, 0x82, 0xdf, 0x8e, 0x02, +0x2e, 0x3e, 0x81, 0x02, 0x2e, 0x93, 0x81, 0x00, +0x2e, 0xb4, 0x8e, 0x5c, 0x47, 0x09, 0x5b, 0x6c, +0x38, 0x3b, 0x43, 0x00, 0x5b, 0x6c, 0x30, 0x41, +0x2e, 0x71, 0xdf, 0xc1, 0x2e, 0x72, 0xdf, 0xbf, +0x03, 0x01, 0x55, 0x00, 0x2e, 0xc7, 0x8e, 0x67, +0x8c, 0x01, 0x2e, 0xcd, 0x80, 0x05, 0x27, 0x3b, +0x40, 0x01, 0x5b, 0x02, 0xef, 0x0c, 0xaf, 0x05, +0x27, 0x52, 0xcf, 0xcb, 0xaf, 0x53, 0xdf, 0xcc, +0xbf, 0xdf, 0x22, 0x01, 0x55, 0xff, 0x22, 0x01, +0x54, 0x0e, 0xef, 0xc9, 0xaf, 0x05, 0x27, 0x0e, +0xcf, 0x6e, 0x1c, 0x49, 0xdf, 0x10, 0x1d, 0x3f, +0x02, 0x49, 0xaf, 0x0d, 0x44, 0x06, 0x5a, 0x0a, +0x41, 0x03, 0x5b, 0x49, 0x43, 0x02, 0x5a, 0x48, +0x26, 0x00, 0x55, 0x49, 0x30, 0x9f, 0x2c, 0x05, +0x5a, 0xdf, 0x2c, 0x4c, 0x5a, 0x0e, 0x41, 0x15, +0x5b, 0x0c, 0x46, 0x13, 0x5a, 0x9f, 0x22, 0x1c, +0xaf, 0x21, 0xaf, 0x45, 0x88 +}; + +static const unsigned char pkt536[] = { +0x42, 0xca, 0x00, +0xfe, 0x27, 0x03, 0x5a, 0x9f, +0x2c, 0x05, 0x5a, 0x9f, 0x22, 0x04, 0x50, 0x9f, +0x22, 0x0e, 0x3e, 0x0e, 0x3d, 0x00, 0x5b, 0x5f, +0xef, 0x1d, 0xaf, 0x49, 0xcf, 0x87, 0x1c, 0x01, +0x18, 0x49, 0xaf, 0x34, 0x50, 0x20, 0x26, 0x08, +0x55, 0x1f, 0xcf, 0x48, 0xdf, 0xff, 0x2d, 0x00, +0x5b, 0xff, 0x21, 0x3f, 0x00, 0x00, 0x53, 0xff, +0xef, 0x1f, 0xaf, 0x47, 0xdf, 0x1c, 0xcf, 0x3f, +0x00, 0x1c, 0xaf, 0x1d, 0xcf, 0x48, 0xdf, 0x3f, +0x00, 0x1d, 0xaf, 0xff, 0x22, 0x1f, 0x54, 0xff, +0x2d, 0x03, 0x5b, 0xff, 0x1e, 0x19, 0x5b, 0x60, +0x10, 0x02, 0x50, 0x60, 0x1e, 0x0a, 0x52, 0x60, +0x16, 0x1d, 0xaf, 0x49, 0x30, 0x49, 0x3c, 0x12, +0x5b, 0x21, 0xcf, 0x47, 0xdf, 0x3f, 0x00, 0x1c, +0xaf, 0x21, 0x23, 0x0c, 0x50, 0x59, 0x1e, 0x0a, +0x52, 0x49, 0x34, 0x01, 0x5a, 0x21, 0x23, 0x06, +0x50, 0x21, 0xcf, 0x47, 0xdf, 0x3f, 0x00, 0x21, +0xaf, 0x01, 0x50, 0x06, 0x1e, 0xf4, 0x5f, 0x05, +0x27, 0x0d, 0xcf, 0x06, 0x1c, 0x06, 0x1e, 0x00, +0x54, 0x0d, 0x27, 0x0c, 0x27, 0x09, 0x46, 0x0c, +0x5b, 0xa8, 0x8e, 0x07, 0x52, 0x0f, 0xcf, 0x01, +0x16, 0x02, 0x53, 0x02, 0x2e, 0x36, 0x83, 0x04, +0x50, 0xf4, 0xaf, 0x02, 0x50, 0xf2, 0xcf, 0x02, +0x10, 0x0f, 0xaf, 0x05, 0x27, 0x5a, 0xcf, 0xdf, +0x22, 0x10, 0x54, 0x3e, 0xdf, 0x3f, 0x20, 0x3f, +0x1f, 0x0a, 0x52, 0xbf, 0x22 +}; + +static const unsigned char pkt540[] = { +0x42, 0x50, 0x00, +0x62, 0x28, 0x3e, 0xbf, 0x3d, +0xdf, 0x3f, 0x20, 0xdf, 0x03, 0x02, 0x52, 0xbf, +0x22, 0x3d, 0xbf, 0x0c, 0x27, 0x3d, 0xbf, 0x0d, +0x27, 0x3e, 0xbf, 0x0d, 0x27, 0x0d, 0x27, 0x0f, +0x1c, 0x69, 0xdf, 0xdf, 0x01, 0x00, 0x53, 0x00, +0xff, 0x05, 0x27, 0x37, 0x82, 0x4a, 0x82, 0x1c, +0x82, 0x1c, 0x82, 0x9d, 0xbf, 0xff, 0x97, 0x08, +0x10, 0x09, 0x27, 0x0f, 0x1c, 0x5c, 0x46, 0x03, +0x5b, 0x02, 0x1e, 0x04, 0x53, 0x02, 0xef, 0x02, +0x50, 0x03, 0x1e, 0x00, 0x53, 0x03, 0xef, 0x69, +0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt544[] = { +0x42, 0xca, 0x00, +0x89, 0x28, 0x0c, 0x42, 0x00, +0x5b, 0x18, 0x23, 0x0c, 0x23, 0x0e, 0xcf, 0xe0, +0x1c, 0x0e, 0xaf, 0x0a, 0x40, 0x02, 0x5a, 0x3b, +0x46, 0x00, 0x5a, 0x05, 0x27, 0x37, 0x43, 0xfc, +0x5b, 0x08, 0xef, 0x0c, 0xaf, 0x0d, 0x40, 0x0a, +0x5a, 0xee, 0xcf, 0x64, 0x1e, 0x01, 0x5e, 0x0c, +0x3b, 0x05, 0x27, 0x0d, 0x30, 0x0c, 0x35, 0xbf, +0x22, 0xc0, 0x2e, 0x96, 0xbf, 0x05, 0x27, 0x0e, +0x45, 0x01, 0x5b, 0x07, 0x88, 0x00, 0x50, 0x0e, +0x88, 0x0d, 0x41, 0x1f, 0x5a, 0x0d, 0x42, 0x11, +0x5a, 0xd6, 0x78, 0x51, 0x88, 0x19, 0xcf, 0xfe, +0x1e, 0x03, 0x5c, 0x0e, 0x3d, 0x0d, 0x39, 0x0d, +0x3b, 0x0c, 0x27, 0x0d, 0x27, 0x64, 0x88, 0x19, +0xcf, 0x02, 0x1e, 0xfa, 0x5a, 0x0e, 0x3e, 0x0d, +0x3a, 0x0d, 0x33, 0x0c, 0x27, 0xe4, 0x37, 0x04, +0x89, 0xe4, 0x3f, 0x01, 0x2e, 0xef, 0x82, 0x0d, +0x45, 0x54, 0x5b, 0x18, 0xcf, 0xdf, 0x22, 0x67, +0x54, 0x0d, 0x3b, 0x4f, 0x78, 0xf9, 0x88, 0x01, +0x2e, 0xef, 0x82, 0x0d, 0x42, 0x06, 0x5a, 0x0d, +0x45, 0x48, 0x5b, 0x18, 0xcf, 0xdf, 0x22, 0x5b, +0x54, 0x0d, 0x33, 0x43, 0x78, 0x15, 0xcf, 0x1a, +0xaf, 0xe4, 0x37, 0xea, 0x88, 0x15, 0xcf, 0x1b, +0xaf, 0xe4, 0x3f, 0x0d, 0xcf, 0x60, 0x1c, 0xdf, +0x22, 0x00, 0x55, 0x63, 0x78, 0x16, 0xcf, 0x13, +0xdf, 0x2a, 0x1e, 0x02, 0x5f, 0x2a, 0x1f, 0x00, +0x5f, 0x5c, 0x78, 0xbf, 0x03 +}; + +static const unsigned char pkt548[] = { +0x42, 0xca, 0x00, +0xed, 0x28, 0x44, 0x54, 0x1d, +0x52, 0x01, 0x2e, 0xef, 0x82, 0x9f, 0x22, 0x1a, +0xaf, 0x18, 0xcf, 0x12, 0xdf, 0xbf, 0x03, 0x00, +0x53, 0x24, 0x50, 0x09, 0x88, 0x01, 0x2e, 0xe3, +0x82, 0x9f, 0x22, 0x1b, 0xaf, 0xb1, 0x8f, 0x1d, +0x78, 0x0e, 0xcf, 0x9f, 0x1c, 0x0e, 0xaf, 0x05, +0x27, 0x0e, 0xcf, 0x5f, 0x2d, 0x05, 0x5a, 0x9f, +0x2b, 0x5f, 0x29, 0x0e, 0xaf, 0x5f, 0xff, 0x1d, +0xbf, 0x1c, 0x23, 0x05, 0x27, 0x9f, 0x22, 0x1b, +0xaf, 0x18, 0xcf, 0xdf, 0x22, 0x0a, 0x54, 0x18, +0xcf, 0x12, 0xdf, 0xbf, 0x03, 0x00, 0x53, 0x05, +0x50, 0x06, 0x88, 0x01, 0x2e, 0xe9, 0x82, 0x9f, +0x22, 0x1a, 0xaf, 0x9b, 0x8f, 0x09, 0x88, 0x05, +0x27, 0x0e, 0xcf, 0x9f, 0x2d, 0x04, 0x5a, 0x9f, +0x29, 0x5f, 0x2b, 0x0e, 0xaf, 0x1d, 0x23, 0x1c, +0x23, 0x05, 0x27, 0x0d, 0x45, 0x1e, 0x5b, 0x8e, +0x88, 0x18, 0xcf, 0x12, 0xdf, 0xbf, 0x03, 0x57, +0x53, 0x0d, 0x44, 0x02, 0x5b, 0x0c, 0x35, 0x0c, +0x78, 0x85, 0x88, 0x17, 0xcf, 0xdf, 0x22, 0x08, +0x55, 0x18, 0xcf, 0xdf, 0x22, 0x05, 0x55, 0x0a, +0x88, 0x0e, 0x3b, 0x0c, 0xdf, 0x24, 0x19, 0x0c, +0xbf, 0x05, 0x27, 0x11, 0xcf, 0xff, 0x1e, 0x01, +0x54, 0x1f, 0x20, 0x11, 0xaf, 0x05, 0x27, 0x1a, +0x23, 0x1b, 0x23, 0x05, 0x27, 0xfb, 0x8f, 0x0b, +0x88, 0x6d, 0x88, 0xf6, 0x8e, 0x34, 0x5a, 0x0a, +0xcf, 0xc0, 0x1c, 0xc0, 0x1e +}; + +static const unsigned char pkt552[] = { +0x42, 0xca, 0x00, +0x51, 0x29, 0x0d, 0x55, 0x9f, +0x22, 0x1f, 0xaf, 0x20, 0xaf, 0x19, 0xaf, 0x1b, +0x78, 0x0e, 0xcf, 0x05, 0x18, 0x0e, 0xaf, 0x9f, +0x22, 0x47, 0xaf, 0x48, 0xaf, 0x17, 0xaf, 0x18, +0xaf, 0x05, 0x27, 0x20, 0xcf, 0xdf, 0x22, 0x05, +0x54, 0x05, 0x1e, 0x19, 0x55, 0x1f, 0xdf, 0x80, +0x1f, 0x16, 0x5e, 0x02, 0x78, 0x1f, 0xdf, 0x10, +0x1f, 0x12, 0x5e, 0x9f, 0x22, 0x20, 0xaf, 0x1f, +0xaf, 0x0a, 0xcf, 0xc0, 0x1c, 0x80, 0x1e, 0x0a, +0x55, 0x0d, 0x41, 0x01, 0x5a, 0x0e, 0x35, 0x00, +0x50, 0x0e, 0x36, 0x0d, 0xcf, 0x06, 0x18, 0x0d, +0xaf, 0x0e, 0x31, 0x9f, 0x22, 0x19, 0xaf, 0x03, +0x78, 0x1f, 0x20, 0x06, 0x1e, 0x00, 0x5e, 0x20, +0xaf, 0x0d, 0x47, 0x01, 0x5b, 0x01, 0x2e, 0xa2, +0x73, 0x0d, 0x44, 0x0b, 0x5a, 0x0d, 0xcf, 0x06, +0x1c, 0x08, 0x54, 0x0c, 0x30, 0x48, 0xcf, 0xdf, +0x2d, 0x02, 0x5a, 0x9f, 0x22, 0x1d, 0xaf, 0x01, +0x50, 0x5f, 0xef, 0x1d, 0xaf, 0x0c, 0x31, 0x0d, +0x45, 0x11, 0x5b, 0x0a, 0xcf, 0x30, 0x1c, 0x0c, +0x55, 0x0d, 0xcf, 0x06, 0x1c, 0x06, 0x1e, 0x0b, +0x54, 0x11, 0xcf, 0x07, 0x1e, 0x02, 0x53, 0x04, +0xef, 0x12, 0xaf, 0x04, 0x78, 0x05, 0xef, 0x12, +0xaf, 0x01, 0x78, 0x01, 0xef, 0x12, 0xaf, 0x18, +0x23, 0x9f, 0x22, 0x11, 0xaf, 0x0d, 0xcf, 0x1f, +0x1c, 0x0d, 0xaf, 0x0c, 0xdf, 0x24, 0x19, 0x0c, +0xbf, 0x0a, 0xdf, 0x30, 0x1d +}; + +static const unsigned char pkt556[] = { +0x42, 0x46, 0x00, +0xb5, 0x29, 0x20, 0x1f, 0x01, +0x55, 0xf9, 0x1c, 0x0d, 0xaf, 0x05, 0x27, 0x17, +0xdf, 0xff, 0x21, 0x47, 0xbf, 0x18, 0xdf, 0x84, +0x8e, 0x02, 0x5b, 0x0e, 0x46, 0x03, 0x5a, 0x01, +0x78, 0x0d, 0x43, 0x00, 0x5a, 0xff, 0x21, 0x48, +0xbf, 0x05, 0x27, 0x14, 0x23, 0x15, 0x23, 0xff, +0xef, 0x13, 0xaf, 0x01, 0x2e, 0x00, 0x83, 0x0d, +0x3e, 0x13, 0xcf, 0x46, 0xff, 0xbf, 0x03, 0x00, +0x53, 0x0d, 0x36, 0x05, 0x27, 0x05, 0x27, 0x05, +0x27 +}; + +static const unsigned char pkt560[] = { +0x42, 0xca, 0x00, +0xd7, 0x29, 0xe1, 0x97, 0xe2, +0x9f, 0x46, 0x2e, 0x28, 0xbf, 0xc6, 0x2e, 0x29, +0xbf, 0xad, 0x88, 0x0a, 0x5b, 0xe9, 0x97, 0xea, +0x9f, 0x4f, 0xaf, 0x50, 0xbf, 0x46, 0x2e, 0x28, +0xdf, 0xc6, 0x2e, 0x29, 0xdf, 0x10, 0x10, 0x00, +0x13, 0x01, 0x78, 0x03, 0x10, 0x00, 0x13, 0xff, +0x96, 0xdf, 0x96, 0xd6, 0xcf, 0xd7, 0xdf, 0x0f, +0x1d, 0x01, 0x10, 0x00, 0x13, 0xff, 0x96, 0xdf, +0x96, 0xc8, 0xdf, 0xc7, 0xcf, 0x1f, 0x1d, 0xff, +0x96, 0xdf, 0x96, 0xc2, 0x97, 0xc3, 0x9f, 0x9d, +0x01, 0x5d, 0x01, 0xf5, 0x52, 0xc3, 0x03, 0x02, +0x5e, 0xf2, 0x52, 0x82, 0x03, 0xf0, 0x52, 0x02, +0x0c, 0xf8, 0x43, 0x03, 0x5b, 0x08, 0x44, 0x01, +0x5a, 0x00, 0x2e, 0xf3, 0x8f, 0x7f, 0x88, 0x6d, +0x5b, 0x41, 0x2e, 0xaf, 0xdf, 0xdf, 0x29, 0x41, +0x2e, 0xaf, 0xbf, 0x46, 0x2e, 0x28, 0xdf, 0xc6, +0x2e, 0x29, 0xdf, 0x03, 0x16, 0x00, 0x15, 0x46, +0x2e, 0x28, 0xbf, 0xc6, 0x2e, 0x29, 0xbf, 0x15, +0x27, 0xff, 0x96, 0xdf, 0x96, 0x8d, 0x88, 0x94, +0x88, 0xcd, 0x88, 0x01, 0xff, 0xab, 0xef, 0x19, +0x27, 0x6b, 0x88, 0xbf, 0x22, 0x3f, 0x98, 0x05, +0xff, 0x7f, 0x98, 0xdd, 0x9f, 0xbf, 0x98, 0x24, +0x28, 0x04, 0xff, 0x7f, 0x98, 0xdd, 0x9f, 0xbf, +0x98, 0x24, 0x28, 0x66, 0xff, 0xbf, 0x99, 0x12, +0xff, 0x7f, 0x99, 0xdd, 0x97, 0xdd, 0x9f, 0x19, +0x27, 0xe0, 0x97, 0xff, 0xaf +}; + +static const unsigned char pkt564[] = { +0x42, 0xca, 0x00, +0x3b, 0x2a, 0x46, 0x2e, 0x28, +0xdf, 0xc6, 0x2e, 0x29, 0xdf, 0x13, 0x10, 0x00, +0x13, 0xff, 0xaf, 0xff, 0xbf, 0xe3, 0x97, 0xff, +0xaf, 0xe4, 0x97, 0xff, 0xaf, 0xe5, 0x97, 0xff, +0xaf, 0xef, 0x88, 0x06, 0x0d, 0xdd, 0x97, 0xdd, +0x9f, 0x46, 0x2e, 0x28, 0xdf, 0xc6, 0x2e, 0x29, +0xdf, 0x06, 0xaf, 0x4e, 0xbf, 0xff, 0x22, 0x11, +0x54, 0x15, 0x27, 0x1a, 0x27, 0x01, 0xff, 0xab, +0xef, 0x19, 0x27, 0xdc, 0x97, 0xdf, 0x99, 0x28, +0x28, 0x0f, 0x27, 0x68, 0x2c, 0xfd, 0x5b, 0xe9, +0x97, 0xff, 0xaf, 0x6a, 0x28, 0x06, 0x25, 0xf4, +0x53, 0x4e, 0x25, 0xf2, 0x55, 0xdc, 0x97, 0xdf, +0x99, 0x28, 0x28, 0x0f, 0x27, 0x68, 0x2c, 0xfd, +0x5b, 0xe9, 0x97, 0xff, 0xaf, 0x6a, 0x28, 0x06, +0x25, 0xf4, 0x55, 0x41, 0x2e, 0xaf, 0xdf, 0xdf, +0x2b, 0x41, 0x2e, 0xaf, 0xbf, 0xbf, 0x22, 0xbf, +0x99, 0x7f, 0x99, 0x05, 0x27, 0xdd, 0x97, 0xdd, +0x9f, 0x06, 0xaf, 0x4e, 0xbf, 0xff, 0x22, 0x05, +0x54, 0xfd, 0x97, 0xff, 0xaf, 0x06, 0x25, 0xfb, +0x53, 0x4e, 0x25, 0xf9, 0x55, 0xfd, 0x97, 0xff, +0xaf, 0x06, 0x25, 0xfb, 0x55, 0x05, 0x27, 0xff, +0x96, 0xc6, 0x2e, 0x01, 0xdf, 0xbf, 0x2c, 0xdd, +0x9f, 0x05, 0x27, 0xc6, 0x2e, 0x28, 0xdf, 0x0f, +0x1d, 0x04, 0x55, 0x0b, 0x88, 0xff, 0x96, 0x10, +0xef, 0xdf, 0x96, 0x06, 0x50, 0x06, 0x88, 0x3f, +0x20, 0xff, 0x96, 0xc6, 0x2e +}; + +static const unsigned char pkt568[] = { +0x42, 0xca, 0x00, +0x9f, 0x2a, 0x28, 0xdf, 0x0f, +0x1d, 0xff, 0x96, 0x05, 0x27, 0x46, 0x2e, 0x28, +0xdf, 0xf0, 0x1c, 0x09, 0x27, 0xdf, 0x9f, 0x46, +0x2e, 0x29, 0xdf, 0x0f, 0x1c, 0x09, 0x27, 0x5f, +0x02, 0x05, 0x27, 0x78, 0x88, 0x6f, 0x88, 0x0a, +0xef, 0xdc, 0x9f, 0x3f, 0x9f, 0x5f, 0x20, 0xfb, +0x55, 0x05, 0x27, 0x9f, 0x22, 0x41, 0x2e, 0xab, +0xbf, 0x50, 0xef, 0xdf, 0x96, 0x3a, 0xef, 0xdf, +0x96, 0x29, 0x88, 0x68, 0x88, 0x0a, 0xef, 0xfc, +0x9f, 0xc1, 0x2e, 0xad, 0xbf, 0xc1, 0x2e, 0xac, +0xdf, 0x3f, 0x20, 0xc1, 0x2e, 0xac, 0xbf, 0x6a, +0x88, 0x5f, 0x20, 0xf4, 0x55, 0x5b, 0xef, 0xdf, +0x96, 0x50, 0xcf, 0xdf, 0x96, 0x17, 0x88, 0x5c, +0xef, 0xdf, 0x96, 0x4f, 0xcf, 0xdf, 0x96, 0x12, +0x88, 0x5d, 0xef, 0xdf, 0x96, 0x9f, 0x22, 0xdf, +0x96, 0x0d, 0x88, 0x5e, 0xef, 0xdf, 0x96, 0x46, +0x2e, 0x29, 0xdf, 0xdf, 0x96, 0x07, 0x88, 0x5f, +0xef, 0xdf, 0x96, 0x46, 0x2e, 0x28, 0xdf, 0xdf, +0x96, 0x01, 0x88, 0x0f, 0x27, 0x05, 0x27, 0xdd, +0x97, 0x41, 0x2e, 0xad, 0xbf, 0xdd, 0x97, 0x41, +0x2e, 0xac, 0xbf, 0x44, 0x88, 0x05, 0x27, 0x9f, +0x22, 0x41, 0x2e, 0xab, 0xbf, 0x10, 0xef, 0xdf, +0x96, 0x02, 0xef, 0xdf, 0x96, 0xef, 0x8f, 0x2e, +0x88, 0x0a, 0xef, 0xfc, 0x9f, 0xc1, 0x2e, 0xad, +0xbf, 0xc1, 0x2e, 0xac, 0xdf, 0x3f, 0x20, 0xc1, +0x2e, 0xac, 0xbf, 0x30, 0x88 +}; + +static const unsigned char pkt572[] = { +0x42, 0x9a, 0x00, +0x03, 0x2b, 0x5f, 0x20, 0xf4, +0x55, 0x1b, 0xef, 0xdf, 0x96, 0x50, 0xcf, 0xdf, +0x96, 0xdd, 0x8f, 0x1c, 0xef, 0xdf, 0x96, 0x4f, +0xcf, 0xdf, 0x96, 0xd8, 0x8f, 0x1d, 0xef, 0xdf, +0x96, 0x9f, 0x22, 0xdf, 0x96, 0xd3, 0x8f, 0x1e, +0xef, 0xdf, 0x96, 0x9f, 0x22, 0xdf, 0x96, 0xce, +0x8f, 0x1f, 0xef, 0xdf, 0x96, 0x01, 0xef, 0xdf, +0x96, 0xc9, 0x8f, 0x0f, 0x27, 0x05, 0x27, 0x02, +0xef, 0x06, 0xff, 0x1a, 0x27, 0x05, 0x27, 0x02, +0xef, 0x06, 0xff, 0x1a, 0x27, 0x05, 0x27, 0xdf, +0x96, 0xff, 0x96, 0x7b, 0xef, 0x00, 0xff, 0x1b, +0x27, 0xdd, 0x9f, 0xdd, 0x97, 0x05, 0x27, 0x01, +0xff, 0xab, 0xef, 0x1b, 0x27, 0x05, 0x27, 0xdf, +0x96, 0x81, 0xef, 0x41, 0x2e, 0xaf, 0xbf, 0xdd, +0x97, 0x05, 0x27, 0x3a, 0xef, 0xff, 0xaf, 0xea, +0x8f, 0x0a, 0xef, 0xfc, 0x9f, 0xff, 0xbf, 0x5f, +0x20, 0xfb, 0x55, 0x50, 0xcf, 0xff, 0xaf, 0x4f, +0xcf, 0xff, 0xaf, 0x9f, 0x22, 0xff, 0xaf, 0x46, +0x2e, 0x29, 0xdf, 0xff, 0xaf, 0x46, 0x2e, 0x28, +0xdf, 0xff, 0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt576[] = { +0x42, 0x1a, 0x00, +0x4f, 0x2b, 0x09, 0x43, 0x04, +0x5b, 0x00, 0xef, 0xf8, 0xaf, 0x32, 0xef, 0xfa, +0xaf, 0x03, 0x50, 0x01, 0xef, 0xf8, 0xaf, 0x42, +0xef, 0xfa, 0xaf, 0x05, 0x27 +}; + +static const unsigned char pkt580[] = { +0x42, 0x18, 0x00, +0x5b, 0x2b, 0xd3, 0x45, 0x03, +0x5a, 0x0f, 0x27, 0xd3, 0x45, 0x00, 0x5a, 0x05, +0x27, 0xd0, 0x41, 0xf7, 0x5b, 0xc1, 0x83, 0xf5, +0x50, 0x05, 0x27 +}; + +static const unsigned char pkt584[] = { +0x42, 0x22, 0x00, +0x66, 0x2b, 0xc8, 0x46, 0x0c, +0x5b, 0xd3, 0x45, 0xfd, 0x5a, 0xd3, 0x45, 0xfb, +0x5a, 0xd3, 0x45, 0xf9, 0x5a, 0x41, 0x2e, 0xa1, +0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, 0xbf, 0x02, +0x2e, 0xb0, 0x81, 0x05, 0x27 +}; + +static const unsigned char pkt588[] = { +0x42, 0x0e, 0x00, +0x76, 0x2b, 0x00, 0x19, 0xe9, +0x2f, 0xe3, 0x55, 0xdf, 0x2d, 0xe9, 0x2f, 0xd0, +0x50 +}; + +static const unsigned char pkt592[] = { +0x42, 0x0e, 0x00, +0x7c, 0x2b, 0x00, 0x19, 0xe9, +0x2f, 0xb5, 0x55, 0xdf, 0x2d, 0xe9, 0x2f, 0xa2, +0x50 +}; + +static const unsigned char pkt596[] = { +0x42, 0x0e, 0x00, +0x82, 0x2b, 0xbf, 0x03, 0xe7, +0x2f, 0xb2, 0x53, 0xec, 0xcf, 0x01, 0x2e, 0x2d, +0x73 +}; + +static const unsigned char pkt600[] = { +0x42, 0x50, 0x00, +0x88, 0x2b, 0x07, 0x3d, 0x02, +0x5b, 0x6c, 0x86, 0xc2, 0x23, 0xd3, 0x3c, 0x02, +0x44, 0xd7, 0x2f, 0x08, 0x5a, 0x02, 0x45, 0xd7, +0x2f, 0x69, 0x5b, 0x58, 0x23, 0x3c, 0x26, 0x02, +0x55, 0x02, 0x2e, 0x43, 0x83, 0x01, 0x50, 0x02, +0x2e, 0x92, 0x83, 0x07, 0x45, 0xea, 0x5a, 0x41, +0x2e, 0x53, 0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, +0x96, 0xdf, 0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, +0x2e, 0x78, 0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, +0x22, 0x00, 0x54, 0xff, 0xef, 0x2e, 0xaf, 0xd7, +0x2f, 0x4d, 0x50 +}; + +static const unsigned char pkt604[] = { +0x67, 0x05, 0x00, 0x00, 0x02, 0x2e, 0x00, 0x70, +0x67, 0x05, 0x00, 0x01, 0x02, 0x2e, 0xb8, 0x71, +0x67, 0x05, 0x00, 0x02, 0x02, 0x2e, 0x35, 0x72, +0x67, 0x05, 0x00, 0x08, 0x02, 0x2e, 0xbb, 0x72, +0x67, 0x05, 0x00, 0x07, 0x02, 0x2e, 0x3b, 0x73, +0x67, 0x05, 0x00, 0x0d, 0x02, 0x2e, 0x38, 0x74, +0x67, 0x05, 0x00, 0x0b, 0x02, 0x2e, 0x85, 0x74, +0x67, 0x05, 0x00, 0x0e, 0x02, 0x2e, 0x61, 0x75, +0x67, 0x05, 0x00, 0x05, 0x02, 0x2e, 0xa6, 0x75, +0x67, 0x05, 0x00, 0x0c, 0x02, 0x2e, 0x89, 0x78, +0x67, 0x05, 0x00, 0x09, 0x02, 0x2e, 0xd7, 0x79, +0x5a, 0x05, 0x00, 0x00, 0x6b, 0x01, 0x4f, 0x2b, +0x5a, 0x05, 0x00, 0x01, 0x82, 0x09, 0x5b, 0x2b, +0x5a, 0x05, 0x00, 0x02, 0x78, 0x09, 0x66, 0x2b, +0x5a, 0x05, 0x00, 0x03, 0x4c, 0x15, 0x76, 0x2b, +0x5a, 0x05, 0x00, 0x04, 0x24, 0x15, 0x7c, 0x2b, +0x5a, 0x05, 0x00, 0x05, 0x50, 0x13, 0x82, 0x2b, +0x5a, 0x05, 0x00, 0x06, 0xe1, 0x02, 0x88, 0x2b, +0x0d, +0x42, 0x04, 0x00, 0x88, 0x2b, 0x07, 0x3d +}; + +struct aesX660_cmd aes1660_init_2[] = { + { .cmd = pkt433, .len = sizeof(pkt433) }, + { .cmd = pkt440, .len = sizeof(pkt440) }, + { .cmd = pkt444, .len = sizeof(pkt444) }, + { .cmd = pkt448, .len = sizeof(pkt448) }, + { .cmd = pkt452, .len = sizeof(pkt452) }, + { .cmd = pkt456, .len = sizeof(pkt456) }, + { .cmd = pkt460, .len = sizeof(pkt460) }, + { .cmd = pkt464, .len = sizeof(pkt464) }, + { .cmd = pkt468, .len = sizeof(pkt468) }, + { .cmd = pkt472, .len = sizeof(pkt472) }, + { .cmd = pkt476, .len = sizeof(pkt476) }, + { .cmd = pkt480, .len = sizeof(pkt480) }, + { .cmd = pkt484, .len = sizeof(pkt484) }, + { .cmd = pkt488, .len = sizeof(pkt488) }, + { .cmd = pkt492, .len = sizeof(pkt492) }, + { .cmd = pkt496, .len = sizeof(pkt496) }, + { .cmd = pkt500, .len = sizeof(pkt500) }, + { .cmd = pkt504, .len = sizeof(pkt504) }, + { .cmd = pkt508, .len = sizeof(pkt508) }, + { .cmd = pkt512, .len = sizeof(pkt512) }, + { .cmd = pkt516, .len = sizeof(pkt516) }, + { .cmd = pkt520, .len = sizeof(pkt520) }, + { .cmd = pkt524, .len = sizeof(pkt524) }, + { .cmd = pkt528, .len = sizeof(pkt528) }, + { .cmd = pkt532, .len = sizeof(pkt532) }, + { .cmd = pkt536, .len = sizeof(pkt536) }, + { .cmd = pkt540, .len = sizeof(pkt540) }, + { .cmd = pkt544, .len = sizeof(pkt544) }, + { .cmd = pkt548, .len = sizeof(pkt548) }, + { .cmd = pkt552, .len = sizeof(pkt552) }, + { .cmd = pkt556, .len = sizeof(pkt556) }, + { .cmd = pkt560, .len = sizeof(pkt560) }, + { .cmd = pkt564, .len = sizeof(pkt564) }, + { .cmd = pkt568, .len = sizeof(pkt568) }, + { .cmd = pkt572, .len = sizeof(pkt572) }, + { .cmd = pkt576, .len = sizeof(pkt576) }, + { .cmd = pkt580, .len = sizeof(pkt580) }, + { .cmd = pkt584, .len = sizeof(pkt584) }, + { .cmd = pkt588, .len = sizeof(pkt588) }, + { .cmd = pkt592, .len = sizeof(pkt592) }, + { .cmd = pkt596, .len = sizeof(pkt596) }, + { .cmd = pkt600, .len = sizeof(pkt600) }, + { .cmd = pkt604, .len = sizeof(pkt604) }, +}; +/* INIT2 is over, 0x07 cmd returns + * { 0x07, 0x05, 0x00, 0x8f, 0x16, 0x25, 0x01, 0x63 } + */ + +/* This command sequence starts imaging */ +static const unsigned char aes1660_start_imaging_cmd[] = { +0x13, +0x20, +0x4c, 0x01, 0x00, 0x00, +0x4b, 0x04, 0x00, 0x78, 0x56, 0x34, 0x12, +0x55, 0x07, 0x00, 0x80, 0x42, 0x00, 0x7f, 0x00, 0x00, 0x14, +0x49, 0x03, 0x00, 0x20, 0x00, 0xc8 +}; + +#endif diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h index f5f22b09..fabce641 100644 --- a/libfprint/drivers/driver_ids.h +++ b/libfprint/drivers/driver_ids.h @@ -34,6 +34,7 @@ enum { VFS301_ID = 11, AES2550_ID = 12, UPEKE2_ID = 13, + AES1660_ID = 14, }; #endif diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index eaa11d4b..7b8cd143 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -255,6 +255,9 @@ extern struct fp_img_driver uru4000_driver; #ifdef ENABLE_AES1610 extern struct fp_img_driver aes1610_driver; #endif +#ifdef ENABLE_AES1660 +extern struct fp_img_driver aes1660_driver; +#endif #ifdef ENABLE_AES2501 extern struct fp_img_driver aes2501_driver; #endif From 118c610e293653132d891caab361f7d15fdbb007 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 25 Nov 2012 20:51:32 +0300 Subject: [PATCH 39/49] lib: add AES2660 driver https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- configure.ac | 15 +- libfprint/Makefile.am | 6 + libfprint/core.c | 3 + libfprint/drivers/aes2660.c | 121 ++ libfprint/drivers/aes2660.h | 1964 ++++++++++++++++++++++++++++++++ libfprint/drivers/driver_ids.h | 1 + libfprint/fp_internal.h | 3 + 7 files changed, 2112 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/aes2660.c create mode 100644 libfprint/drivers/aes2660.h diff --git a/configure.ac b/configure.ac index fdcbd8d7..3c88fe8b 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) AC_SUBST(lt_age) -all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes4000 vfs101 vfs301" +all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes4000 vfs101 vfs301" require_imaging='no' require_aeslib='no' @@ -38,6 +38,7 @@ enable_aes1610='no' enable_aes1660='no' enable_aes2501='no' enable_aes2550='no' +enable_aes2660='no' enable_aes4000='no' enable_vfs101='no' enable_vfs301='no' @@ -99,6 +100,12 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do require_aesX660="yes" enable_aes1660="yes" ;; + aes2660) + AC_DEFINE([ENABLE_AES2660], [], [Build AuthenTec AES1660 driver]) + require_aeslib="yes" + require_aesX660="yes" + enable_aes2660="yes" + ;; aes4000) AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver]) require_aeslib="yes" @@ -127,6 +134,7 @@ AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" = "yes"]) AM_CONDITIONAL([ENABLE_AES1660], [test "$enable_aes1660" = "yes"]) AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"]) +AM_CONDITIONAL([ENABLE_AES2660], [test "$enable_aes2660" = "yes"]) AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"]) AM_CONDITIONAL([REQUIRE_AESX660], [test "$require_aesX660" = "yes"]) @@ -319,6 +327,11 @@ if test x$enable_aes2550 != xno ; then else AC_MSG_NOTICE([ aes2550/aes2810 driver disabled]) fi +if test x$enable_aes2660 != xno ; then + AC_MSG_NOTICE([** aes2660 driver enabled]) +else + AC_MSG_NOTICE([ aes2660 driver disabled]) +fi if test x$enable_aes4000 != xno ; then AC_MSG_NOTICE([** aes4000 driver enabled]) else diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index ea495ebe..ed4f337e 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -11,6 +11,7 @@ AES1610_SRC = drivers/aes1610.c AES1660_SRC = drivers/aes1660.c drivers/aes1660.h AES2501_SRC = drivers/aes2501.c drivers/aes2501.h AES2550_SRC = drivers/aes2550.c drivers/aes2550.h +AES2660_SRC = drivers/aes2660.c drivers/aes2660.h AES4000_SRC = drivers/aes4000.c FDU2000_SRC = drivers/fdu2000.c VCOM5S_SRC = drivers/vcom5s.c @@ -27,6 +28,7 @@ EXTRA_DIST = \ $(AES1660_SRC) \ $(AES2501_SRC) \ $(AES2550_SRC) \ + $(AES2660_SRC) \ $(AES4000_SRC) \ $(FDU2000_SRC) \ $(VCOM5S_SRC) \ @@ -137,6 +139,10 @@ if ENABLE_AES2550 DRIVER_SRC += $(AES2550_SRC) endif +if ENABLE_AES2660 +DRIVER_SRC += $(AES2660_SRC) +endif + if ENABLE_AES4000 DRIVER_SRC += $(AES4000_SRC) endif diff --git a/libfprint/core.c b/libfprint/core.c index ddab4aa3..5315fdc7 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -374,6 +374,9 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_AES1660 &aes1660_driver, #endif +#ifdef ENABLE_AES2660 + &aes2660_driver, +#endif #ifdef ENABLE_VFS101 &vfs101_driver, #endif diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c new file mode 100644 index 00000000..bc1dd007 --- /dev/null +++ b/libfprint/drivers/aes2660.c @@ -0,0 +1,121 @@ +/* + * AuthenTec AES2660 driver for libfprint + * Copyright (C) 2012 Vasily Khoruzhick + * + * 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 + */ + +#define FP_COMPONENT "aes2660" + +#include + +#include +#include + +#include + +#include + +#include "aesx660.h" +#include "aes2660.h" +#include "driver_ids.h" + +#define FRAME_WIDTH 192 + +static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) +{ + /* TODO check that device has endpoints we're using */ + int r; + struct aesX660_dev *aesdev; + + r = libusb_claim_interface(dev->udev, 0); + if (r < 0) { + fp_err("could not claim interface 0"); + return r; + } + + dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev)); + if (!aesdev) + return -ENOMEM; + + aesdev->buffer = g_malloc0(AES2660_FRAME_SIZE + AESX660_HEADER_SIZE); + if (!aesdev->buffer) { + g_free(aesdev); + dev->priv = NULL; + return -ENOMEM; + } + + /* No scaling for AES2660 */ + aesdev->h_scale_factor = 1; + aesdev->init_seqs[0] = aes2660_init_1; + aesdev->init_seqs_len[0] = array_n_elements(aes2660_init_1); + aesdev->init_seqs[1] = aes2660_init_2; + aesdev->init_seqs_len[1] = array_n_elements(aes2660_init_2); + aesdev->start_imaging_cmd = (unsigned char *)aes2660_start_imaging_cmd; + aesdev->start_imaging_cmd_len = sizeof(aes2660_start_imaging_cmd); + aesdev->frame_width = FRAME_WIDTH; + + fpi_imgdev_open_complete(dev, 0); + return 0; +} + +static void dev_deinit(struct fp_img_dev *dev) +{ + struct aesX660_dev *aesdev = dev->priv; + g_free(aesdev->buffer); + g_free(aesdev); + libusb_release_interface(dev->udev, 0); + fpi_imgdev_close_complete(dev); +} + +static const struct usb_id id_table[] = { + { .vendor = 0x08ff, .product = 0x2660 }, + { .vendor = 0x08ff, .product = 0x2680 }, + { .vendor = 0x08ff, .product = 0x2681 }, + { .vendor = 0x08ff, .product = 0x2682 }, + { .vendor = 0x08ff, .product = 0x2683 }, + { .vendor = 0x08ff, .product = 0x2684 }, + { .vendor = 0x08ff, .product = 0x2685 }, + { .vendor = 0x08ff, .product = 0x2686 }, + { .vendor = 0x08ff, .product = 0x2687 }, + { .vendor = 0x08ff, .product = 0x2688 }, + { .vendor = 0x08ff, .product = 0x2689 }, + { .vendor = 0x08ff, .product = 0x268a }, + { .vendor = 0x08ff, .product = 0x268b }, + { .vendor = 0x08ff, .product = 0x268c }, + { .vendor = 0x08ff, .product = 0x268d }, + { .vendor = 0x08ff, .product = 0x268e }, + { .vendor = 0x08ff, .product = 0x268f }, + { .vendor = 0x08ff, .product = 0x2691 }, + { 0, 0, 0, }, +}; + +struct fp_img_driver aes2660_driver = { + .driver = { + .id = AES2660_ID, + .name = FP_COMPONENT, + .full_name = "AuthenTec AES2660", + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + .flags = 0, + .img_height = -1, + .img_width = FRAME_WIDTH, + + .open = dev_init, + .close = dev_deinit, + .activate = aesX660_dev_activate, + .deactivate = aesX660_dev_deactivate, +}; diff --git a/libfprint/drivers/aes2660.h b/libfprint/drivers/aes2660.h new file mode 100644 index 00000000..c85bb0a3 --- /dev/null +++ b/libfprint/drivers/aes2660.h @@ -0,0 +1,1964 @@ +/* + * AuthenTec AES2660 driver for libfprint + * Copyright (c) 2012 Vasily Khoruzhick + * + * 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 __AES2660_H +#define __AES2660_H + +#define AES2660_FRAME_SIZE 0x354 + +/* First init sequence, 0x07 cmd returns following before INIT1: + * { 0x07, 0x05, 0x00, 0x91, 0x26, 0x21, 0x00, 0x00 } + */ + +/* INIT1 */ + +static const unsigned char pkt13[] = { +0x44, 0x02, 0x00, 0x04, 0x00, +0x0d, +0x23, +0x42, 0xca, 0x00, +0x00, 0x20, 0x7f, /* .#B... . */ +0x97, 0x37, 0xcf, 0xdf, 0x96, 0x26, 0xcf, 0xdf, /* .7...&.. */ +0x96, 0xff, 0x96, 0x9f, 0x22, 0x6d, 0x2e, 0x6a, /* ...."m.j */ +0xbf, 0x62, 0x23, 0x23, 0x83, 0xdd, 0x97, 0x26, /* .b##...& */ +0xaf, 0xdd, 0x97, 0x37, 0xaf, 0xa9, 0xcf, 0x70, /* ...7...p */ +0x18, 0xa9, 0xaf, 0x02, 0xef, 0x5d, 0xaf, 0xc5, /* .....].. */ +0xef, 0x2f, 0xff, 0xff, 0x96, 0xdf, 0x96, 0x69, /* ./.....i */ +0xef, 0x20, 0xff, 0xff, 0x96, 0xdf, 0x96, 0x1a, /* . ...... */ +0x27, 0x0b, 0xef, 0x06, 0xaf, 0xf1, 0x81, 0x3a, /* '......: */ +0xff, 0x3f, 0x1d, 0xc1, 0x2e, 0xa3, 0xbf, 0xc2, /* .?...... */ +0x2e, 0x00, 0xdf, 0xff, 0x2d, 0x02, 0x5a, 0xbf, /* ....-.Z. */ +0x22, 0xc1, 0x2e, 0xa3, 0xbf, 0x3c, 0x23, 0x57, /* "....<#W */ +0x23, 0x02, 0x2e, 0x30, 0x80, 0x05, 0x27, 0x12, /* #..0..'. */ +0xef, 0x99, 0xaf, 0x10, 0xef, 0x9b, 0xaf, 0x10, /* ........ */ +0xef, 0x55, 0xaf, 0x3d, 0x23, 0x30, 0xef, 0x20, /* .U.=#0. */ +0xff, 0x1a, 0x27, 0x05, 0xef, 0x27, 0xff, 0x06, /* ..'..'.. */ +0x27, 0x05, 0x27, 0x3f, 0x80, 0x2b, 0x0d, 0x05, /* '.'?.+.. */ +0x27, 0xe5, 0x31, 0x05, 0x81, 0xe5, 0x39, 0x05, /* '.1...9. */ +0x27, 0xc8, 0x46, 0x0e, 0x5b, 0xd3, 0x45, 0xfd, /* '.F.[.E. */ +0x5a, 0x0f, 0x27, 0xd3, 0x45, 0xfa, 0x5a, 0x0f, /* Z.'.E.Z. */ +0x27, 0xd3, 0x45, 0xf7, 0x5a, 0x41, 0x2e, 0xa1, /* '.E.ZA.. */ +0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, 0xbf, 0x02, /* ..(A.... */ +0x2e, 0x57, 0x80, 0x05, 0x27, 0x9f, 0x22, 0xbf, /* .W..'.". */ +0x22, 0x1f, 0x20, 0xfd, 0x53, 0x3f, 0x20, 0x14, /* ". .S? . */ +0x1f, 0xfa, 0x55, 0x05, 0x27, 0x10, 0xef, 0xd0, /* ..U.'... */ +0x81, 0x65, 0xaf, 0x10, 0xef, 0xd0, 0x81 /* .e..... */ +}; + +static const unsigned char pkt15[] = { +0x42, 0x48, 0x00, +0x64, 0x20, 0x9c, 0xaf, 0x10, /* BH.d ... */ +0xef, 0xd0, 0x81, 0x9a, 0xaf, 0x05, 0x27, 0x11, /* ......'. */ +0x00, 0x51, 0x87, 0x91, 0x81, 0xd1, 0x6c, 0xd2, /* .Q....l. */ +0x75, 0xe2, 0x80, 0xf2, 0x80, 0xf0, 0x57, 0xf4, /* u.....W. */ +0x7b, 0xf8, 0x7e, 0xfc, 0x8b, 0x10, 0xcf, 0x7c, /* {.~....| */ +0xff, 0x3f, 0x00, 0x20, 0xff, 0x00, 0x13, 0x1a, /* .?. .... */ +0x27, 0x07, 0x27, 0x05, 0x27, 0x01, 0x00, 0x11, /* '.'.'... */ +0x00, 0x21, 0x00, 0x31, 0x00, 0x31, 0x01, 0x32, /* .!.1.1.2 */ +0x01, 0x33, 0x01, 0x33, 0x03, 0x43, 0x03, 0x53, /* .3.3.C.S */ +0x03, 0x63, 0x03 /* .c. */ +}; + +static const unsigned char pkt17[] = { +0x42, 0xca, 0x00, +0x87, 0x20, 0x51, 0x85, 0x44, /* B... Q.D */ +0x1e, 0x03, 0x55, 0xc8, 0x46, 0x01, 0x5b, 0xe4, /* ..U.F.[. */ +0x2f, 0xc9, 0x50, 0x49, 0x1e, 0x16, 0x55, 0xe4, /* /.PI..U. */ +0x2f, 0xc5, 0x50, 0x02, 0xef, 0x02, 0x2e, 0x62, /* /.P....b */ +0x82, 0xfe, 0xcf, 0x08, 0xaf, 0xfe, 0xcf, 0x09, /* ........ */ +0xaf, 0xfe, 0xcf, 0x0b, 0xaf, 0x55, 0x81, 0x02, /* .....U.. */ +0xcf, 0x0f, 0x1c, 0x40, 0x18, 0x08, 0x42, 0x00, /* ...@..B. */ +0x5b, 0x20, 0x18, 0x3d, 0x23, 0x02, 0xaf, 0x10, /* [ .=#... */ +0xef, 0x55, 0xaf, 0x05, 0x27, 0x4a, 0x1e, 0x01, /* .U..'J.. */ +0x55, 0xe4, 0x2f, 0xac, 0x50, 0x4e, 0x1e, 0x01, /* U./.PN.. */ +0x55, 0x00, 0x2e, 0x0d, 0x7b, 0x4f, 0x1e, 0x01, /* U...{O.. */ +0x55, 0x02, 0x2e, 0xbd, 0x71, 0x51, 0x1e, 0x1a, /* U...qQ.. */ +0x55, 0xf9, 0xcf, 0x67, 0xaf, 0xcf, 0x1c, 0xf9, /* U..g.... */ +0xaf, 0xff, 0x86, 0xbf, 0x22, 0x09, 0xbf, 0xfe, /* ...."... */ +0xdf, 0x00, 0x2e, 0xd7, 0x8b, 0x01, 0xef, 0x3b, /* .......; */ +0xaf, 0x01, 0x2e, 0x63, 0x84, 0x3b, 0x80, 0x3b, /* ...c.;.; */ +0xcf, 0x1f, 0x99, 0x01, 0x2e, 0x07, 0x85, 0x00, /* ........ */ +0x2e, 0xa7, 0x8a, 0xbf, 0x22, 0xc1, 0x2e, 0x49, /* ...."..I */ +0xbf, 0x67, 0xcf, 0xf9, 0xaf, 0x05, 0x27, 0x54, /* .g....'T */ +0x1e, 0x32, 0x55, 0x04, 0xef, 0x20, 0x80, 0xe4, /* .2U.. .. */ +0x2f, 0x81, 0x5a, 0x23, 0x81, 0xfe, 0xcf, 0xfe, /* /.Z#.... */ +0xdf, 0xff, 0x96, 0xdf, 0x96, 0xfe, 0xcf, 0xfe, /* ........ */ +0xdf, 0xff, 0x96, 0xdf, 0x96, 0xdf, 0x22, 0x01, /* ......". */ +0x55, 0xff, 0x22, 0x06, 0x54, 0xc1, 0x97, 0x83, /* U.".T... */ +0x03, 0x0e, 0x52, 0x02, 0x5e, 0xc0, 0x97, 0x82, /* ..R.^... */ +0x03, 0x0a, 0x52, 0xc2, 0x97 /* ..R.. */ +}; + +static const unsigned char pkt19[] = { +0x42, 0xca, 0x00, +0xeb, 0x20, 0xc3, 0x9f, 0xcd, /* B... ... */ +0x80, 0x07, 0x80, 0x00, 0xef, 0xff, 0xaf, 0x00, /* ........ */ +0x2e, 0xa7, 0x8a, 0x04, 0x0c, 0x29, 0x81, 0x05, /* .....).. */ +0x27, 0xc0, 0x97, 0xc1, 0x9f, 0xcd, 0x80, 0x07, /* '....... */ +0x80, 0x01, 0xef, 0xff, 0xaf, 0x00, 0x2e, 0xa9, /* ........ */ +0x8a, 0xc2, 0x97, 0xc3, 0x9f, 0x80, 0x01, 0x41, /* .......A */ +0x01, 0x9f, 0x90, 0xff, 0x90, 0x02, 0x2e, 0xe3, /* ........ */ +0x70, 0x55, 0x1e, 0x16, 0x55, 0x54, 0x85, 0xe4, /* pU..UT.. */ +0x2f, 0x4d, 0x5b, 0x07, 0xef, 0x20, 0x80, 0xe4, /* /M[.. .. */ +0x2f, 0x49, 0x5a, 0xfe, 0xcf, 0x0a, 0xaf, 0xfe, /* /IZ..... */ +0xcf, 0xfe, 0xcf, 0x41, 0x2e, 0x44, 0xbf, 0xfe, /* ...A.D.. */ +0xcf, 0x41, 0x2e, 0x45, 0xbf, 0xfe, 0xcf, 0x52, /* .A.E...R */ +0xaf, 0xfe, 0xcf, 0x53, 0xaf, 0xfe, 0xcf, 0x5a, /* ...S...Z */ +0xaf, 0x05, 0x27, 0x58, 0x1e, 0x0d, 0x55, 0x02, /* ..'X..U. */ +0x44, 0x01, 0x5a, 0x00, 0x2e, 0x54, 0x79, 0xfe, /* D.Z..Ty. */ +0xcf, 0x75, 0xaf, 0xfe, 0xdf, 0x76, 0xbf, 0x41, /* .u...v.A */ +0x2e, 0xa4, 0xdf, 0xdf, 0x29, 0x41, 0x2e, 0xa4, /* ....)A.. */ +0xbf, 0x05, 0x27, 0x59, 0x1e, 0x03, 0x55, 0xfe, /* ..'Y..U. */ +0xcf, 0x10, 0xaf, 0x01, 0x2e, 0x94, 0x76, 0x63, /* ......vc */ +0x1e, 0x1a, 0x55, 0x54, 0x85, 0xe4, 0x2f, 0x1e, /* ..UT../. */ +0x5b, 0x0c, 0xef, 0x20, 0x80, 0xe4, 0x2f, 0x1a, /* [.. ../. */ +0x5a, 0xf0, 0xef, 0x00, 0xff, 0x19, 0x27, 0x08, /* Z.....'. */ +0xef, 0x06, 0xaf, 0xfe, 0xcf, 0x5f, 0x9f, 0x06, /* ....._.. */ +0x25, 0xfb, 0x55, 0xfe, 0xcf, 0xfe, 0xcf, 0x41, /* %.U....A */ +0x2e, 0x40, 0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x41, /* .@...A.A */ +0xbf, 0xfe, 0xcf, 0x41, 0x2e /* ...A. */ +}; + +static const unsigned char pkt21[] = { +0x42, 0xca, 0x00, +0x4f, 0x21, 0x42, 0xbf, 0x05, /* B..O!B.. */ +0x27, 0x64, 0x1e, 0x31, 0x55, 0xb0, 0xef, 0x00, /* 'd.1U... */ +0xff, 0x19, 0x27, 0x0b, 0xef, 0x06, 0xaf, 0xfe, /* ..'..... */ +0xcf, 0x5f, 0x9f, 0x06, 0x25, 0xfb, 0x55, 0xfe, /* ._..%.U. */ +0xcf, 0x56, 0xaf, 0xfe, 0xcf, 0xae, 0xdf, 0x1f, /* .V...... */ +0x1c, 0xe0, 0x1d, 0x5f, 0x02, 0xae, 0xbf, 0xfe, /* ..._.... */ +0xcf, 0x41, 0x2e, 0x54, 0xbf, 0xfe, 0xcf, 0x41, /* .A.T...A */ +0x2e, 0x77, 0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x55, /* .w...A.U */ +0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x78, 0xbf, 0xfe, /* ...A.x.. */ +0xcf, 0xbb, 0xaf, 0xfe, 0xcf, 0xbc, 0xaf, 0xfe, /* ........ */ +0xcf, 0xbd, 0xaf, 0xfe, 0xcf, 0xbe, 0xaf, 0xfe, /* ........ */ +0xcf, 0x83, 0xaf, 0xfe, 0xcf, 0x84, 0xaf, 0xfe, /* ........ */ +0xcf, 0x81, 0xaf, 0xfe, 0xcf, 0x82, 0xaf, 0xfe, /* ........ */ +0xcf, 0x24, 0xaf, 0xfe, 0xcf, 0x02, 0x33, 0x05, /* .$....3. */ +0x27, 0x66, 0x1e, 0x0b, 0x55, 0xc5, 0xef, 0x2f, /* 'f..U../ */ +0xff, 0x1a, 0x27, 0x0b, 0xef, 0x06, 0xaf, 0xfe, /* ..'..... */ +0xcf, 0xfe, 0xdf, 0x06, 0x27, 0x01, 0x0e, 0x06, /* ....'... */ +0x25, 0xf9, 0x55, 0x05, 0x27, 0x73, 0x1e, 0x02, /* %.U.'s.. */ +0x55, 0x02, 0x2e, 0x5a, 0x88, 0x05, 0x27, 0x7d, /* U..Z..'} */ +0x1e, 0x0c, 0x55, 0x02, 0x2e, 0xb7, 0x81, 0xe3, /* ..U..... */ +0x2f, 0xb9, 0x5a, 0xfe, 0xcf, 0xfe, 0xdf, 0x1b, /* /.Z..... */ +0x27, 0xfe, 0xcf, 0x36, 0x03, 0xfe, 0xdf, 0x3f, /* '..6...? */ +0x02, 0x9f, 0x9d, 0x05, 0x27, 0x7e, 0x1e, 0x0c, /* ....'~.. */ +0x55, 0x02, 0x2e, 0xb7, 0x81, 0xe3, 0x2f, 0xaa, /* U...../. */ +0x5a, 0xfe, 0xcf, 0xfe, 0xdf, 0x1b, 0x27, 0x07, /* Z.....'. */ +0x80, 0xf6, 0x97, 0xff, 0xaf /* ..... */ +}; + +static const unsigned char pkt23[] = { +0x42, 0xca, 0x00, +0xb3, 0x21, 0x00, 0x2e, 0xa7, /* B...!... */ +0x8a, 0x05, 0x27, 0x61, 0x74, 0xff, 0x96, 0xc6, /* ..'at... */ +0x2e, 0x01, 0xdf, 0x3f, 0x2c, 0xdd, 0x9f, 0x05, /* ...?,... */ +0x27, 0x01, 0xef, 0x20, 0x80, 0xe3, 0x2f, 0x96, /* '.. ../. */ +0x5a, 0xfe, 0xcf, 0xdf, 0x22, 0xe9, 0x2f, 0xf0, /* Z..."./. */ +0x54, 0x01, 0xff, 0x85, 0xef, 0xff, 0x96, 0xdf, /* T....... */ +0x96, 0x34, 0xff, 0x8d, 0xef, 0x19, 0x27, 0x03, /* .4....'. */ +0xcf, 0x7f, 0x1c, 0x5f, 0x9f, 0xdd, 0x97, 0x5f, /* ..._..._ */ +0x9f, 0xdd, 0x97, 0x5f, 0x9f, 0x05, 0xef, 0x06, /* ..._.... */ +0xaf, 0x9f, 0x22, 0x5f, 0x9f, 0x06, 0x25, 0xfc, /* .."_..%. */ +0x55, 0x5f, 0x9f, 0x06, 0x25, 0xfc, 0x55, 0x20, /* U_..%.U */ +0xef, 0x08, 0xaf, 0x09, 0x23, 0x01, 0x2e, 0x06, /* ....#... */ +0x82, 0x51, 0x81, 0x03, 0xef, 0xfc, 0xaf, 0x84, /* .Q...... */ +0xef, 0xaa, 0xaf, 0x08, 0xef, 0xe3, 0xaf, 0x9f, /* ........ */ +0x22, 0xe2, 0xaf, 0x21, 0xef, 0x41, 0x2e, 0x47, /* "..!.A.G */ +0xbf, 0x27, 0xef, 0xf4, 0xaf, 0x2d, 0xff, 0xa7, /* .'...-.. */ +0xef, 0xe1, 0xbf, 0xe0, 0xaf, 0x08, 0xef, 0x10, /* ........ */ +0xaf, 0x01, 0x2e, 0x94, 0x86, 0xed, 0x80, 0x01, /* ........ */ +0x2e, 0x18, 0x87, 0x01, 0x2e, 0x1a, 0x87, 0x9b, /* ........ */ +0x22, 0x9b, 0x22, 0x34, 0xff, 0x95, 0xef, 0x19, /* "."4.... */ +0x27, 0x2d, 0xff, 0xa7, 0xef, 0x1a, 0x27, 0xc0, /* '-....'. */ +0xef, 0x06, 0xaf, 0xdc, 0x97, 0x5f, 0x9f, 0x06, /* ....._.. */ +0xdf, 0xc0, 0x1f, 0x03, 0x54, 0xdf, 0x22, 0x01, /* ....T.". */ +0x54, 0x00, 0x2e, 0xb9, 0x8b, 0x06, 0x25, 0xf4, /* T.....%. */ +0x55, 0x34, 0xff, 0x91, 0xef, 0x19, 0x27, 0xdd, /* U4....'. */ +0x97, 0xdd, 0x9f, 0x5f, 0x9f /* ..._. */ +}; + +static const unsigned char pkt25[] = { +0x42, 0xb2, 0x00, +0x17, 0x22, 0x7f, 0x9f, 0xfd, /* B..."... */ +0x0d, 0xdf, 0x22, 0x01, 0x55, 0xff, 0x22, 0x01, /* ..".U.". */ +0x54, 0x01, 0xef, 0x1f, 0x98, 0x2f, 0xef, 0x41, /* T..../.A */ +0x2e, 0x47, 0xbf, 0x11, 0xef, 0xf4, 0xaf, 0x2d, /* .G.....- */ +0xff, 0xa7, 0xef, 0xe1, 0xbf, 0xe0, 0xaf, 0x01, /* ........ */ +0x2e, 0x18, 0x87, 0x01, 0x2e, 0x1a, 0x87, 0x9b, /* ........ */ +0x22, 0x9b, 0x22, 0x35, 0xff, 0x55, 0xef, 0x19, /* "."5.U.. */ +0x27, 0x2d, 0xff, 0xa7, 0xef, 0x1a, 0x27, 0xc0, /* '-....'. */ +0xef, 0x06, 0xaf, 0xdc, 0x97, 0xff, 0x1a, 0x5f, /* ......._ */ +0x9f, 0x06, 0xdf, 0xc0, 0x1f, 0x03, 0x54, 0xdf, /* ......T. */ +0x22, 0x01, 0x54, 0x00, 0x2e, 0xb9, 0x8b, 0x06, /* ".T..... */ +0x25, 0xf3, 0x55, 0x34, 0xff, 0x93, 0xef, 0x19, /* %.U4.... */ +0x27, 0xdd, 0x97, 0xdd, 0x9f, 0x5f, 0x9f, 0x7f, /* '...._.. */ +0x9f, 0xfb, 0x0d, 0xdf, 0x22, 0x01, 0x54, 0x01, /* ....".T. */ +0xef, 0x1f, 0x98, 0xff, 0x22, 0x01, 0x54, 0x01, /* ....".T. */ +0xef, 0x1f, 0x98, 0x34, 0xff, 0x8d, 0xef, 0x19, /* ...4.... */ +0x27, 0x01, 0x2e, 0x0c, 0x85, 0x00, 0x2e, 0xa7, /* '....... */ +0x8a, 0x55, 0x81, 0x02, 0xef, 0xfc, 0xaf, 0x88, /* .U...... */ +0xef, 0xaa, 0xaf, 0x00, 0xef, 0x41, 0x2e, 0x47, /* .....A.G */ +0xbf, 0x05, 0x27, 0xf9, 0x35, 0xc1, 0x2e, 0x4e, /* ..'.5..N */ +0xdf, 0x0f, 0x1d, 0x09, 0x27, 0x5f, 0x02, 0xc1, /* ....'_.. */ +0x2e, 0x4e, 0xbf, 0x05, 0x27, 0x9f, 0x22, 0x02, /* .N..'.". */ +0x2e, 0xa6, 0x85, 0x05, 0x27 /* ....' */ +}; + +static const unsigned char pkt27[] = { +0x42, 0xca, 0x00, +0x6f, 0x22, 0x51, 0x85, 0x01, /* B..o"Q.. */ +0x1e, 0x38, 0x55, 0x26, 0x40, 0x12, 0x5b, 0x26, /* .8U&@.[& */ +0x42, 0x2e, 0x5a, 0x26, 0x41, 0x0e, 0x5a, 0x26, /* B.Z&A.Z& */ +0xcf, 0x40, 0x1a, 0x26, 0xaf, 0x9f, 0x2d, 0x27, /* .@.&..-' */ +0x5a, 0x07, 0x80, 0x01, 0xef, 0xff, 0xaf, 0x26, /* Z......& */ +0x43, 0x01, 0x5b, 0x74, 0x25, 0x00, 0x55, 0x26, /* C.[t%.U& */ +0x32, 0x00, 0x2e, 0xa7, 0x7a, 0x02, 0x2e, 0xc0, /* 2...z... */ +0x85, 0x26, 0x40, 0x08, 0x5b, 0x41, 0x2e, 0x52, /* .&@.[A.R */ +0xdf, 0xdf, 0x2d, 0x04, 0x5b, 0x26, 0x43, 0x01, /* ..-.[&C. */ +0x5b, 0x74, 0x25, 0x00, 0x55, 0x26, 0x32, 0x41, /* [t%.U&2A */ +0x2e, 0x53, 0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, /* .S...y.. */ +0x96, 0xdf, 0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, /* ...A.U.. */ +0x2e, 0x78, 0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, /* .x...].. */ +0x22, 0x00, 0x54, 0xff, 0xef, 0x2e, 0xaf, 0x05, /* ".T..... */ +0x27, 0x07, 0x80, 0x9f, 0x22, 0xff, 0xaf, 0x00, /* '..."... */ +0x2e, 0xa7, 0x8a, 0x05, 0x27, 0x03, 0x1e, 0x3f, /* ....'..? */ +0x55, 0x02, 0x2e, 0xad, 0x85, 0xa1, 0xcf, 0xfe, /* U....... */ +0x1c, 0xa1, 0xaf, 0xed, 0x80, 0x31, 0x81, 0x02, /* .....1.. */ +0x2e, 0x51, 0x83, 0xff, 0x96, 0xdf, 0x96, 0xa1, /* .Q...... */ +0xcf, 0x01, 0x18, 0xa1, 0xaf, 0xed, 0x80, 0x64, /* .......d */ +0xef, 0xbf, 0x22, 0xa9, 0x80, 0x31, 0x81, 0x02, /* .."..1.. */ +0x2e, 0x51, 0x83, 0xff, 0x96, 0xdf, 0x96, 0x9b, /* .Q...... */ +0x22, 0x14, 0x1e, 0x03, 0x53, 0xff, 0x22, 0x01, /* "...S.". */ +0x55, 0x00, 0x20, 0x0a, 0x50, 0xc3, 0x97, 0xc4, /* U. .P... */ +0x9f, 0x81, 0x01, 0x42, 0x01, 0x03, 0x52, 0xfa, /* ...B..R. */ +0x1e, 0x03, 0x53, 0xff, 0x22 /* ..S." */ +}; + +static const unsigned char pkt29[] = { +0x42, 0xca, 0x00, +0xd3, 0x22, 0x01, 0x55, 0x00, /* B...".U. */ +0x20, 0xf2, 0x50, 0x00, 0x2e, 0xd8, 0x8d, 0x03, /* .P..... */ +0xcf, 0x7f, 0x1c, 0xff, 0xaf, 0x05, 0xef, 0xff, /* ........ */ +0xaf, 0x00, 0xef, 0xff, 0xaf, 0xdd, 0x97, 0xff, /* ........ */ +0xaf, 0xc2, 0x97, 0xff, 0xaf, 0xc3, 0x97, 0xff, /* ........ */ +0xaf, 0xc0, 0x97, 0xff, 0xaf, 0xc1, 0x97, 0xff, /* ........ */ +0xaf, 0x04, 0x0c, 0x00, 0x2e, 0xa7, 0x8a, 0x05, /* ........ */ +0x27, 0x06, 0x1e, 0x01, 0x55, 0x0f, 0x27, 0x0f, /* '...U.'. */ +0x27, 0x0a, 0x1e, 0x08, 0x55, 0x02, 0x2e, 0xf6, /* '...U... */ +0x82, 0xa8, 0x77, 0x3b, 0x30, 0x07, 0x35, 0xff, /* ..w;0.5. */ +0xff, 0xc2, 0xbf, 0x0d, 0x27, 0x0c, 0x27, 0x0d, /* ....'.'. */ +0x1e, 0x02, 0x55, 0x54, 0x85, 0xf5, 0x5b, 0xbd, /* ..UT..[. */ +0x77, 0x12, 0x1e, 0x07, 0x55, 0xdc, 0xef, 0x05, /* w...U... */ +0xff, 0x1a, 0x27, 0x56, 0xdf, 0x3f, 0x20, 0x59, /* ..'V.? Y */ +0x80, 0x3c, 0xaf, 0x05, 0x27, 0x13, 0x1e, 0x01, /* .<..'... */ +0x55, 0x3c, 0x23, 0x05, 0x27, 0x1f, 0x1e, 0x06, /* U<#.'... */ +0x55, 0x37, 0x35, 0x08, 0xef, 0x40, 0x2e, 0xf0, /* U75..@.. */ +0xbf, 0x40, 0x2e, 0xf6, 0xbf, 0x05, 0x27, 0x20, /* .@....' */ +0x1e, 0x06, 0x55, 0x37, 0x3d, 0x16, 0xef, 0x40, /* ..U7=..@ */ +0x2e, 0xf0, 0xbf, 0x40, 0x2e, 0xf6, 0xbf, 0x05, /* ...@.... */ +0x27, 0x2e, 0x1e, 0x0c, 0x55, 0x02, 0x2e, 0x57, /* '...U..W */ +0x80, 0x41, 0x2e, 0xa1, 0xdf, 0xdf, 0x2a, 0x41, /* .A....*A */ +0x2e, 0xa1, 0xbf, 0x02, 0x2e, 0x57, 0x80, 0x9b, /* .....W.. */ +0x22, 0xdf, 0x2f, 0xd3, 0x50, 0x05, 0x27, 0x2f, /* "./.P.'/ */ +0x1e, 0x0c, 0x55, 0x02, 0x2e, 0x57, 0x80, 0x41, /* ..U..W.A */ +0x2e, 0xa1, 0xdf, 0xdf, 0x2a /* ....* */ +}; + +static const unsigned char pkt31[] = { +0x42, 0x88, 0x00, +0x37, 0x23, 0x41, 0x2e, 0xa1, /* B..7#A.. */ +0xbf, 0x02, 0x2e, 0x57, 0x80, 0x08, 0x18, 0x41, /* ...W...A */ +0x2e, 0xa1, 0xbf, 0x05, 0x27, 0x30, 0x1e, 0x0e, /* ....'0.. */ +0x55, 0x7e, 0xef, 0xff, 0xaf, 0x02, 0xef, 0xff, /* U~...... */ +0xaf, 0x00, 0xef, 0xff, 0xaf, 0xff, 0xef, 0x1f, /* ........ */ +0xff, 0x1a, 0x27, 0x07, 0x27, 0xff, 0xaf, 0xff, /* ..'.'... */ +0xbf, 0x00, 0x2e, 0xa7, 0x8a, 0x05, 0x27, 0xf7, /* ......'. */ +0x74, 0xc9, 0xcf, 0xf3, 0x1c, 0x04, 0x18, 0xc9, /* t....... */ +0xaf, 0x23, 0x81, 0x10, 0xff, 0xff, 0xef, 0xc1, /* .#...... */ +0x2e, 0x7c, 0xbf, 0x41, 0x2e, 0x7b, 0xbf, 0x02, /* .|.A.{.. */ +0xef, 0x41, 0x2e, 0x7a, 0xbf, 0xc9, 0x31, 0x18, /* .A.z..1. */ +0xef, 0xc0, 0xaf, 0x04, 0x27, 0x41, 0x2e, 0x7a, /* ....'A.z */ +0xdf, 0xdf, 0x2d, 0x08, 0x5b, 0x01, 0xef, 0x41, /* ..-.[..A */ +0x2e, 0x7a, 0xbf, 0xc0, 0x23, 0x18, 0xef, 0xc1, /* .z..#... */ +0xaf, 0xcb, 0xcf, 0xcc, 0xdf, 0x05, 0x27, 0xc9, /* ......'. */ +0x30, 0x01, 0xef, 0x41, 0x2e, 0x7a, 0xbf, 0xc0, /* 0..A.z.. */ +0x23, 0x18, 0xef, 0xc1, 0xaf, 0x9f, 0x22, 0xbf, /* #.....". */ +0x22, 0x05, 0x27 /* ".' */ +}; + +static const unsigned char pkt33[] = { +0x42, 0xca, 0x00, +0x7a, 0x23, 0x9b, 0x22, 0xff, /* B..z#.". */ +0x86, 0x02, 0x2e, 0x96, 0x83, 0xc2, 0x85, 0x00, /* ........ */ +0xef, 0x41, 0x2e, 0x76, 0xbf, 0x56, 0x87, 0x02, /* .A.v.V.. */ +0x2e, 0xed, 0x83, 0x78, 0x86, 0x02, 0x33, 0x07, /* ...x..3. */ +0x80, 0xdd, 0x97, 0xff, 0xaf, 0x00, 0x2e, 0xa7, /* ........ */ +0x8a, 0x05, 0x27, 0x6c, 0xcf, 0x6d, 0xdf, 0xbf, /* ..'l.m.. */ +0x01, 0x6c, 0xaf, 0x6d, 0x26, 0x00, 0x2e, 0x2c, /* .l.m&.., */ +0x55, 0x00, 0x2e, 0x47, 0x50, 0x9f, 0x22, 0x6b, /* U..GP."k */ +0xaf, 0x62, 0xaf, 0x6d, 0x2e, 0x6a, 0xbf, 0x01, /* .b.m.j.. */ +0x2e, 0x3f, 0x84, 0x00, 0xef, 0x41, 0x2e, 0x44, /* .?...A.D */ +0xbf, 0xbf, 0xef, 0x41, 0x2e, 0x45, 0xbf, 0x80, /* ...A.E.. */ +0xef, 0x0a, 0xaf, 0x01, 0x2e, 0x06, 0x82, 0x80, /* ........ */ +0x82, 0x84, 0x82, 0x6b, 0xcf, 0x10, 0xaf, 0x01, /* ...k.... */ +0x2e, 0x94, 0x86, 0x40, 0xef, 0x6d, 0xaf, 0x80, /* ...@.m.. */ +0xef, 0x6c, 0xaf, 0x01, 0x2e, 0xf9, 0x81, 0xed, /* .l...... */ +0x80, 0x01, 0x2e, 0x18, 0x87, 0x01, 0x2e, 0x1a, /* ........ */ +0x87, 0x07, 0x87, 0xff, 0x2f, 0xd1, 0x5a, 0x6c, /* ..../.Zl */ +0xcf, 0x6d, 0xdf, 0x3f, 0x00, 0x6c, 0xaf, 0x6d, /* .m.?.l.m */ +0x26, 0x03, 0x54, 0x6d, 0xdf, 0x0c, 0x82, 0x6d, /* &.Tm...m */ +0xbf, 0xeb, 0x50, 0x6b, 0xcf, 0x08, 0x1e, 0x11, /* ..Pk.... */ +0x5f, 0x6c, 0x24, 0x02, 0x53, 0xff, 0xef, 0x6c, /* _l$.S..l */ +0xaf, 0x10, 0x50, 0x6c, 0x24, 0x02, 0x53, 0xff, /* ..Pl$.S. */ +0xef, 0x6c, 0xaf, 0x0b, 0x50, 0x6b, 0xcf, 0x0a, /* .l..Pk.. */ +0x1e, 0x08, 0x55, 0x6c, 0x24, 0x02, 0x53, 0xff, /* ..Ul$.S. */ +0xef, 0x6c, 0xaf, 0x03, 0x50, 0x6c, 0x24, 0x01, /* .l..Pl$. */ +0x53, 0xff, 0xef, 0x6c, 0xaf /* S..l. */ +}; + +static const unsigned char pkt35[] = { +0x42, 0xca, 0x00, +0xde, 0x23, 0x6b, 0xcf, 0xdf, /* B...#k.. */ +0x96, 0xb0, 0xef, 0x00, 0xff, 0x1d, 0x00, 0x00, /* ........ */ +0x13, 0x1b, 0x27, 0x6c, 0xcf, 0x9f, 0x9d, 0x6b, /* ..'l...k */ +0xcf, 0x1f, 0x20, 0x6b, 0xaf, 0x0a, 0x1e, 0xbc, /* .. k.... */ +0x5f, 0x05, 0x27, 0x01, 0x2e, 0x3f, 0x84, 0x55, /* _.'..?.U */ +0x82, 0x01, 0x2e, 0x06, 0x82, 0x73, 0x23, 0x0a, /* .....s#. */ +0xef, 0x10, 0xaf, 0x01, 0x2e, 0x94, 0x86, 0x80, /* ........ */ +0xef, 0x01, 0x2e, 0xf9, 0x81, 0xed, 0x80, 0x08, /* ........ */ +0xef, 0x06, 0xaf, 0x01, 0x2e, 0x18, 0x87, 0x01, /* ........ */ +0x2e, 0x1a, 0x87, 0x06, 0x25, 0xf9, 0x55, 0x02, /* ....%.U. */ +0x2e, 0x52, 0x84, 0x4e, 0x23, 0x40, 0xcf, 0xe0, /* .R.N#@.. */ +0xaf, 0x41, 0xdf, 0xe1, 0xbf, 0x41, 0x2e, 0x4e, /* .A...A.N */ +0xdf, 0xf7, 0x1c, 0x41, 0x2e, 0x4e, 0xbf, 0x01, /* ...A.N.. */ +0x2e, 0x18, 0x87, 0x01, 0x2e, 0x1a, 0x87, 0x45, /* .......E */ +0x82, 0x4e, 0x24, 0x4e, 0xcf, 0x20, 0x1e, 0x03, /* .N$N. .. */ +0x55, 0x01, 0xef, 0x1f, 0x90, 0x02, 0x2e, 0x87, /* U....... */ +0x73, 0x40, 0x2e, 0x8f, 0xdf, 0xdf, 0x22, 0xe5, /* s@....". */ +0x55, 0x4e, 0x86, 0x4e, 0x23, 0x4e, 0xcf, 0x52, /* UN.N#N.R */ +0x86, 0x59, 0x86, 0x3f, 0x9f, 0x4e, 0xcf, 0x52, /* .Y.?.N.R */ +0x86, 0x5f, 0x86, 0x1f, 0x9f, 0x4e, 0x24, 0x4e, /* ._...N$N */ +0xcf, 0x04, 0x1e, 0xf3, 0x55, 0xf8, 0x0f, 0x08, /* ....U... */ +0xef, 0x06, 0xaf, 0xf6, 0x97, 0xbc, 0x03, 0x01, /* ........ */ +0x5f, 0xff, 0x0f, 0xfc, 0x97, 0x06, 0x25, 0xf9, /* _.....%. */ +0x55, 0xf8, 0x0f, 0x08, 0xff, 0x06, 0xbf, 0xf6, /* U....... */ +0x9f, 0xdf, 0x01, 0xa1, 0x27, 0x7f, 0x21, 0x3f, /* ....'.!? */ +0x9f, 0x06, 0x25, 0xf8, 0x55 /* ..%.U */ +}; + +static const unsigned char pkt37[] = { +0x42, 0xb2, 0x00, +0x42, 0x24, 0xf8, 0x0f, 0x04, /* B..B$... */ +0xef, 0x06, 0xaf, 0xbb, 0xef, 0x00, 0xff, 0x1a, /* ........ */ +0x27, 0xfc, 0x9f, 0xfc, 0x97, 0x09, 0x27, 0x5f, /* '.....'_ */ +0x02, 0x3f, 0x97, 0x06, 0x25, 0xf8, 0x55, 0x81, /* .?..%.U. */ +0xcf, 0x24, 0xaf, 0x05, 0x27, 0x0a, 0xef, 0x73, /* .$..'..s */ +0x43, 0x02, 0x5b, 0x73, 0xcf, 0x09, 0x27, 0x0f, /* C.[s..'. */ +0x1c, 0x81, 0xaf, 0x73, 0xcf, 0x09, 0x27, 0x30, /* ...s..'0 */ +0x1c, 0xfc, 0xdf, 0xcf, 0x1d, 0x5f, 0x02, 0xfc, /* ....._.. */ +0xbf, 0x81, 0xcf, 0x10, 0xaf, 0x01, 0x2e, 0x94, /* ........ */ +0x86, 0x80, 0x82, 0x01, 0x2e, 0x34, 0x81, 0x40, /* .....4.@ */ +0xef, 0x6b, 0xaf, 0x80, 0xef, 0x82, 0xaf, 0x01, /* .k...... */ +0x2e, 0xf9, 0x81, 0xed, 0x80, 0x01, 0x2e, 0x18, /* ........ */ +0x87, 0x01, 0x2e, 0x1a, 0x87, 0x16, 0x82, 0x01, /* ........ */ +0x2e, 0x2f, 0x89, 0x0a, 0x5b, 0x73, 0x43, 0x19, /* ./..[sC. */ +0x5a, 0x81, 0xcf, 0x5e, 0xdf, 0xbf, 0x03, 0x15, /* Z..^.... */ +0x5f, 0x5f, 0x20, 0x81, 0xaf, 0xdf, 0x22, 0x11, /* __ ...". */ +0x54, 0xde, 0x50, 0x40, 0x2e, 0x8f, 0xdf, 0x1f, /* T.P@.... */ +0x2c, 0x00, 0x2e, 0x0c, 0x5a, 0x5f, 0x2c, 0x09, /* ,...Z_,. */ +0x5b, 0x82, 0xcf, 0x6b, 0xdf, 0x3f, 0x00, 0x82, /* [..k.?.. */ +0xaf, 0x6b, 0x26, 0xe7, 0x54, 0x6b, 0xdf, 0x0c, /* .k&.Tk.. */ +0x82, 0x6b, 0xbf, 0xd8, 0x50, 0x05, 0x27, 0x82, /* .k..P.'. */ +0xcf, 0x6b, 0xdf, 0xbf, 0x01, 0x82, 0xaf, 0x6b, /* .k.....k */ +0x26, 0xf4, 0x55, 0xdb, 0x50 /* &.U.P */ +}; + +static const unsigned char pkt39[] = { +0x42, 0xca, 0x00, +0x9a, 0x24, 0xfa, 0xcf, 0xdf, /* B...$... */ +0x96, 0x37, 0xcf, 0xdf, 0x96, 0x08, 0xcf, 0xdf, /* .7...... */ +0x96, 0x3d, 0xcf, 0xdf, 0x96, 0x77, 0xcf, 0xdf, /* .=...w.. */ +0x96, 0x01, 0x2e, 0x08, 0x82, 0xdd, 0x97, 0x77, /* .......w */ +0xaf, 0xdd, 0x97, 0x3d, 0xaf, 0xdd, 0x97, 0x08, /* ...=.... */ +0xaf, 0xdd, 0x97, 0x37, 0xaf, 0xdd, 0x97, 0xfa, /* ...7.... */ +0xaf, 0x9f, 0x22, 0x6d, 0x2e, 0x6d, 0xbf, 0xfb, /* .."m.m.. */ +0x39, 0x08, 0x45, 0x00, 0x5a, 0xfb, 0x31, 0x0a, /* 9.E.Z.1. */ +0x42, 0x00, 0x5b, 0xa2, 0x39, 0x02, 0xcf, 0x5c, /* B.[.9..\ */ +0xaf, 0xe1, 0xef, 0x95, 0xaf, 0x9f, 0x22, 0x61, /* ......"a */ +0xaf, 0x62, 0xaf, 0x69, 0xaf, 0x6a, 0xaf, 0x16, /* .b.i.j.. */ +0xaf, 0x96, 0xaf, 0x29, 0xaf, 0x28, 0xaf, 0xc1, /* ...).(.. */ +0x2e, 0x49, 0xdf, 0x3f, 0x2d, 0x03, 0x5b, 0xa0, /* .I.?-.[. */ +0xcf, 0x8f, 0x1c, 0x20, 0x18, 0xa0, 0xaf, 0xa1, /* ... .... */ +0xcf, 0xdf, 0x1c, 0xa1, 0xaf, 0xed, 0x80, 0x02, /* ........ */ +0x47, 0x06, 0x5a, 0x0a, 0x41, 0x04, 0x5a, 0x0a, /* G.Z.A.Z. */ +0xdf, 0x30, 0x1d, 0x30, 0x1f, 0x00, 0x54, 0x01, /* .0.0..T. */ +0xef, 0x44, 0xaf, 0x09, 0xef, 0x60, 0xaf, 0xa7, /* .D...`.. */ +0xef, 0x40, 0xaf, 0x2d, 0xef, 0x41, 0xaf, 0x0a, /* .@.-.A.. */ +0x40, 0x06, 0x5a, 0x10, 0xcf, 0x27, 0xaf, 0xe2, /* @.Z..'.. */ +0x23, 0x6e, 0x23, 0x08, 0xef, 0xe3, 0xaf, 0x6f, /* #n#....o */ +0xaf, 0xe2, 0x23, 0x08, 0xef, 0xe3, 0xaf, 0x79, /* ..#....y */ +0x82, 0x4d, 0xaf, 0xdf, 0x96, 0x64, 0xdf, 0x8b, /* .M...d.. */ +0x82, 0x93, 0xbf, 0xdd, 0x97, 0x77, 0xff, 0x8b, /* .....w.. */ +0x82, 0x94, 0xbf, 0x9e, 0x23, 0xe4, 0x23, 0x9f, /* ....#.#. */ +0x22, 0x6d, 0x2e, 0x6b, 0xbf /* "m.k. */ +}; + +static const unsigned char pkt41[] = { +0x42, 0x12, 0x00, +0xfe, 0x24, 0x6d, 0x2e, 0x6a, /* B...$m.j */ +0xbf, 0x6d, 0x2e, 0x6c, 0xbf, 0xa5, 0xcf, 0xf3, /* .m.l.... */ +0x1c, 0xa5, 0xaf, 0x05, 0x27 /* ....' */ +}; + +static const unsigned char pkt43[] = { +0x42, 0xca, 0x00, +0x06, 0x25, 0xfe, 0xcf, 0x58, /* B...%..X */ +0xaf, 0xfe, 0xcf, 0xfe, 0xdf, 0x02, 0x2e, 0x9d, /* ........ */ +0x85, 0xfe, 0xcf, 0x3c, 0xaf, 0x07, 0x3d, 0x58, /* ...<..=X */ +0x40, 0x4e, 0x5a, 0x3c, 0x26, 0x4c, 0x55, 0x37, /* @NZ<&LU7 */ +0x45, 0x4a, 0x5a, 0x02, 0x2e, 0x1b, 0x86, 0x47, /* EJZ....G */ +0x5a, 0x02, 0x2e, 0xad, 0x85, 0x00, 0x2e, 0xb9, /* Z....... */ +0x8d, 0xfe, 0xef, 0x16, 0x80, 0x02, 0xcf, 0xdf, /* ........ */ +0x96, 0x61, 0xef, 0xc0, 0xaf, 0x04, 0x27, 0xc1, /* .a....'. */ +0x46, 0x04, 0x5b, 0xc0, 0x3e, 0x40, 0xef, 0xc1, /* F.[.>@.. */ +0xaf, 0x01, 0x2e, 0x8d, 0x8b, 0xd0, 0x41, 0x07, /* ......A. */ +0x5b, 0x02, 0x2e, 0x5d, 0x85, 0xf2, 0x5b, 0xae, /* [..]..[. */ +0x87, 0xdd, 0x97, 0x1f, 0x2d, 0x06, 0x5b, 0x03, /* ....-.[. */ +0x50, 0x01, 0x0c, 0x02, 0xcf, 0xc0, 0x1c, 0x01, /* P....... */ +0x55, 0x02, 0x2e, 0x40, 0x85, 0xc0, 0x23, 0x20, /* U..@..# */ +0xef, 0xc1, 0xaf, 0x00, 0x2e, 0xd8, 0x8d, 0x05, /* ........ */ +0x27, 0x9b, 0x22, 0x37, 0x45, 0x05, 0x5a, 0x41, /* '."7E.ZA */ +0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x04, 0x5b, 0x00, /* .R..-.[. */ +0x28, 0x02, 0x50, 0x3b, 0x43, 0x00, 0x5b, 0x00, /* (.P;C.[. */ +0x28, 0xd3, 0xdf, 0xc6, 0x2e, 0x15, 0xbf, 0xd3, /* (....... */ +0x3c, 0x40, 0xef, 0x09, 0x80, 0xdd, 0x97, 0xff, /* <@...... */ +0xaf, 0x00, 0x2e, 0xa7, 0x8a, 0xc6, 0x2e, 0x15, /* ........ */ +0xdf, 0x10, 0x1d, 0xd3, 0xcf, 0x3f, 0x02, 0xd3, /* .....?.. */ +0xaf, 0x05, 0x27, 0xed, 0x83, 0x07, 0x45, 0x05, /* ..'...E. */ +0x27, 0x3d, 0x23, 0x07, 0x3d, 0x02, 0xcf, 0xdf, /* '=#.=... */ +0x96, 0x02, 0x2e, 0xad, 0x85, 0x02, 0x2e, 0x96, /* ........ */ +0x85, 0xfe, 0xef, 0x16, 0x80 /* ..... */ +}; + +static const unsigned char pkt45[] = { +0x42, 0xca, 0x00, +0x6a, 0x25, 0x05, 0xef, 0xc0, /* B..j%... */ +0xaf, 0x04, 0x27, 0xd0, 0x41, 0x03, 0x5b, 0x02, /* ..'.A.[. */ +0x2e, 0x5d, 0x85, 0xf9, 0x5b, 0xbb, 0x50, 0x27, /* .]..[.P' */ +0x82, 0x04, 0xef, 0xc1, 0xaf, 0x9b, 0x22, 0x02, /* ......". */ +0x2e, 0xd1, 0x85, 0xdd, 0x97, 0xdf, 0x22, 0x02, /* ......". */ +0x55, 0x58, 0x40, 0x02, 0x5a, 0x0b, 0x50, 0x58, /* UX@.Z.PX */ +0x40, 0x09, 0x5a, 0xdd, 0x97, 0x1f, 0x2d, 0xb3, /* @.Z...-. */ +0x5a, 0x02, 0x2e, 0x1c, 0x86, 0xb2, 0x5b, 0x9b, /* Z.....[. */ +0x22, 0x02, 0x2e, 0x4c, 0x85, 0xae, 0x50, 0x02, /* "..L..P. */ +0x2e, 0x1c, 0x86, 0xd5, 0x5b, 0x02, 0x2e, 0x40, /* ....[..@ */ +0x85, 0x58, 0x41, 0x02, 0x5b, 0x01, 0x0c, 0x02, /* .XA.[... */ +0x2e, 0x3a, 0x75, 0xcd, 0x50, 0x41, 0x2e, 0x52, /* .:u.PA.R */ +0xdf, 0xed, 0x1c, 0x04, 0x18, 0x41, 0x2e, 0x52, /* .....A.R */ +0xbf, 0x05, 0x27, 0x1a, 0x27, 0x56, 0xdf, 0x59, /* ..'.'V.Y */ +0x80, 0xdf, 0x22, 0x00, 0x54, 0x01, 0x16, 0x3f, /* ..".T..? */ +0x1e, 0x00, 0x5f, 0x3f, 0xef, 0x1f, 0x22, 0x1f, /* .._?..". */ +0x22, 0xaf, 0xdf, 0x03, 0x1d, 0x5f, 0x02, 0xaf, /* "...._.. */ +0xbf, 0x05, 0x27, 0x00, 0x2e, 0xa1, 0x8d, 0xae, /* ..'..... */ +0xdf, 0xe0, 0x19, 0xae, 0xbf, 0x57, 0x40, 0x00, /* .....W@. */ +0x5b, 0xa1, 0x32, 0x57, 0x43, 0x00, 0x5b, 0xae, /* [.2WC.[. */ +0x3f, 0xed, 0x80, 0x05, 0x27, 0x41, 0x2e, 0x52, /* ?...'A.R */ +0xdf, 0x03, 0x18, 0x41, 0x2e, 0x52, 0xbf, 0x05, /* ...A.R.. */ +0x27, 0xd3, 0xdf, 0xff, 0x96, 0x9b, 0x22, 0x02, /* '.....". */ +0x2e, 0xd1, 0x85, 0xd3, 0x3c, 0x07, 0x80, 0xdd, /* ....<... */ +0x97, 0xff, 0xaf, 0x00, 0x2e, 0xa7, 0x8a, 0xdd, /* ........ */ +0x9f, 0x10, 0x1d, 0xd3, 0xcf /* ..... */ +}; + +static const unsigned char pkt47[] = { +0x42, 0xb4, 0x00, +0xce, 0x25, 0x3f, 0x02, 0xd3, /* B...%?.. */ +0xaf, 0x05, 0x27, 0x37, 0x45, 0x10, 0x5a, 0x02, /* ..'7E.Z. */ +0x2e, 0x1b, 0x86, 0x0d, 0x5a, 0x02, 0x2e, 0xad, /* ....Z... */ +0x85, 0x00, 0x2e, 0xbf, 0x8d, 0x00, 0x2e, 0xd3, /* ........ */ +0x8d, 0x41, 0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x00, /* .A.R..-. */ +0x5b, 0x00, 0x28, 0x00, 0x2e, 0xd8, 0x8d, 0x05, /* [.(..... */ +0x27, 0xf9, 0xcf, 0xdf, 0x96, 0xf9, 0x3d, 0x01, /* '.....=. */ +0x2e, 0x06, 0x82, 0x2d, 0xff, 0xa7, 0xef, 0xe1, /* ...-.... */ +0xbf, 0xe0, 0xaf, 0x09, 0xef, 0x10, 0xaf, 0x01, /* ........ */ +0x2e, 0x94, 0x86, 0xed, 0x80, 0x01, 0x2e, 0x18, /* ........ */ +0x87, 0x01, 0x2e, 0x1a, 0x87, 0x00, 0x2e, 0x16, /* ........ */ +0x82, 0x5b, 0x82, 0x00, 0x2e, 0x2d, 0x82, 0x26, /* .[...-.& */ +0x37, 0x00, 0x5a, 0x0c, 0x50, 0xff, 0x96, 0xdf, /* 7.Z.P... */ +0x96, 0x79, 0xcf, 0x7a, 0xdf, 0xff, 0x96, 0xdf, /* .y.z.... */ +0x96, 0xc2, 0x97, 0xc3, 0x9f, 0x9d, 0x01, 0x5d, /* .......] */ +0x01, 0x07, 0x53, 0xdd, 0x97, 0xdd, 0x9f, 0x79, /* ..S....y */ +0xaf, 0x7a, 0xbf, 0x3b, 0x3b, 0xdd, 0x97, 0xf9, /* .z.;;... */ +0xaf, 0x05, 0x27, 0xff, 0x22, 0x01, 0x55, 0x32, /* ..'.".U2 */ +0x1e, 0xf3, 0x5f, 0x02, 0x0c, 0x02, 0x2e, 0x0e, /* .._..... */ +0x86, 0x3b, 0x33, 0x00, 0x28, 0x05, 0x27, 0x0d, /* .;3.(.'. */ +0x27, 0x3c, 0x26, 0x07, 0x54, 0x3c, 0xcf, 0x3d, /* '<&.T<.= */ +0xdf, 0x3f, 0x20, 0x3d, 0xbf, 0xdf, 0x03, 0x01, /* .? =.... */ +0x52, 0x3d, 0x23, 0x0c, 0x27, 0x0d, 0x27 /* R=#.'.' */ +}; + +static const unsigned char pkt49[] = { +0x42, 0x1a, 0x00, +0x27, 0x26, 0x09, 0x43, 0x04, /* B..'&.C. */ +0x5b, 0x00, 0xef, 0xf8, 0xaf, 0x32, 0xef, 0xfa, /* [....2.. */ +0xaf, 0x03, 0x50, 0x01, 0xef, 0xf8, 0xaf, 0x42, /* ..P....B */ +0xef, 0xfa, 0xaf, 0x05, 0x27 /* ....' */ +}; + +static const unsigned char pkt51[] = { +0x42, 0x26, 0x00, +0x33, 0x26, 0xd3, 0x45, 0xfd, /* B&.3&.E. */ +0x5a, 0x0f, 0x27, 0xd3, 0x45, 0xfa, 0x5a, 0x0f, /* Z.'.E.Z. */ +0x27, 0xd3, 0x45, 0xf7, 0x5a, 0x0f, 0x27, 0x41, /* '.E.Z.'A */ +0x2e, 0xa1, 0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, /* ....(A.. */ +0xbf, 0x02, 0x2e, 0x57, 0x80, 0x00, 0x2e, 0xcb, /* ...W.... */ +0x7a /* z */ +}; + +static const unsigned char pkt53[] = { +0x42, 0x4e, 0x00, +0x45, 0x26, 0x07, 0x3d, 0x02, /* BN.E&.=. */ +0x5b, 0xae, 0x87, 0xc2, 0x23, 0xd3, 0x3c, 0x02, /* [...#.<. */ +0x44, 0xdc, 0x2f, 0x43, 0x5a, 0x02, 0x45, 0xdc, /* D./CZ.E. */ +0x2f, 0xa4, 0x5b, 0x58, 0x23, 0x3c, 0x26, 0x02, /* /.[X#<&. */ +0x55, 0x02, 0x2e, 0x0e, 0x85, 0x00, 0x50, 0x09, /* U.....P. */ +0x8f, 0x07, 0x45, 0xeb, 0x5a, 0x41, 0x2e, 0x53, /* ..E.ZA.S */ +0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, 0x96, 0xdf, /* ...y.... */ +0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, 0x2e, 0x78, /* .A.U...x */ +0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, 0x22, 0x00, /* ...]..". */ +0x54, 0xff, 0xef, 0x2e, 0xaf, 0xdc, 0x2f, 0x89, /* T...../. */ +0x50 /* P */ +}; + +static const unsigned char pkt55[] = { +0x42, 0x86, 0x00, +0x6b, 0x26, 0xa5, 0xcf, 0xed, /* B..k&... */ +0x2e, 0x6a, 0xdf, 0xf3, 0x1c, 0x3f, 0x02, 0xa5, /* .j...?.. */ +0xaf, 0x4a, 0xcf, 0xdf, 0x96, 0x10, 0xcf, 0x5f, /* .J....._ */ +0xdf, 0xbf, 0x03, 0x02, 0x5f, 0x5f, 0xcf, 0x10, /* ....__.. */ +0xaf, 0x04, 0x50, 0x5e, 0xdf, 0xbf, 0x03, 0x01, /* ..P^.... */ +0x53, 0x5e, 0xcf, 0x10, 0xaf, 0x01, 0x2e, 0x40, /* S^.....@ */ +0x88, 0x01, 0x2e, 0xe1, 0x86, 0xdd, 0x97, 0x0a, /* ........ */ +0x40, 0x18, 0x5a, 0x62, 0xcf, 0xdf, 0x22, 0x22, /* @.Zb.."" */ +0x54, 0xed, 0x2e, 0x6a, 0xdf, 0x10, 0xef, 0x00, /* T..j.... */ +0x1f, 0x06, 0x54, 0x0c, 0xef, 0x04, 0x1f, 0x03, /* ..T..... */ +0x54, 0x0b, 0xef, 0x08, 0x1f, 0x00, 0x54, 0x05, /* T.....T. */ +0xef, 0x62, 0xdf, 0x76, 0x80, 0x12, 0x82, 0x12, /* .b.v.... */ +0x82, 0x80, 0x10, 0x01, 0x13, 0x4a, 0xcf, 0x3f, /* .....J.? */ +0x00, 0x00, 0x53, 0xff, 0xef, 0x4a, 0xdf, 0xed, /* ..S..J.. */ +0x2e, 0x6e, 0xbf, 0x4a, 0xaf, 0x6d, 0x2e, 0x6f, /* .n.J.m.o */ +0xbf, 0xdf, 0x96, 0xbf, 0x01, 0x6d, 0x2e, 0x6d, /* .....m.m */ +0xbf, 0xdd, 0x97, 0x01, 0x2e, 0xf9, 0x81, 0x05, /* ........ */ +0x27 /* ' */ +}; + +static const unsigned char pkt57[] = { +0x42, 0x16, 0x00, +0xad, 0x26, 0xd3, 0x45, 0x02, /* B...&.E. */ +0x5a, 0xd3, 0x45, 0x00, 0x5a, 0x05, 0x27, 0xd0, /* Z.E.Z.'. */ +0x41, 0xf8, 0x5b, 0xed, 0x83, 0xf6, 0x50, 0x05, /* A.[...P. */ +0x27 /* ' */ +}; + +static const unsigned char pkt59[] = { +0x42, 0xca, 0x00, +0xb7, 0x26, 0xfd, 0x0c, 0x00, /* B...&... */ +0x2e, 0x3f, 0x8a, 0x39, 0x84, 0x05, 0xcf, 0xdf, /* .?.9.... */ +0x22, 0x00, 0x2e, 0xb4, 0x55, 0x04, 0xcf, 0x14, /* "...U... */ +0x1e, 0x00, 0x2e, 0xb0, 0x55, 0x00, 0x2e, 0xf5, /* ....U... */ +0x89, 0xbb, 0xef, 0x1f, 0x90, 0x91, 0xff, 0x7f, /* ........ */ +0x90, 0x14, 0xef, 0x00, 0x2e, 0x31, 0x8a, 0x14, /* .....1.. */ +0xef, 0x00, 0x2e, 0x39, 0x8a, 0x33, 0xef, 0x1f, /* ...9.3.. */ +0x90, 0x71, 0xff, 0x7f, 0x90, 0x18, 0xef, 0x00, /* .q...... */ +0x2e, 0x31, 0x8a, 0x00, 0x2e, 0xf5, 0x89, 0x40, /* .1.....@ */ +0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, 0x55, 0x01, /* ..._ .U. */ +0x2e, 0x67, 0x8d, 0x01, 0x2e, 0xfe, 0x8c, 0x00, /* .g...... */ +0x2e, 0xf5, 0x89, 0x02, 0x2e, 0x7a, 0x87, 0x0a, /* .....z.. */ +0xef, 0x00, 0x2e, 0x01, 0x8a, 0x02, 0x2e, 0x7a, /* .......z */ +0x87, 0x00, 0xff, 0x80, 0xef, 0x19, 0x27, 0x0a, /* ......'. */ +0xef, 0xdc, 0x9f, 0x7f, 0x9f, 0x5f, 0x20, 0xfb, /* ....._ . */ +0x55, 0x39, 0x84, 0x02, 0x2e, 0x7a, 0x87, 0x0a, /* U9...z.. */ +0xef, 0x00, 0x2e, 0x01, 0x8a, 0x02, 0x2e, 0x7a, /* .......z */ +0x87, 0x0a, 0xef, 0xdc, 0x9f, 0x7f, 0x9f, 0x5f, /* ......._ */ +0x20, 0xfb, 0x55, 0x02, 0x2e, 0x76, 0x87, 0x02, /* .U..v.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x9d, 0xef, 0x1f, 0x90, 0xda, /* .D...... */ +0xff, 0x7f, 0x90, 0x0f, 0xef, 0x00, 0x2e, 0x31, /* .......1 */ +0x8a, 0x80, 0xef, 0x1f, 0x9f /* ..... */ +}; + +static const unsigned char pkt61[] = { +0x42, 0xca, 0x00, +0x1b, 0x27, 0x9f, 0x22, 0x1f, /* B...'.". */ +0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, /* ........ */ +0x9f, 0x1f, 0x9f, 0x03, 0xef, 0x1f, 0x9f, 0xb8, /* ........ */ +0xef, 0x1f, 0x9f, 0x00, 0x2e, 0xf5, 0x89, 0x40, /* .......@ */ +0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, 0x55, 0x01, /* ..._ .U. */ +0x2e, 0xfe, 0x8c, 0x00, 0x2e, 0xff, 0x89, 0x02, /* ........ */ +0x2e, 0xb3, 0x87, 0x02, 0x2e, 0x44, 0x88, 0x02, /* .....D.. */ +0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, 0x88, 0x02, /* .?...D.. */ +0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, 0x88, 0x02, /* .?...D.. */ +0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, 0x88, 0x02, /* .?...D.. */ +0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, 0x88, 0x02, /* .?...D.. */ +0x2e, 0xb3, 0x87, 0x14, 0xef, 0xfc, 0x9f, 0x5f, /* ......._ */ +0x20, 0xfc, 0x55, 0x01, 0xff, 0xab, 0xef, 0x19, /* .U..... */ +0x27, 0x02, 0x2e, 0xb3, 0x87, 0x11, 0xff, 0xbf, /* '....... */ +0x90, 0x51, 0xff, 0xc2, 0x97, 0xdf, 0x01, 0x7f, /* .Q...... */ +0x98, 0xfc, 0x9f, 0xbf, 0x98, 0x24, 0x28, 0xc2, /* .....$(. */ +0x9f, 0x7f, 0x20, 0xbf, 0x90, 0xf4, 0x55, 0x24, /* .. ...U$ */ +0x2a, 0x02, 0x2e, 0x7e, 0x87, 0x72, 0xef, 0xff, /* *..~.r.. */ +0xaf, 0x14, 0xef, 0xff, 0xaf, 0x00, 0xef, 0xff, /* ........ */ +0xaf, 0x00, 0xff, 0x80, 0xef, 0x19, 0x27, 0x14, /* ......'. */ +0xff, 0xfd, 0x97, 0xff, 0xaf, 0x7f, 0x20, 0xfb, /* ...... . */ +0x55, 0x00, 0x2e, 0xa9, 0x8a, 0x03, 0x0c, 0xd0, /* U....... */ +0xef, 0x07, 0xff, 0xa9, 0x80, 0x05, 0x27, 0x58, /* ......'X */ +0x85, 0x05, 0x27, 0x40, 0xef, 0x2d, 0xff, 0x1a, /* ..'@.-.. */ +0x27, 0x05, 0x27, 0x02, 0xef, 0x06, 0xff, 0x1a, /* '.'..... */ +0x27, 0x05, 0x27, 0x01, 0xff /* '.'.. */ +}; + +static const unsigned char pkt63[] = { +0x42, 0x72, 0x00, +0x7f, 0x27, 0xab, 0xef, 0x19, /* Br..'... */ +0x27, 0x08, 0xef, 0x1f, 0x98, 0xe4, 0x29, 0x00, /* '.....). */ +0xff, 0xff, 0x96, 0x20, 0xff, 0xff, 0x96, 0x00, /* ... .... */ +0xff, 0xff, 0x96, 0x40, 0xff, 0xff, 0x96, 0x00, /* ...@.... */ +0xff, 0xff, 0x96, 0x60, 0xff, 0xff, 0x96, 0x00, /* ...`.... */ +0xff, 0xff, 0x96, 0x00, 0xff, 0xff, 0x96, 0x01, /* ........ */ +0xff, 0xff, 0x96, 0x20, 0xff, 0xff, 0x96, 0x00, /* ... .... */ +0xff, 0xff, 0x96, 0x02, 0xff, 0xff, 0x96, 0x02, /* ........ */ +0xff, 0xff, 0x96, 0x82, 0xff, 0xff, 0x96, 0x02, /* ........ */ +0xff, 0xff, 0x96, 0x02, 0x2e, 0xaa, 0x87, 0x46, /* .......F */ +0x2e, 0x01, 0xdf, 0x9f, 0x28, 0x46, 0x2e, 0x01, /* ....(F.. */ +0xbf, 0x05, 0x27, 0x0f, 0xef, 0x5f, 0x98, 0xdd, /* ..'.._.. */ +0x9f, 0xbf, 0x98, 0x24, 0x28, 0x5f, 0x20, 0xf9, /* ...$(_ . */ +0x55, 0x24, 0x2a, 0x05, 0x27, 0x7f, 0xef, 0x2d, /* U$*.'..- */ +0xff, 0x1b, 0x27, 0x05, 0x27 /* ..'.' */ +}; + +static const unsigned char pkt65[] = { +0x42, 0xca, 0x00, +0xb7, 0x27, 0x00, 0x2e, 0x3f, /* B...'..? */ +0x8a, 0x23, 0x81, 0x02, 0x2e, 0x4d, 0x88, 0x05, /* .#...M.. */ +0xcf, 0xdf, 0x22, 0x35, 0x55, 0x04, 0xcf, 0x2a, /* .."5U..* */ +0x1e, 0x32, 0x55, 0xfe, 0xdf, 0xfe, 0xcf, 0x00, /* .2U..... */ +0x1f, 0x1d, 0x55, 0x00, 0x1e, 0x0e, 0x54, 0xc6, /* ..U...T. */ +0x2e, 0x00, 0xdf, 0x3f, 0x20, 0xbf, 0x03, 0x16, /* ...? ... */ +0x55, 0xc6, 0x2e, 0x01, 0xdf, 0x3f, 0x2c, 0x12, /* U....?,. */ +0x5b, 0x46, 0x2e, 0x00, 0xbf, 0x00, 0x2e, 0x25, /* [F.....% */ +0x8a, 0x02, 0x2e, 0xe1, 0x77, 0x00, 0xef, 0x46, /* ....w..F */ +0x2e, 0x00, 0xbf, 0x46, 0x2e, 0x01, 0xdf, 0x1f, /* ...F.... */ +0x28, 0x46, 0x2e, 0x01, 0xbf, 0x00, 0x2e, 0x06, /* (F...... */ +0x8a, 0x02, 0x2e, 0xf7, 0x87, 0x05, 0x27, 0x46, /* ......'F */ +0x2e, 0x01, 0xdf, 0x1f, 0x2a, 0x46, 0x2e, 0x01, /* ....*F.. */ +0xbf, 0x41, 0x2e, 0xb6, 0xdf, 0x01, 0xff, 0xab, /* .A...... */ +0xef, 0x19, 0x27, 0x42, 0xff, 0x7f, 0x98, 0x9f, /* ..'B.... */ +0x98, 0x24, 0x28, 0x56, 0x85, 0x24, 0x2a, 0x05, /* .$(V.$*. */ +0x27, 0x58, 0x85, 0x05, 0x27, 0xfd, 0x0c, 0x00, /* 'X..'... */ +0x2e, 0xf5, 0x89, 0x14, 0xef, 0x00, 0x2e, 0x39, /* .......9 */ +0x8a, 0x02, 0x2e, 0x3b, 0x88, 0x02, 0x2e, 0x44, /* ...;...D */ +0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, /* ...?...D */ +0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, /* ...?...D */ +0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, /* ...?...D */ +0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, 0x2e, 0x44, /* ...?...D */ +0x88, 0x46, 0x2e, 0x00, 0xdf, 0x1f, 0x9f, 0xe2, /* .F...... */ +0xef, 0x1f, 0x90, 0xe0, 0xff, 0x7f, 0x90, 0x0e, /* ........ */ +0xef, 0x00, 0x2e, 0x31, 0x8a /* ...1. */ +}; + +static const unsigned char pkt67[] = { +0x42, 0xca, 0x00, +0x1b, 0x28, 0x80, 0xef, 0x1f, /* B...(... */ +0x9f, 0x9f, 0x22, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, /* .."..... */ +0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x1f, 0x9f, 0x01, /* ........ */ +0xef, 0x1f, 0x9f, 0xb8, 0xef, 0x1f, 0x9f, 0x00, /* ........ */ +0x2e, 0xf5, 0x89, 0x40, 0xef, 0xfc, 0x9f, 0x5f, /* ...@..._ */ +0x20, 0xfc, 0x55, 0x03, 0x0c, 0x01, 0x2e, 0x67, /* .U....g */ +0x8d, 0x01, 0x2e, 0xfe, 0x8c, 0x00, 0x2e, 0xff, /* ........ */ +0x89, 0x00, 0x2e, 0xfb, 0x89, 0x14, 0xef, 0x00, /* ........ */ +0x2e, 0x01, 0x8a, 0x05, 0x27, 0x40, 0xef, 0x2d, /* ....'@.- */ +0xff, 0x1a, 0x27, 0x05, 0x27, 0x16, 0x27, 0x04, /* ..'.'.'. */ +0x10, 0x00, 0x13, 0x1a, 0x27, 0x05, 0x27, 0xd9, /* ....'.'. */ +0x9f, 0x3f, 0x9f, 0xd8, 0x9f, 0x3f, 0x9f, 0xd7, /* .?...?.. */ +0x9f, 0x3f, 0x9f, 0xd6, 0x9f, 0x3f, 0x9f, 0x05, /* .?...?.. */ +0x27, 0x7f, 0xef, 0x2d, 0xff, 0x46, 0x2e, 0x1d, /* '..-.F.. */ +0xbf, 0xc6, 0x2e, 0x1c, 0xbf, 0x93, 0xef, 0x2d, /* .......- */ +0xff, 0x46, 0x2e, 0x1f, 0xbf, 0xc6, 0x2e, 0x1e, /* .F...... */ +0xbf, 0x05, 0x27, 0x00, 0x2e, 0x3f, 0x8a, 0x23, /* ..'..?.# */ +0x81, 0x02, 0x2e, 0x4d, 0x88, 0x02, 0x2e, 0x60, /* ...M...` */ +0x89, 0x08, 0xef, 0xfe, 0xdf, 0x3f, 0x9f, 0x5f, /* .....?._ */ +0x20, 0xfb, 0x55, 0x28, 0xef, 0xfe, 0xdf, 0x5f, /* .U(..._ */ +0x20, 0xfc, 0x55, 0x00, 0x2e, 0xf5, 0x89, 0xfe, /* .U..... */ +0xdf, 0x00, 0x2e, 0xf5, 0x89, 0x14, 0xff, 0xfe, /* ........ */ +0xcf, 0x1f, 0x9f, 0x7f, 0x20, 0xfb, 0x55, 0x23, /* .... .U# */ +0xff, 0xfe, 0xcf, 0x7f, 0x20, 0xfc, 0x55, 0x02, /* .... .U. */ +0x2e, 0x64, 0x89, 0x00, 0x2e, 0xf5, 0x89, 0x14, /* .d...... */ +0xff, 0xfc, 0x97, 0x1f, 0x97 /* ..... */ +}; + +static const unsigned char pkt69[] = { +0x42, 0xca, 0x00, +0x7f, 0x28, 0x7f, 0x20, 0xfb, /* B...(. . */ +0x55, 0x2c, 0xef, 0xbf, 0x22, 0x3f, 0x9f, 0x5f, /* U,.."?._ */ +0x20, 0xfc, 0x55, 0x00, 0x2e, 0xf5, 0x89, 0x40, /* .U....@ */ +0xef, 0xf6, 0x9f, 0x36, 0x1b, 0x3f, 0x9f, 0x5f, /* ...6.?._ */ +0x20, 0xfa, 0x55, 0x01, 0x2e, 0x67, 0x8d, 0x01, /* .U..g.. */ +0x2e, 0xfe, 0x8c, 0x00, 0x2e, 0xf5, 0x89, 0x02, /* ........ */ +0x2e, 0x5c, 0x89, 0xdc, 0x9f, 0x3f, 0x9f, 0xdc, /* .\...?.. */ +0x9f, 0x3f, 0x9f, 0xdc, 0x9f, 0x3f, 0x9f, 0xdc, /* .?...?.. */ +0x9f, 0x3f, 0x9f, 0xdc, 0x9f, 0x3f, 0x9f, 0xdc, /* .?...?.. */ +0x9f, 0x3f, 0x9f, 0xdc, 0x9f, 0x3f, 0x9f, 0xdc, /* .?...?.. */ +0x9f, 0x3f, 0x9f, 0x80, 0xff, 0x3f, 0x9f, 0x2f, /* .?...?./ */ +0xef, 0xbf, 0x22, 0x3f, 0x9f, 0x5f, 0x20, 0xfc, /* .."?._ . */ +0x55, 0x3f, 0x9f, 0x3f, 0x9f, 0x3f, 0x9f, 0x3f, /* U?.?.?.? */ +0x9f, 0x3f, 0x9f, 0x3f, 0x9f, 0x02, 0xff, 0x3f, /* .?.?...? */ +0x9f, 0x40, 0xff, 0x3f, 0x9f, 0x00, 0x2e, 0xf5, /* .@.?.... */ +0x89, 0x40, 0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, /* .@..._ . */ +0x55, 0x01, 0x2e, 0xfe, 0x8c, 0x00, 0x2e, 0xff, /* U....... */ +0x89, 0x00, 0x2e, 0xf5, 0x89, 0x14, 0xef, 0x00, /* ........ */ +0x2e, 0x01, 0x8a, 0x46, 0x2e, 0x18, 0xdf, 0xc6, /* ...F.... */ +0x2e, 0x17, 0xdf, 0x1a, 0x27, 0x02, 0x2e, 0x68, /* ....'..h */ +0x89, 0x14, 0xef, 0xfc, 0x9f, 0x5c, 0x1b, 0x3f, /* .....\.? */ +0x97, 0x5f, 0x20, 0xfa, 0x55, 0x2c, 0xef, 0x5c, /* ._ .U,.\ */ +0xff, 0x3f, 0x97, 0x5f, 0x20, 0xfc, 0x55, 0x00, /* .?._ .U. */ +0x2e, 0xff, 0x89, 0x02, 0x2e, 0x68, 0x89, 0x02, /* .....h.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e /* .D... */ +}; + +static const unsigned char pkt71[] = { +0x42, 0xca, 0x00, +0xe3, 0x28, 0x3f, 0x88, 0x02, /* B...(?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x00, 0x2e, 0xf5, 0x89, 0x40, /* .D.....@ */ +0xef, 0xfc, 0x9f, 0x5f, 0x20, 0xfc, 0x55, 0x01, /* ..._ .U. */ +0x2e, 0x67, 0x8d, 0x01, 0x2e, 0xfe, 0x8c, 0x46, /* .g.....F */ +0x2e, 0x18, 0xdf, 0xc6, 0x2e, 0x17, 0xdf, 0x1a, /* ........ */ +0x27, 0x02, 0x2e, 0x68, 0x89, 0x14, 0xef, 0xfc, /* '..h.... */ +0x9f, 0x3f, 0x97, 0x5f, 0x20, 0xfb, 0x55, 0x80, /* .?._ .U. */ +0xff, 0x3f, 0x97, 0x23, 0xef, 0xbf, 0x22, 0x3f, /* .?.#.."? */ +0x97, 0x5f, 0x20, 0xfc, 0x55, 0x3f, 0x97, 0x3f, /* ._ .U?.? */ +0x97, 0x3f, 0x97, 0x3f, 0x97, 0x3f, 0x97, 0x3f, /* .?.?.?.? */ +0x97, 0x02, 0xff, 0x3f, 0x97, 0xa0, 0xff, 0x3f, /* ...?...? */ +0x97, 0x00, 0x2e, 0xf5, 0x89, 0x40, 0xef, 0xfc, /* .....@.. */ +0x9f, 0x5f, 0x20, 0xfc, 0x55, 0x01, 0x2e, 0xfe, /* ._ .U... */ +0x8c, 0x00, 0x2e, 0xff, 0x89, 0x00, 0x2e, 0xf5, /* ........ */ +0x89, 0x14, 0xef, 0x00, 0x2e, 0x01, 0x8a, 0x00, /* ........ */ +0x2e, 0xff, 0x89, 0x02, 0x2e, 0x68, 0x89, 0x02, /* .....h.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x02, 0x2e, 0x3f, 0x88, 0x02, /* .D...?.. */ +0x2e, 0x44, 0x88, 0x17, 0x27, 0x5f, 0x20, 0x1b, /* .D..'_ . */ +0x27, 0xf6, 0x97, 0x0f, 0x1c, 0x54, 0x10, 0x2d, /* '....T.- */ +0xff, 0x1b, 0x27, 0x73, 0xef, 0xff, 0xaf, 0x84, /* ..'s.... */ +0xef, 0xff, 0xaf, 0x00, 0xef /* ..... */ +}; + +static const unsigned char pkt73[] = { +0x42, 0x4c, 0x00, +0x47, 0x29, 0xff, 0xaf, 0xfc, /* BL.G)... */ +0x97, 0xff, 0xaf, 0xfc, 0x97, 0xff, 0xaf, 0xfc, /* ........ */ +0x97, 0xff, 0xaf, 0xfc, 0x97, 0xff, 0xaf, 0x80, /* ........ */ +0xef, 0xfe, 0xdf, 0xff, 0xbf, 0x5f, 0x20, 0xfb, /* ....._ . */ +0x55, 0x10, 0xef, 0xfe, 0xdf, 0x5f, 0x20, 0xfc, /* U...._ . */ +0x55, 0x00, 0x2e, 0xa9, 0x8a, 0x05, 0x27, 0x69, /* U.....'i */ +0xef, 0x2d, 0xff, 0x1a, 0x27, 0x05, 0x27, 0x69, /* .-..'.'i */ +0xef, 0x2d, 0xff, 0x1b, 0x27, 0x05, 0x27, 0x54, /* .-..'.'T */ +0xef, 0x2d, 0xff, 0x1a, 0x27, 0x05, 0x27, 0x54, /* .-..'.'T */ +0xef, 0x2d, 0xff, 0x1b, 0x27, 0x05, 0x27 /* .-..'.' */ +}; + +static const unsigned char pkt75[] = { +0x67, 0x05, 0x00, 0x00, 0x02, 0x2e, 0x00, 0x70, /* g......p */ +0x67, 0x05, 0x00, 0x02, 0x02, 0x2e, 0x87, 0x70, /* g......p */ +0x67, 0x05, 0x00, 0x01, 0x02, 0x2e, 0x6f, 0x72, /* g.....or */ +0x67, 0x05, 0x00, 0x03, 0x02, 0x2e, 0x7a, 0x73, /* g.....zs */ +0x67, 0x05, 0x00, 0x08, 0x02, 0x2e, 0x9a, 0x74, /* g......t */ +0x67, 0x05, 0x00, 0x07, 0x02, 0x2e, 0x06, 0x75, /* g......u */ +0x5a, 0x05, 0x00, 0x00, 0x55, 0x01, 0x27, 0x26, /* Z...U.'& */ +0x5a, 0x05, 0x00, 0x01, 0xc4, 0x0a, 0x33, 0x26, /* Z.....3& */ +0x5a, 0x05, 0x00, 0x02, 0xd9, 0x02, 0x45, 0x26, /* Z.....E& */ +0x5a, 0x05, 0x00, 0x03, 0x94, 0x16, 0x6b, 0x26, /* Z.....k& */ +0x5a, 0x05, 0x00, 0x04, 0xcc, 0x0a, 0xad, 0x26, /* Z......& */ +0x5a, 0x05, 0x00, 0x05, 0x3e, 0x0a, 0xb7, 0x26, /* Z...>..& */ +0x5a, 0x05, 0x00, 0x06, 0xf4, 0x09, 0xb7, 0x27, /* Z......' */ +0x0d, +0x42, 0x04, 0x00, +0x47, 0x29, 0xff, 0xaf /* .B..G).. */ +}; + +/* INIT1 is over, 0x07 cmd returns + * { 0x07, 0x05, 0x00, 0x91, 0x26, 0x21, 0x00, 0x3a } + */ +struct aesX660_cmd aes2660_init_1[] = { + { .cmd = pkt13, .len = sizeof(pkt13) }, + { .cmd = pkt15, .len = sizeof(pkt15) }, + { .cmd = pkt17, .len = sizeof(pkt17) }, + { .cmd = pkt19, .len = sizeof(pkt19) }, + { .cmd = pkt21, .len = sizeof(pkt21) }, + { .cmd = pkt23, .len = sizeof(pkt23) }, + { .cmd = pkt25, .len = sizeof(pkt25) }, + { .cmd = pkt27, .len = sizeof(pkt27) }, + { .cmd = pkt29, .len = sizeof(pkt29) }, + { .cmd = pkt31, .len = sizeof(pkt31) }, + { .cmd = pkt33, .len = sizeof(pkt33) }, + { .cmd = pkt35, .len = sizeof(pkt35) }, + { .cmd = pkt37, .len = sizeof(pkt37) }, + { .cmd = pkt39, .len = sizeof(pkt39) }, + { .cmd = pkt41, .len = sizeof(pkt41) }, + { .cmd = pkt43, .len = sizeof(pkt43) }, + { .cmd = pkt45, .len = sizeof(pkt45) }, + { .cmd = pkt47, .len = sizeof(pkt47) }, + { .cmd = pkt49, .len = sizeof(pkt49) }, + { .cmd = pkt51, .len = sizeof(pkt51) }, + { .cmd = pkt53, .len = sizeof(pkt53) }, + { .cmd = pkt55, .len = sizeof(pkt55) }, + { .cmd = pkt57, .len = sizeof(pkt57) }, + { .cmd = pkt59, .len = sizeof(pkt59) }, + { .cmd = pkt61, .len = sizeof(pkt61) }, + { .cmd = pkt63, .len = sizeof(pkt63) }, + { .cmd = pkt65, .len = sizeof(pkt65) }, + { .cmd = pkt67, .len = sizeof(pkt67) }, + { .cmd = pkt69, .len = sizeof(pkt69) }, + { .cmd = pkt71, .len = sizeof(pkt71) }, + { .cmd = pkt73, .len = sizeof(pkt73) }, + { .cmd = pkt75, .len = sizeof(pkt75) }, +}; + +/* Second init sequence + * INIT2 */ +static const unsigned char pkt187[] = { +0x0d, +0x23, +0x42, 0xca, 0x00, +0x00, 0x20, 0x7f, /* .#B... . */ +0x97, 0x37, 0xcf, 0xdf, 0x96, 0x26, 0xcf, 0xdf, /* .7...&.. */ +0x96, 0xff, 0x96, 0x9f, 0x22, 0x6d, 0x2e, 0x6a, /* ...."m.j */ +0xbf, 0x62, 0x23, 0x23, 0x83, 0xdd, 0x97, 0x26, /* .b##...& */ +0xaf, 0xdd, 0x97, 0x37, 0xaf, 0xa9, 0xcf, 0x70, /* ...7...p */ +0x18, 0xa9, 0xaf, 0x02, 0xef, 0x5d, 0xaf, 0xc5, /* .....].. */ +0xef, 0x2f, 0xff, 0xff, 0x96, 0xdf, 0x96, 0x6a, /* ./.....j */ +0xef, 0x20, 0xff, 0xff, 0x96, 0xdf, 0x96, 0x1a, /* . ...... */ +0x27, 0x0b, 0xef, 0x06, 0xaf, 0xf1, 0x81, 0x3a, /* '......: */ +0xff, 0x3f, 0x1d, 0x40, 0x19, 0xc1, 0x2e, 0xa3, /* .?.@.... */ +0xbf, 0xc2, 0x2e, 0x00, 0xdf, 0xff, 0x2d, 0x02, /* ......-. */ +0x5a, 0xbf, 0x22, 0xc1, 0x2e, 0xa3, 0xbf, 0x3c, /* Z."....< */ +0x23, 0x57, 0x23, 0x02, 0x2e, 0x31, 0x80, 0x05, /* #W#..1.. */ +0x27, 0x12, 0xef, 0x99, 0xaf, 0x10, 0xef, 0x9b, /* '....... */ +0xaf, 0x10, 0xef, 0x55, 0xaf, 0x3d, 0x23, 0x31, /* ...U.=#1 */ +0xef, 0x20, 0xff, 0x1a, 0x27, 0x05, 0xef, 0x27, /* . ..'..' */ +0xff, 0x06, 0x27, 0x05, 0x27, 0x3f, 0x80, 0x2b, /* ..'.'?.+ */ +0x0d, 0x05, 0x27, 0xe5, 0x31, 0x05, 0x81, 0xe5, /* ..'.1... */ +0x39, 0x05, 0x27, 0xc8, 0x46, 0x0e, 0x5b, 0xd3, /* 9.'.F.[. */ +0x45, 0xfd, 0x5a, 0x0f, 0x27, 0xd3, 0x45, 0xfa, /* E.Z.'.E. */ +0x5a, 0x0f, 0x27, 0xd3, 0x45, 0xf7, 0x5a, 0x41, /* Z.'.E.ZA */ +0x2e, 0xa1, 0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, /* ....(A.. */ +0xbf, 0x02, 0x2e, 0x58, 0x80, 0x05, 0x27, 0x9f, /* ...X..'. */ +0x22, 0xbf, 0x22, 0x1f, 0x20, 0xfd, 0x53, 0x3f, /* ".". .S? */ +0x20, 0x14, 0x1f, 0xfa, 0x55, 0x05, 0x27, 0x10, /* ...U.'. */ +0xef, 0xd0, 0x81, 0x65, 0xaf, 0x10, 0xef /* ...e... */ +}; + +static const unsigned char pkt189[] = { +0x42, 0x4a, 0x00, +0x64, 0x20, 0xd0, 0x81, 0x9c, /* BJ.d ... */ +0xaf, 0x10, 0xef, 0xd0, 0x81, 0x9a, 0xaf, 0x05, /* ........ */ +0x27, 0x11, 0x00, 0x51, 0x87, 0x91, 0x81, 0xd1, /* '..Q.... */ +0x6c, 0xd2, 0x75, 0xe2, 0x80, 0xf2, 0x80, 0xf0, /* l.u..... */ +0x57, 0xf4, 0x7b, 0xf8, 0x7e, 0xfc, 0x8b, 0x10, /* W.{.~... */ +0xcf, 0x7d, 0xff, 0x3f, 0x00, 0x20, 0xff, 0x00, /* .}.?. .. */ +0x13, 0x1a, 0x27, 0x07, 0x27, 0x05, 0x27, 0x01, /* ..'.'.'. */ +0x00, 0x11, 0x00, 0x21, 0x00, 0x31, 0x00, 0x31, /* ...!.1.1 */ +0x01, 0x32, 0x01, 0x33, 0x01, 0x33, 0x03, 0x43, /* .2.3.3.C */ +0x03, 0x53, 0x03, 0x63, 0x03 /* .S.c. */ +}; + +static const unsigned char pkt191[] = { +0x42, 0xca, 0x00, +0x88, 0x20, 0x51, 0x85, 0x44, /* B... Q.D */ +0x1e, 0x03, 0x55, 0xc8, 0x46, 0x01, 0x5b, 0xe4, /* ..U.F.[. */ +0x2f, 0xc8, 0x50, 0x49, 0x1e, 0x16, 0x55, 0x37, /* /.PI..U7 */ +0x39, 0x0f, 0x27, 0x02, 0xef, 0x02, 0x2e, 0x2f, /* 9.'..../ */ +0x81, 0xfe, 0xcf, 0x08, 0xaf, 0xfe, 0xcf, 0x09, /* ........ */ +0xaf, 0xfe, 0xcf, 0x0b, 0xaf, 0x55, 0x81, 0x02, /* .....U.. */ +0xcf, 0x0f, 0x1c, 0x40, 0x18, 0x08, 0x42, 0x00, /* ...@..B. */ +0x5b, 0x20, 0x18, 0x3d, 0x23, 0x02, 0xaf, 0x10, /* [ .=#... */ +0xef, 0x55, 0xaf, 0x05, 0x27, 0x4a, 0x1e, 0x01, /* .U..'J.. */ +0x55, 0xe4, 0x2f, 0xab, 0x50, 0x4e, 0x1e, 0x01, /* U./.PN.. */ +0x55, 0x00, 0x2e, 0x0d, 0x7b, 0x55, 0x1e, 0x16, /* U...{U.. */ +0x55, 0x54, 0x85, 0xe4, 0x2f, 0xa2, 0x5b, 0x07, /* UT../.[. */ +0xef, 0x20, 0x80, 0xe4, 0x2f, 0x9e, 0x5a, 0xfe, /* . ../.Z. */ +0xcf, 0x0a, 0xaf, 0xfe, 0xcf, 0xfe, 0xcf, 0x41, /* .......A */ +0x2e, 0x44, 0xbf, 0xfe, 0xcf, 0x41, 0x2e, 0x45, /* .D...A.E */ +0xbf, 0xfe, 0xcf, 0x52, 0xaf, 0xfe, 0xcf, 0x53, /* ...R...S */ +0xaf, 0xfe, 0xcf, 0x5a, 0xaf, 0x05, 0x27, 0x58, /* ...Z..'X */ +0x1e, 0x0d, 0x55, 0x02, 0x44, 0x01, 0x5a, 0x00, /* ..U.D.Z. */ +0x2e, 0x54, 0x79, 0xfe, 0xcf, 0x75, 0xaf, 0xfe, /* .Ty..u.. */ +0xdf, 0x76, 0xbf, 0x41, 0x2e, 0xa4, 0xdf, 0xdf, /* .v.A.... */ +0x29, 0x41, 0x2e, 0xa4, 0xbf, 0x05, 0x27, 0x59, /* )A....'Y */ +0x1e, 0x03, 0x55, 0xfe, 0xcf, 0x10, 0xaf, 0x01, /* ..U..... */ +0x2e, 0x94, 0x76, 0x63, 0x1e, 0x1a, 0x55, 0x54, /* ..vc..UT */ +0x85, 0xe4, 0x2f, 0x73, 0x5b, 0x0c, 0xef, 0x20, /* ../s[.. */ +0x80, 0xe4, 0x2f, 0x6f, 0x5a, 0xf0, 0xef, 0x00, /* ../oZ... */ +0xff, 0x19, 0x27, 0x08, 0xef /* ..'.. */ +}; + +static const unsigned char pkt193[] = { +0x42, 0xa2, 0x00, +0xec, 0x20, 0x06, 0xaf, 0xfe, /* B... ... */ +0xcf, 0x5f, 0x9f, 0x06, 0x25, 0xfb, 0x55, 0xfe, /* ._..%.U. */ +0xcf, 0xfe, 0xcf, 0x41, 0x2e, 0x40, 0xbf, 0xfe, /* ...A.@.. */ +0xcf, 0x41, 0x2e, 0x41, 0xbf, 0xfe, 0xcf, 0x41, /* .A.A...A */ +0x2e, 0x42, 0xbf, 0x05, 0x27, 0x66, 0x1e, 0x0b, /* .B..'f.. */ +0x55, 0xc5, 0xef, 0x2f, 0xff, 0x1a, 0x27, 0x0b, /* U../..'. */ +0xef, 0x06, 0xaf, 0xfe, 0xcf, 0xfe, 0xdf, 0x06, /* ........ */ +0x27, 0x01, 0x0e, 0x06, 0x25, 0xf9, 0x55, 0x05, /* '...%.U. */ +0x27, 0x7d, 0x1e, 0x0c, 0x55, 0x02, 0x2e, 0x29, /* '}..U..) */ +0x81, 0xe4, 0x2f, 0x47, 0x5a, 0xfe, 0xcf, 0xfe, /* ../GZ... */ +0xdf, 0x1b, 0x27, 0xfe, 0xcf, 0x36, 0x03, 0xfe, /* ..'..6.. */ +0xdf, 0x3f, 0x02, 0x9f, 0x9d, 0x05, 0x27, 0x7e, /* .?....'~ */ +0x1e, 0x0c, 0x55, 0x02, 0x2e, 0x29, 0x81, 0xe4, /* ..U..).. */ +0x2f, 0x38, 0x5a, 0xfe, 0xcf, 0xfe, 0xdf, 0x1b, /* /8Z..... */ +0x27, 0x07, 0x80, 0xf6, 0x97, 0xff, 0xaf, 0x00, /* '....... */ +0x2e, 0xa7, 0x8a, 0x05, 0x27, 0x61, 0x74, 0xff, /* ....'at. */ +0x96, 0xc6, 0x2e, 0x01, 0xdf, 0x3f, 0x2c, 0xdd, /* .....?,. */ +0x9f, 0x05, 0x27, 0xf9, 0x35, 0xc1, 0x2e, 0x4e, /* ..'.5..N */ +0xdf, 0x0f, 0x1d, 0x09, 0x27, 0x5f, 0x02, 0xc1, /* ....'_.. */ +0x2e, 0x4e, 0xbf, 0x05, 0x27, 0x9f, 0x22, 0x02, /* .N..'.". */ +0x2e, 0xe7, 0x8c, 0x05, 0x27 /* ....' */ +}; + +static const unsigned char pkt195[] = { +0x42, 0xca, 0x00, +0x3c, 0x21, 0x51, 0x85, 0x01, /* B...Z. */ +0x27, 0x2d, 0x82, 0x40, 0x82, 0x12, 0x82, 0x12, /* '-.@.... */ +0x82, 0x9d, 0xbf, 0xff, 0x97, 0x08, 0x10, 0x09, /* ........ */ +0x27, 0x0f, 0x1c, 0x5c, 0x46, 0x03, 0x5b, 0x02, /* '..\F.[. */ +0x1e, 0x04, 0x53, 0x02, 0xef, 0x02, 0x50, 0x03, /* ..S...P. */ +0x1e, 0x00, 0x53, 0x03, 0xef, 0x69, 0xaf, 0x3f, /* ..S..i.? */ +0x80, 0x1b, 0x0d, 0xe1, 0x97, 0x0f, 0x1c, 0x69, /* .......i */ +0xdf, 0xdf, 0x01, 0x00, 0x53, 0x00, 0xff, 0xe0, /* ....S... */ +0x97, 0x76, 0x80, 0x04, 0x10, 0x07, 0x82, 0x0f, /* .v...... */ +0x1e, 0x00, 0x5f, 0x0f, 0xef, 0x6a, 0xaf, 0xc1, /* .._..j.. */ +0x2e, 0x47, 0xdf, 0xf0, 0x1d, 0x5f, 0x02, 0xc1, /* .G..._.. */ +0x2e, 0x47, 0xbf, 0x10, 0x0d, 0x05, 0x27, 0x01, /* .G....'. */ +0x2e, 0x1a, 0x87, 0xf7, 0xef, 0x16, 0x80, 0x52, /* .......R */ +0x80, 0x16, 0x82, 0x02, 0x2e, 0xb7, 0x85, 0x55, /* .......U */ +0x82, 0x02, 0x2e, 0x60, 0x80, 0x01, 0x2e, 0x84, /* ...`.... */ +0x83, 0x26, 0x40, 0x00, 0x5b, 0x3b, 0x33, 0x5c, /* .&@.[;3\ */ +0x47, 0x09, 0x5b, 0x6c, 0x38, 0x3b, 0x43, 0x00, /* G.[l8;C. */ +0x5b, 0x6c, 0x30, 0x41, 0x2e, 0x71, 0xdf, 0xc1, /* [l0A.q.. */ +0x2e, 0x72, 0xdf, 0xbf, 0x03, 0x01, 0x55, 0x01, /* .r....U. */ +0x2e, 0x98, 0x83, 0x01, 0x2e, 0x63, 0x84, 0x01, /* .....c.. */ +0x2e, 0x71, 0x87, 0x05, 0x27, 0x3b, 0x40, 0x01, /* .q..';@. */ +0x5b, 0x02, 0xef, 0x0c, 0xaf, 0x05, 0x27, 0x52, /* [.....'R */ +0xcf, 0xcb, 0xaf, 0x53, 0xdf /* ...S. */ +}; + +static const unsigned char pkt229[] = { +0x42, 0xca, 0x00, +0x2a, 0x27, 0xcc, 0xbf, 0xdf, /* B..*'... */ +0x22, 0x01, 0x55, 0xff, 0x22, 0x01, 0x54, 0x0e, /* ".U.".T. */ +0xef, 0xc9, 0xaf, 0x05, 0x27, 0x0e, 0xcf, 0x6e, /* ....'..n */ +0x1c, 0x49, 0xdf, 0x10, 0x1d, 0x3f, 0x02, 0x49, /* .I...?.I */ +0xaf, 0x0d, 0x44, 0x06, 0x5a, 0x0a, 0x41, 0x03, /* ..D.Z.A. */ +0x5b, 0x49, 0x43, 0x02, 0x5a, 0x48, 0x26, 0x00, /* [IC.ZH&. */ +0x55, 0x49, 0x30, 0x9f, 0x2c, 0x05, 0x5a, 0xdf, /* UI0.,.Z. */ +0x2c, 0x4d, 0x5a, 0x0e, 0x41, 0x16, 0x5b, 0x0c, /* ,MZ.A.[. */ +0x46, 0x14, 0x5a, 0x9f, 0x22, 0x1c, 0xaf, 0x21, /* F.Z."..! */ +0xaf, 0x02, 0x2e, 0xb4, 0x87, 0x03, 0x5a, 0x9f, /* ......Z. */ +0x2c, 0x05, 0x5a, 0x9f, 0x22, 0x04, 0x50, 0x9f, /* ,.Z.".P. */ +0x22, 0x0e, 0x3e, 0x0e, 0x3d, 0x00, 0x5b, 0x5f, /* ".>.=.[_ */ +0xef, 0x1d, 0xaf, 0x49, 0xcf, 0x87, 0x1c, 0x01, /* ...I.... */ +0x18, 0x49, 0xaf, 0x34, 0x50, 0x20, 0x26, 0x08, /* .I.4P &. */ +0x55, 0x1f, 0xcf, 0x48, 0xdf, 0xff, 0x2d, 0x00, /* U..H..-. */ +0x5b, 0xff, 0x21, 0x3f, 0x00, 0x00, 0x53, 0xff, /* [.!?..S. */ +0xef, 0x1f, 0xaf, 0x47, 0xdf, 0x1c, 0xcf, 0x3f, /* ...G...? */ +0x00, 0x1c, 0xaf, 0x1d, 0xcf, 0x48, 0xdf, 0x3f, /* .....H.? */ +0x00, 0x1d, 0xaf, 0xff, 0x22, 0x1f, 0x54, 0xff, /* ....".T. */ +0x2d, 0x03, 0x5b, 0xff, 0x1e, 0x19, 0x5b, 0x60, /* -.[...[` */ +0x10, 0x02, 0x50, 0x60, 0x1e, 0x0a, 0x52, 0x60, /* ..P`..R` */ +0x16, 0x1d, 0xaf, 0x49, 0x30, 0x49, 0x3c, 0x12, /* ...I0I<. */ +0x5b, 0x21, 0xcf, 0x47, 0xdf, 0x3f, 0x00, 0x1c, /* [!.G.?.. */ +0xaf, 0x21, 0x23, 0x0c, 0x50, 0x59, 0x1e, 0x0a, /* .!#.PY.. */ +0x52, 0x49, 0x34, 0x01, 0x5a, 0x21, 0x23, 0x06, /* RI4.Z!#. */ +0x50, 0x21, 0xcf, 0x47, 0xdf /* P!.G. */ +}; + +static const unsigned char pkt231[] = { +0x42, 0xca, 0x00, +0x8e, 0x27, 0x3f, 0x00, 0x21, /* B...'?.! */ +0xaf, 0x01, 0x50, 0x06, 0x1e, 0xf4, 0x5f, 0x05, /* ..P..._. */ +0x27, 0x1e, 0x23, 0x0d, 0xcf, 0x06, 0x1c, 0x1a, /* '.#..... */ +0x54, 0x48, 0xcf, 0xdf, 0x2d, 0x00, 0x5b, 0xdf, /* TH..-.[. */ +0x21, 0x09, 0x27, 0x1f, 0x22, 0xbf, 0x22, 0x1a, /* !.'.".". */ +0x27, 0xc0, 0x2e, 0x96, 0xdf, 0x7f, 0x1f, 0x02, /* '....... */ +0x54, 0x3f, 0x20, 0xc0, 0x2e, 0x96, 0xbf, 0x59, /* T? ....Y */ +0x80, 0x40, 0x2e, 0x97, 0xbf, 0xc0, 0x2e, 0x95, /* .@...... */ +0xdf, 0x76, 0x80, 0x1e, 0xbf, 0x0c, 0x42, 0x02, /* .v....B. */ +0x5b, 0x9f, 0x22, 0x40, 0x2e, 0x96, 0xbf, 0x05, /* [."@.... */ +0x27, 0x0d, 0xcf, 0x06, 0x1c, 0x06, 0x1e, 0x00, /* '....... */ +0x54, 0x0d, 0x27, 0x0c, 0x27, 0x09, 0x46, 0x0d, /* T.'.'.F. */ +0x5b, 0x02, 0x2e, 0x38, 0x86, 0x07, 0x52, 0x0f, /* [..8..R. */ +0xcf, 0x01, 0x16, 0x02, 0x53, 0x02, 0x2e, 0xfe, /* ....S... */ +0x87, 0x04, 0x50, 0xf4, 0xaf, 0x02, 0x50, 0xf2, /* ..P...P. */ +0xcf, 0x02, 0x10, 0x0f, 0xaf, 0x05, 0x27, 0x5a, /* ......'Z */ +0xcf, 0xdf, 0x22, 0x10, 0x54, 0x3e, 0xdf, 0x3f, /* ..".T>.? */ +0x20, 0x3f, 0x1f, 0x0a, 0x52, 0xbf, 0x22, 0x3e, /* ?..R."> */ +0xbf, 0x3d, 0xdf, 0x3f, 0x20, 0xdf, 0x03, 0x02, /* .=.? ... */ +0x52, 0xbf, 0x22, 0x3d, 0xbf, 0x0c, 0x27, 0x3d, /* R."=..'= */ +0xbf, 0x0d, 0x27, 0x3e, 0xbf, 0x0d, 0x27, 0x0d, /* ..'>..'. */ +0x27, 0xbf, 0x22, 0x3e, 0xbf, 0x3d, 0xbf, 0x05, /* '.">.=.. */ +0x27, 0x0f, 0x1c, 0x69, 0xdf, 0xdf, 0x01, 0x00, /* '..i.... */ +0x53, 0x00, 0xff, 0x05, 0x27, 0x2d, 0x82, 0x40, /* S...'-.@ */ +0x82, 0x12, 0x82, 0x12, 0x82, 0x9d, 0xbf, 0xff, /* ........ */ +0x97, 0x08, 0x10, 0x09, 0x27 /* ....' */ +}; + +static const unsigned char pkt233[] = { +0x42, 0x24, 0x00, +0xf2, 0x27, 0x0f, 0x1c, 0x5c, /* B$..'..\ */ +0x46, 0x03, 0x5b, 0x02, 0x1e, 0x04, 0x53, 0x02, /* F.[...S. */ +0xef, 0x02, 0x50, 0x03, 0x1e, 0x00, 0x53, 0x03, /* ..P...S. */ +0xef, 0x69, 0xaf, 0x05, 0x27, 0x14, 0xef, 0xf4, /* .i..'... */ +0xaf, 0x00, 0xef, 0xf5, 0xaf, 0x05, 0x27 /* ......' */ +}; + +static const unsigned char pkt235[] = { +0x42, 0xca, 0x00, +0x03, 0x28, 0x0c, 0x42, 0x00, /* B...(.B. */ +0x5b, 0x18, 0x23, 0x00, 0xef, 0x0c, 0xaf, 0x0e, /* [.#..... */ +0xcf, 0xe0, 0x1c, 0x0e, 0xaf, 0x0a, 0x40, 0x02, /* ......@. */ +0x5a, 0x3b, 0x46, 0x00, 0x5a, 0x05, 0x27, 0x37, /* Z;F.Z.'7 */ +0x43, 0xfc, 0x5b, 0x08, 0xef, 0x0c, 0xaf, 0x0d, /* C.[..... */ +0x40, 0x0a, 0x5a, 0xee, 0xcf, 0x64, 0x1e, 0x01, /* @.Z..d.. */ +0x5e, 0x0c, 0x3b, 0x05, 0x27, 0x0d, 0x30, 0x0c, /* ^.;.'.0. */ +0x35, 0xbf, 0x22, 0xc0, 0x2e, 0x96, 0xbf, 0x05, /* 5."..... */ +0x27, 0x0e, 0x45, 0x02, 0x5b, 0x02, 0x2e, 0x30, /* '.E.[..0 */ +0x88, 0x01, 0x50, 0x02, 0x2e, 0x3a, 0x88, 0x0d, /* ..P..:.. */ +0x41, 0x24, 0x5a, 0x0d, 0x42, 0x14, 0x5a, 0x02, /* A$Z.B.Z. */ +0x2e, 0x2f, 0x79, 0x02, 0x2e, 0x8f, 0x88, 0x19, /* ./y..... */ +0xcf, 0xfe, 0x1e, 0x03, 0x5c, 0x0e, 0x3d, 0x0d, /* ....\.=. */ +0x39, 0x0d, 0x3b, 0x0c, 0x27, 0x0d, 0x27, 0x02, /* 9.;.'.'. */ +0x2e, 0xae, 0x88, 0x19, 0xcf, 0x02, 0x1e, 0xf9, /* ........ */ +0x5a, 0x0e, 0x3e, 0x0d, 0x3a, 0x0d, 0x33, 0x0c, /* Z.>.:.3. */ +0x27, 0xe4, 0x37, 0x02, 0x2e, 0x8b, 0x89, 0xe4, /* '.7..... */ +0x3f, 0x02, 0x2e, 0x80, 0x89, 0x0d, 0x45, 0x61, /* ?.....Ea */ +0x5b, 0x18, 0xcf, 0xdf, 0x22, 0x6b, 0x54, 0x0d, /* [..."kT. */ +0x3b, 0x02, 0x2e, 0xab, 0x78, 0x02, 0x2e, 0x8b, /* ;...x... */ +0x89, 0x02, 0x2e, 0x80, 0x89, 0x0d, 0x42, 0x07, /* ......B. */ +0x5a, 0x0d, 0x45, 0x53, 0x5b, 0x18, 0xcf, 0xdf, /* Z.ES[... */ +0x22, 0x5d, 0x54, 0x0d, 0x33, 0x02, 0x2e, 0xab, /* "]T.3... */ +0x78, 0x15, 0xcf, 0x1a, 0xaf, 0xe4, 0x37, 0x02, /* x.....7. */ +0x2e, 0x8b, 0x89, 0x15, 0xcf, 0x1b, 0xaf, 0xe4, /* ........ */ +0x3f, 0x0d, 0xcf, 0x60, 0x1c /* ?..`. */ +}; + +static const unsigned char pkt237[] = { +0x42, 0xca, 0x00, +0x67, 0x28, 0xdf, 0x22, 0x01, /* B..g(.". */ +0x55, 0x02, 0x2e, 0xdf, 0x78, 0x16, 0xcf, 0x13, /* U...x... */ +0xdf, 0x2a, 0x1e, 0x00, 0x2e, 0x04, 0x5f, 0x2a, /* .*...._* */ +0x1f, 0x00, 0x2e, 0x01, 0x5f, 0x02, 0x2e, 0xdf, /* ...._... */ +0x78, 0xbf, 0x03, 0x40, 0x54, 0x20, 0x52, 0x02, /* x..@T R. */ +0x2e, 0x80, 0x89, 0x9f, 0x22, 0x1a, 0xaf, 0x18, /* ...."... */ +0xcf, 0x12, 0xdf, 0xbf, 0x03, 0x00, 0x53, 0x29, /* ......S) */ +0x50, 0x02, 0x2e, 0x8f, 0x88, 0x02, 0x2e, 0x74, /* P......t */ +0x89, 0x9f, 0x22, 0x1b, 0xaf, 0x02, 0x2e, 0x2e, /* .."..... */ +0x88, 0x02, 0x2e, 0xab, 0x78, 0x0e, 0xcf, 0x9f, /* ....x... */ +0x1c, 0x0e, 0xaf, 0x05, 0x27, 0x0e, 0xcf, 0x5f, /* ....'.._ */ +0x2d, 0x05, 0x5a, 0x9f, 0x2b, 0x5f, 0x29, 0x0e, /* -.Z.+_). */ +0xaf, 0x5f, 0xff, 0x1d, 0xbf, 0x1c, 0x23, 0x05, /* ._....#. */ +0x27, 0x9f, 0x22, 0x1b, 0xaf, 0x18, 0xcf, 0xdf, /* '."..... */ +0x22, 0x0c, 0x54, 0x18, 0xcf, 0x12, 0xdf, 0xbf, /* ".T..... */ +0x03, 0x00, 0x53, 0x07, 0x50, 0x02, 0x2e, 0xae, /* ..S.P... */ +0x88, 0x02, 0x2e, 0x7a, 0x89, 0x9f, 0x22, 0x1a, /* ...z..". */ +0xaf, 0x02, 0x2e, 0x38, 0x88, 0x02, 0x2e, 0xbc, /* ...8.... */ +0x88, 0x05, 0x27, 0x0e, 0xcf, 0x9f, 0x2d, 0x05, /* ..'...-. */ +0x5a, 0x9f, 0x29, 0x5f, 0x2b, 0x0e, 0xaf, 0x00, /* Z.)_+... */ +0xff, 0x1d, 0xbf, 0x1c, 0x23, 0x05, 0x27, 0x02, /* ....#.'. */ +0x2e, 0x64, 0x89, 0x02, 0x2e, 0xc4, 0x78, 0x0d, /* .d....x. */ +0x45, 0x20, 0x5b, 0x02, 0x2e, 0x64, 0x89, 0x18, /* E [..d.. */ +0xcf, 0x12, 0xdf, 0xbf, 0x03, 0x6a, 0x53, 0x0d, /* .....jS. */ +0x44, 0x02, 0x5b, 0x0c, 0x35, 0x02, 0x2e, 0xd6, /* D.[.5... */ +0x78, 0x17, 0xcf, 0xdf, 0x22 /* x..." */ +}; + +static const unsigned char pkt239[] = { +0x42, 0xca, 0x00, +0xcb, 0x28, 0x09, 0x55, 0x18, /* B...(.U. */ +0xcf, 0xdf, 0x22, 0x06, 0x55, 0x02, 0x2e, 0xdc, /* ..".U... */ +0x88, 0x0e, 0x3b, 0x0c, 0xdf, 0x24, 0x19, 0x0c, /* ..;..$.. */ +0xbf, 0x05, 0x27, 0x11, 0xcf, 0xff, 0x1e, 0x01, /* ..'..... */ +0x54, 0x1f, 0x20, 0x11, 0xaf, 0x05, 0x27, 0x1a, /* T. ...'. */ +0x23, 0x1b, 0x23, 0x05, 0x27, 0x02, 0x2e, 0xdc, /* #.#.'... */ +0x88, 0x02, 0x2e, 0xf2, 0x88, 0x02, 0x2e, 0x64, /* .......d */ +0x89, 0x02, 0x2e, 0xb4, 0x87, 0x37, 0x5a, 0x0a, /* .....7Z. */ +0xcf, 0xc0, 0x1c, 0xc0, 0x1e, 0x0e, 0x55, 0x9f, /* ......U. */ +0x22, 0x1f, 0xaf, 0x20, 0xaf, 0x19, 0xaf, 0x02, /* ".. .... */ +0x2e, 0x0f, 0x79, 0x0e, 0xcf, 0x05, 0x18, 0x0e, /* ..y..... */ +0xaf, 0x9f, 0x22, 0x47, 0xaf, 0x48, 0xaf, 0x17, /* .."G.H.. */ +0xaf, 0x18, 0xaf, 0x05, 0x27, 0x20, 0xcf, 0xdf, /* ....' .. */ +0x22, 0x06, 0x54, 0x05, 0x1e, 0x1b, 0x55, 0x1f, /* ".T...U. */ +0xdf, 0x80, 0x1f, 0x18, 0x5e, 0x02, 0x2e, 0x08, /* ....^... */ +0x79, 0x1f, 0xdf, 0x10, 0x1f, 0x13, 0x5e, 0x9f, /* y.....^. */ +0x22, 0x20, 0xaf, 0x1f, 0xaf, 0x0a, 0xcf, 0xc0, /* " ...... */ +0x1c, 0x80, 0x1e, 0x0a, 0x55, 0x0d, 0x41, 0x01, /* ....U.A. */ +0x5a, 0x0e, 0x35, 0x00, 0x50, 0x0e, 0x36, 0x0d, /* Z.5.P.6. */ +0xcf, 0x06, 0x18, 0x0d, 0xaf, 0x0e, 0x31, 0x9f, /* ......1. */ +0x22, 0x19, 0xaf, 0x02, 0x2e, 0x20, 0x79, 0x1f, /* ".... y. */ +0x20, 0x06, 0x1e, 0x00, 0x5e, 0x20, 0xaf, 0x0d, /* ...^ .. */ +0x47, 0x0c, 0x5b, 0x51, 0xef, 0x0c, 0xaf, 0x0e, /* G.[Q.... */ +0xcf, 0xfa, 0x1c, 0x0e, 0xaf, 0x20, 0xcf, 0xdf, /* ..... .. */ +0x22, 0x03, 0x54, 0x06, 0x1e, 0x01, 0x54, 0x5f, /* ".T...T_ */ +0x20, 0x20, 0xaf, 0x05, 0x27 /* ..' */ +}; + +static const unsigned char pkt241[] = { +0x42, 0xca, 0x00, +0x2f, 0x29, 0x0d, 0x44, 0x0b, /* B../).D. */ +0x5a, 0x0d, 0xcf, 0x06, 0x1c, 0x08, 0x54, 0x0c, /* Z.....T. */ +0x30, 0x48, 0xcf, 0xdf, 0x2d, 0x02, 0x5a, 0x9f, /* 0H..-.Z. */ +0x22, 0x1d, 0xaf, 0x01, 0x50, 0x5f, 0xef, 0x1d, /* "...P_.. */ +0xaf, 0x0c, 0x31, 0x0d, 0x45, 0x13, 0x5b, 0x0a, /* ..1.E.[. */ +0xcf, 0x30, 0x1c, 0x0e, 0x55, 0x0d, 0xcf, 0x06, /* .0..U... */ +0x1c, 0x06, 0x1e, 0x0d, 0x54, 0x11, 0xcf, 0x07, /* ....T... */ +0x1e, 0x03, 0x53, 0x03, 0xef, 0x12, 0xaf, 0x02, /* ..S..... */ +0x2e, 0x54, 0x79, 0x05, 0xef, 0x12, 0xaf, 0x02, /* .Ty..... */ +0x2e, 0x54, 0x79, 0x01, 0xef, 0x12, 0xaf, 0x18, /* .Ty..... */ +0x23, 0x9f, 0x22, 0x11, 0xaf, 0x0d, 0xcf, 0x1f, /* #."..... */ +0x1c, 0x0d, 0xaf, 0x0c, 0xdf, 0x24, 0x19, 0x0c, /* .....$.. */ +0xbf, 0x0a, 0xdf, 0x30, 0x1d, 0x20, 0x1f, 0x01, /* ...0. .. */ +0x55, 0xf9, 0x1c, 0x0d, 0xaf, 0x05, 0x27, 0x17, /* U.....'. */ +0xdf, 0xff, 0x21, 0x47, 0xbf, 0x18, 0xdf, 0x02, /* ..!G.... */ +0x2e, 0xb4, 0x87, 0x03, 0x5b, 0x0e, 0x46, 0x04, /* ....[.F. */ +0x5a, 0x02, 0x2e, 0x71, 0x79, 0x0d, 0x43, 0x00, /* Z..qy.C. */ +0x5a, 0xff, 0x21, 0x48, 0xbf, 0x05, 0x27, 0x19, /* Z.!H..'. */ +0xcf, 0x80, 0x1e, 0x01, 0x54, 0x5f, 0x20, 0x19, /* ....T_ . */ +0xaf, 0x05, 0x27, 0x19, 0xcf, 0x7f, 0x1e, 0x01, /* ..'..... */ +0x54, 0x1f, 0x20, 0x19, 0xaf, 0x05, 0x27, 0x13, /* T. ...'. */ +0xcf, 0x16, 0xaf, 0x15, 0xcf, 0x18, 0xaf, 0x14, /* ........ */ +0xcf, 0x17, 0xaf, 0x0d, 0x3d, 0x0d, 0x46, 0x00, /* ....=.F. */ +0x5b, 0x0d, 0x35, 0x05, 0x27, 0x14, 0x23, 0x15, /* [.5.'.#. */ +0x23, 0xff, 0xef, 0x13, 0xaf, 0x02, 0x2e, 0x98, /* #....... */ +0x89, 0x0d, 0x3e, 0x13, 0xcf /* ..>.. */ +}; + +static const unsigned char pkt243[] = { +0x42, 0xc0, 0x00, +0x93, 0x29, 0x46, 0xff, 0xbf, /* B...)F.. */ +0x03, 0x00, 0x53, 0x0d, 0x36, 0x05, 0x27, 0x0d, /* ..S.6.'. */ +0xcf, 0x06, 0x1c, 0x06, 0x1e, 0x07, 0x55, 0xe4, /* ......U. */ +0x47, 0x02, 0x5a, 0x1a, 0xcf, 0x02, 0x2e, 0xa5, /* G.Z..... */ +0x79, 0x1b, 0xcf, 0x02, 0x2e, 0xa5, 0x79, 0x18, /* y.....y. */ +0xcf, 0x00, 0x1e, 0x04, 0x55, 0x5d, 0xef, 0x1b, /* ....U].. */ +0xff, 0x02, 0x2e, 0xc0, 0x79, 0x18, 0xcf, 0x01, /* ....y... */ +0x1e, 0x03, 0x55, 0x5e, 0xef, 0x1b, 0xff, 0x02, /* ..U^.... */ +0x2e, 0xc0, 0x79, 0x02, 0x1e, 0x03, 0x55, 0x61, /* ..y...Ua */ +0xef, 0x1b, 0xff, 0x02, 0x2e, 0xc0, 0x79, 0x03, /* ......y. */ +0x1e, 0x03, 0x55, 0x66, 0xef, 0x1b, 0xff, 0x02, /* ..Uf.... */ +0x2e, 0xc0, 0x79, 0x6d, 0xef, 0x1b, 0xff, 0x1a, /* ..ym.... */ +0x27, 0x07, 0x27, 0xe6, 0xaf, 0xe9, 0xbf, 0x7e, /* '.'....~ */ +0x81, 0xec, 0xcf, 0x13, 0xdf, 0xbf, 0x03, 0x19, /* ........ */ +0x54, 0x0a, 0x5e, 0x13, 0xaf, 0xe9, 0xcf, 0x0f, /* T.^..... */ +0x1c, 0x15, 0xaf, 0xe9, 0xcf, 0x09, 0x27, 0x0f, /* ......'. */ +0x1c, 0xdf, 0x2c, 0x00, 0x5b, 0xf0, 0x18, 0x14, /* ..,.[... */ +0xaf, 0x01, 0x0e, 0x07, 0x27, 0x88, 0x1f, 0xe8, /* ....'... */ +0x55, 0x0d, 0x3e, 0x13, 0xcf, 0x46, 0x1e, 0x04, /* U.>..F.. */ +0x53, 0x0d, 0x36, 0x13, 0xcf, 0x46, 0x1e, 0x00, /* S.6..F.. */ +0x5e, 0x0d, 0x36, 0x05, 0x27, 0xe9, 0xcf, 0x09, /* ^.6.'... */ +0x27, 0xdf, 0x2c, 0x00, 0x5b, 0xdf, 0x21, 0x0f, /* '.,.[.!. */ +0x1c, 0x14, 0xdf, 0xff, 0x2d, 0x00, 0x5b, 0xff, /* ....-.[. */ +0x21, 0xbf, 0x03, 0xe5, 0x53, 0xec, 0xcf, 0x02, /* !...S... */ +0x2e, 0xca, 0x79 /* ..y */ +}; + +static const unsigned char pkt245[] = { +0x42, 0x66, 0x00, +0x00, 0x2c, 0x01, 0x2e, 0x65, /* Bf..,..e */ +0x84, 0x08, 0x44, 0x2c, 0x5a, 0xff, 0x0d, 0x48, /* ..D,Z..H */ +0xef, 0x5f, 0x9a, 0x2a, 0xaf, 0x02, 0x2e, 0x75, /* ._.*...u */ +0x80, 0xdf, 0x96, 0x26, 0x40, 0x07, 0x5b, 0xa0, /* ...&@.[. */ +0xcf, 0x30, 0x1c, 0x04, 0x54, 0x20, 0x1e, 0x01, /* .0..T .. */ +0x55, 0x31, 0xff, 0x01, 0x50, 0x00, 0xff, 0x30, /* U1..P..0 */ +0x19, 0xbf, 0x9a, 0x2b, 0xbf, 0xa9, 0xcf, 0x70, /* ...+...p */ +0x1c, 0xa5, 0xdf, 0x0c, 0x1d, 0xff, 0x20, 0xff, /* ...... . */ +0x20, 0x5f, 0x02, 0xff, 0x9a, 0x2c, 0xbf, 0xdd, /* _...,.. */ +0x97, 0x1f, 0x9b, 0x2d, 0xaf, 0x29, 0xcf, 0x09, /* ...-.).. */ +0x27, 0x28, 0xdf, 0x3f, 0x02, 0x9f, 0x9c, 0x6a, /* '(.?...j */ +0xcf, 0x09, 0x27, 0x69, 0xdf, 0x3f, 0x02, 0xdf, /* ..'i.?.. */ +0x9c, 0x6d, 0x2e, 0x6d, 0xdf, 0x1f, 0x9d, 0x05, /* .m.m.... */ +0x27 /* ' */ +}; + +static const unsigned char pkt247[] = { +0x42, 0x2c, 0x00, +0x32, 0x2c, 0x08, 0x44, 0x11, /* B,.2,.D. */ +0x5a, 0x3f, 0x80, 0x28, 0x0d, 0xe2, 0x97, 0xdf, /* Z?.(.... */ +0x96, 0xe1, 0x97, 0xdf, 0x96, 0x01, 0x2e, 0xbf, /* ........ */ +0x84, 0xfd, 0x0d, 0x29, 0xcf, 0x09, 0x27, 0x28, /* ...)..'( */ +0xdf, 0x3f, 0x02, 0x5f, 0x9f, 0xdd, 0x97, 0x5f, /* .?._..._ */ +0x9f, 0xdd, 0x97, 0x5f, 0x9f, 0x05, 0x27 /* ..._..' */ +}; + +static const unsigned char pkt249[] = { +0x42, 0xca, 0x00, +0x47, 0x2c, 0xfe, 0xcf, 0x58, /* B..G,..X */ +0xaf, 0xfe, 0xcf, 0xfe, 0xdf, 0x02, 0x2e, 0xde, /* ........ */ +0x8c, 0xfe, 0xcf, 0x3c, 0xaf, 0x07, 0x3d, 0x58, /* ...<..=X */ +0x40, 0x4e, 0x5a, 0x3c, 0x26, 0x4c, 0x55, 0x37, /* @NZ<&LU7 */ +0x45, 0x4a, 0x5a, 0x02, 0x2e, 0x5c, 0x8d, 0x47, /* EJZ..\.G */ +0x5a, 0x02, 0x2e, 0xee, 0x8c, 0x00, 0x2e, 0xb9, /* Z....... */ +0x8d, 0xfe, 0xef, 0x16, 0x80, 0x02, 0xcf, 0xdf, /* ........ */ +0x96, 0x61, 0xef, 0xc0, 0xaf, 0x04, 0x27, 0xc1, /* .a....'. */ +0x46, 0x04, 0x5b, 0xc0, 0x3e, 0x40, 0xef, 0xc1, /* F.[.>@.. */ +0xaf, 0x01, 0x2e, 0x8d, 0x8b, 0xd0, 0x41, 0x07, /* ......A. */ +0x5b, 0x02, 0x2e, 0x9e, 0x8c, 0xf2, 0x5b, 0xae, /* [.....[. */ +0x87, 0xdd, 0x97, 0x1f, 0x2d, 0x06, 0x5b, 0x03, /* ....-.[. */ +0x50, 0x01, 0x0c, 0x02, 0xcf, 0xc0, 0x1c, 0x01, /* P....... */ +0x55, 0x02, 0x2e, 0x81, 0x8c, 0xc0, 0x23, 0x20, /* U.....# */ +0xef, 0xc1, 0xaf, 0x00, 0x2e, 0xd8, 0x8d, 0x05, /* ........ */ +0x27, 0x9b, 0x22, 0x37, 0x45, 0x05, 0x5a, 0x41, /* '."7E.ZA */ +0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x04, 0x5b, 0x00, /* .R..-.[. */ +0x28, 0x02, 0x50, 0x3b, 0x43, 0x00, 0x5b, 0x00, /* (.P;C.[. */ +0x28, 0xd3, 0xdf, 0xc6, 0x2e, 0x15, 0xbf, 0xd3, /* (....... */ +0x3c, 0x40, 0xef, 0x09, 0x80, 0xdd, 0x97, 0xff, /* <@...... */ +0xaf, 0x00, 0x2e, 0xa7, 0x8a, 0xc6, 0x2e, 0x15, /* ........ */ +0xdf, 0x10, 0x1d, 0xd3, 0xcf, 0x3f, 0x02, 0xd3, /* .....?.. */ +0xaf, 0x05, 0x27, 0xed, 0x83, 0x07, 0x45, 0x05, /* ..'...E. */ +0x27, 0x3d, 0x23, 0x07, 0x3d, 0x02, 0xcf, 0xdf, /* '=#.=... */ +0x96, 0x02, 0x2e, 0xee, 0x8c, 0x02, 0x2e, 0xd7, /* ........ */ +0x8c, 0xfe, 0xef, 0x16, 0x80 /* ..... */ +}; + +static const unsigned char pkt251[] = { +0x42, 0xca, 0x00, +0xab, 0x2c, 0x05, 0xef, 0xc0, /* B...,... */ +0xaf, 0x04, 0x27, 0xd0, 0x41, 0x03, 0x5b, 0x02, /* ..'.A.[. */ +0x2e, 0x9e, 0x8c, 0xf9, 0x5b, 0xbb, 0x50, 0x27, /* ....[.P' */ +0x82, 0x04, 0xef, 0xc1, 0xaf, 0x9b, 0x22, 0x02, /* ......". */ +0x2e, 0x12, 0x8d, 0xdd, 0x97, 0xdf, 0x22, 0x02, /* ......". */ +0x55, 0x58, 0x40, 0x02, 0x5a, 0x0b, 0x50, 0x58, /* UX@.Z.PX */ +0x40, 0x09, 0x5a, 0xdd, 0x97, 0x1f, 0x2d, 0xb3, /* @.Z...-. */ +0x5a, 0x02, 0x2e, 0x5d, 0x8d, 0xb2, 0x5b, 0x9b, /* Z..]..[. */ +0x22, 0x02, 0x2e, 0x8d, 0x8c, 0xae, 0x50, 0x02, /* ".....P. */ +0x2e, 0x5d, 0x8d, 0xd5, 0x5b, 0x02, 0x2e, 0x81, /* .]..[... */ +0x8c, 0x58, 0x41, 0x02, 0x5b, 0x01, 0x0c, 0x02, /* .XA.[... */ +0x2e, 0x7b, 0x7c, 0xcd, 0x50, 0x41, 0x2e, 0x52, /* .{|.PA.R */ +0xdf, 0xed, 0x1c, 0x04, 0x18, 0x41, 0x2e, 0x52, /* .....A.R */ +0xbf, 0x05, 0x27, 0x1a, 0x27, 0x56, 0xdf, 0x59, /* ..'.'V.Y */ +0x80, 0xdf, 0x22, 0x00, 0x54, 0x01, 0x16, 0x3f, /* ..".T..? */ +0x1e, 0x00, 0x5f, 0x3f, 0xef, 0x1f, 0x22, 0x1f, /* .._?..". */ +0x22, 0xaf, 0xdf, 0x03, 0x1d, 0x5f, 0x02, 0xaf, /* "...._.. */ +0xbf, 0x05, 0x27, 0x00, 0x2e, 0xa1, 0x8d, 0xae, /* ..'..... */ +0xdf, 0xe0, 0x19, 0xae, 0xbf, 0x57, 0x40, 0x00, /* .....W@. */ +0x5b, 0xa1, 0x32, 0x57, 0x43, 0x00, 0x5b, 0xae, /* [.2WC.[. */ +0x3f, 0xed, 0x80, 0x05, 0x27, 0x41, 0x2e, 0x52, /* ?...'A.R */ +0xdf, 0x03, 0x18, 0x41, 0x2e, 0x52, 0xbf, 0x05, /* ...A.R.. */ +0x27, 0xd3, 0xdf, 0xff, 0x96, 0x9b, 0x22, 0x02, /* '.....". */ +0x2e, 0x12, 0x8d, 0xd3, 0x3c, 0x07, 0x80, 0xdd, /* ....<... */ +0x97, 0xff, 0xaf, 0x00, 0x2e, 0xa7, 0x8a, 0xdd, /* ........ */ +0x9f, 0x10, 0x1d, 0xd3, 0xcf /* ..... */ +}; + +static const unsigned char pkt253[] = { +0x42, 0xb4, 0x00, +0x0f, 0x2d, 0x3f, 0x02, 0xd3, /* B...-?.. */ +0xaf, 0x05, 0x27, 0x37, 0x45, 0x10, 0x5a, 0x02, /* ..'7E.Z. */ +0x2e, 0x5c, 0x8d, 0x0d, 0x5a, 0x02, 0x2e, 0xee, /* .\..Z... */ +0x8c, 0x00, 0x2e, 0xbf, 0x8d, 0x00, 0x2e, 0xd3, /* ........ */ +0x8d, 0x41, 0x2e, 0x52, 0xdf, 0xdf, 0x2d, 0x00, /* .A.R..-. */ +0x5b, 0x00, 0x28, 0x00, 0x2e, 0xd8, 0x8d, 0x05, /* [.(..... */ +0x27, 0xf9, 0xcf, 0xdf, 0x96, 0xf9, 0x3d, 0x01, /* '.....=. */ +0x2e, 0x06, 0x82, 0x2d, 0xff, 0xa7, 0xef, 0xe1, /* ...-.... */ +0xbf, 0xe0, 0xaf, 0x09, 0xef, 0x10, 0xaf, 0x01, /* ........ */ +0x2e, 0x94, 0x86, 0xed, 0x80, 0x01, 0x2e, 0x18, /* ........ */ +0x87, 0x01, 0x2e, 0x1a, 0x87, 0x00, 0x2e, 0x16, /* ........ */ +0x82, 0x5b, 0x82, 0x00, 0x2e, 0x2d, 0x82, 0x26, /* .[...-.& */ +0x37, 0x00, 0x5a, 0x0c, 0x50, 0xff, 0x96, 0xdf, /* 7.Z.P... */ +0x96, 0x79, 0xcf, 0x7a, 0xdf, 0xff, 0x96, 0xdf, /* .y.z.... */ +0x96, 0xc2, 0x97, 0xc3, 0x9f, 0x9d, 0x01, 0x5d, /* .......] */ +0x01, 0x07, 0x53, 0xdd, 0x97, 0xdd, 0x9f, 0x79, /* ..S....y */ +0xaf, 0x7a, 0xbf, 0x3b, 0x3b, 0xdd, 0x97, 0xf9, /* .z.;;... */ +0xaf, 0x05, 0x27, 0xff, 0x22, 0x01, 0x55, 0x32, /* ..'.".U2 */ +0x1e, 0xf3, 0x5f, 0x02, 0x0c, 0x02, 0x2e, 0x4f, /* .._....O */ +0x8d, 0x3b, 0x33, 0x00, 0x28, 0x05, 0x27, 0x0d, /* .;3.(.'. */ +0x27, 0x3c, 0x26, 0x07, 0x54, 0x3c, 0xcf, 0x3d, /* '<&.T<.= */ +0xdf, 0x3f, 0x20, 0x3d, 0xbf, 0xdf, 0x03, 0x01, /* .? =.... */ +0x52, 0x3d, 0x23, 0x0c, 0x27, 0x0d, 0x27 /* R=#.'.' */ +}; + +static const unsigned char pkt255[] = { +0x42, 0x1a, 0x00, +0x68, 0x2d, 0x09, 0x43, 0x04, /* B..h-.C. */ +0x5b, 0x00, 0xef, 0xf8, 0xaf, 0x32, 0xef, 0xfa, /* [....2.. */ +0xaf, 0x03, 0x50, 0x01, 0xef, 0xf8, 0xaf, 0x42, /* ..P....B */ +0xef, 0xfa, 0xaf, 0x05, 0x27 /* ....' */ +}; + +static const unsigned char pkt257[] = { +0x42, 0x26, 0x00, +0x74, 0x2d, 0xd3, 0x45, 0xfd, /* B&.t-.E. */ +0x5a, 0x0f, 0x27, 0xd3, 0x45, 0xfa, 0x5a, 0x0f, /* Z.'.E.Z. */ +0x27, 0xd3, 0x45, 0xf7, 0x5a, 0x0f, 0x27, 0x41, /* '.E.Z.'A */ +0x2e, 0xa1, 0xdf, 0x9f, 0x28, 0x41, 0x2e, 0xa1, /* ....(A.. */ +0xbf, 0x02, 0x2e, 0x58, 0x80, 0x00, 0x2e, 0xcb, /* ...X.... */ +0x7a /* z */ +}; + +static const unsigned char pkt259[] = { +0x42, 0x16, 0x00, +0x86, 0x2d, 0xd3, 0x45, 0x02, /* B...-.E. */ +0x5a, 0xd3, 0x45, 0x00, 0x5a, 0x05, 0x27, 0xd0, /* Z.E.Z.'. */ +0x41, 0xf8, 0x5b, 0xed, 0x83, 0xf6, 0x50, 0x05, /* A.[...P. */ +0x27 /* ' */ +}; + +static const unsigned char pkt261[] = { +0x42, 0x4e, 0x00, +0x90, 0x2d, 0x07, 0x3d, 0x02, /* BN..-.=. */ +0x5b, 0xae, 0x87, 0xc2, 0x23, 0xd3, 0x3c, 0x02, /* [...#.<. */ +0x44, 0xd4, 0x2f, 0xf8, 0x5a, 0x02, 0x45, 0xd5, /* D./.Z.E. */ +0x2f, 0x59, 0x5b, 0x58, 0x23, 0x3c, 0x26, 0x02, /* /Y[X#<&. */ +0x55, 0x02, 0x2e, 0x4f, 0x8c, 0x00, 0x50, 0xff, /* U..O..P. */ +0x8e, 0x07, 0x45, 0xeb, 0x5a, 0x41, 0x2e, 0x53, /* ..E.ZA.S */ +0xdf, 0xc1, 0x2e, 0x79, 0xdf, 0xff, 0x96, 0xdf, /* ...y.... */ +0x96, 0x41, 0x2e, 0x55, 0xdf, 0xc1, 0x2e, 0x78, /* .A.U...x */ +0xdf, 0x9d, 0x01, 0x5d, 0x01, 0xff, 0x22, 0x00, /* ...]..". */ +0x54, 0xff, 0xef, 0x2e, 0xaf, 0xd5, 0x2f, 0x3e, /* T...../> */ +0x50 /* P */ +}; + +static const unsigned char pkt263[] = { +0x42, 0xca, 0x00, +0xb6, 0x2d, 0xfa, 0xcf, 0xdf, /* B...-... */ +0x96, 0x37, 0xcf, 0xdf, 0x96, 0x08, 0xcf, 0xdf, /* .7...... */ +0x96, 0x3d, 0xcf, 0xdf, 0x96, 0x77, 0xcf, 0xdf, /* .=...w.. */ +0x96, 0x26, 0xcf, 0xdf, 0x96, 0x26, 0x23, 0x01, /* .&...&#. */ +0x2e, 0x08, 0x82, 0xdd, 0x97, 0x26, 0xaf, 0xdd, /* .....&.. */ +0x97, 0x77, 0xaf, 0xdd, 0x97, 0x3d, 0xaf, 0xdd, /* .w...=.. */ +0x97, 0x08, 0xaf, 0xdd, 0x97, 0x37, 0xaf, 0xdd, /* .....7.. */ +0x97, 0xfa, 0xaf, 0x9f, 0x22, 0x6d, 0x2e, 0x6d, /* ...."m.m */ +0xbf, 0x26, 0x40, 0x3a, 0x5b, 0x73, 0x43, 0x08, /* .&@:[sC. */ +0x5b, 0x73, 0xcf, 0x09, 0x27, 0x0f, 0x1c, 0x10, /* [s..'... */ +0xaf, 0x82, 0xcf, 0x01, 0x2e, 0xf9, 0x81, 0xed, /* ........ */ +0x80, 0x05, 0x50, 0x81, 0xcf, 0x10, 0xaf, 0x82, /* ..P..... */ +0xcf, 0x01, 0x2e, 0xf9, 0x81, 0xed, 0x80, 0xc8, /* ........ */ +0xef, 0x0f, 0xaf, 0x08, 0x31, 0x31, 0xef, 0x0a, /* ....11.. */ +0xaf, 0x9f, 0x22, 0x0d, 0xaf, 0x81, 0xcf, 0x10, /* .."..... */ +0xaf, 0x01, 0x2e, 0x94, 0x86, 0x82, 0xcf, 0x04, /* ........ */ +0x16, 0x01, 0x2e, 0xf9, 0x81, 0xed, 0x80, 0x10, /* ........ */ +0xcf, 0xb0, 0xff, 0x3f, 0x00, 0x00, 0xff, 0x00, /* ...?.... */ +0x13, 0x1a, 0x27, 0xd6, 0x97, 0x82, 0xdf, 0xbf, /* ..'..... */ +0x01, 0x6d, 0x2e, 0x6d, 0xbf, 0x74, 0xcf, 0x02, /* .m.m.t.. */ +0x1e, 0x04, 0x55, 0xa0, 0xcf, 0xcf, 0x1c, 0x10, /* ..U..... */ +0x18, 0xa0, 0xaf, 0x05, 0x50, 0x01, 0x1e, 0x04, /* ....P... */ +0x55, 0xa0, 0xcf, 0xcf, 0x1c, 0x20, 0x18, 0xa0, /* U.... .. */ +0xaf, 0xed, 0x80, 0xfb, 0x39, 0x08, 0x45, 0x00, /* ....9.E. */ +0x5a, 0xfb, 0x31, 0x0a, 0x42, 0x00, 0x5b, 0xa2, /* Z.1.B.[. */ +0x39, 0x02, 0xcf, 0x5c, 0xaf /* 9..\. */ +}; + +static const unsigned char pkt265[] = { +0x42, 0x96, 0x00, +0x1a, 0x2e, 0xe1, 0xef, 0x95, /* B....... */ +0xaf, 0x9f, 0x22, 0x61, 0xaf, 0x62, 0xaf, 0x69, /* .."a.b.i */ +0xaf, 0x6a, 0xaf, 0x16, 0xaf, 0x96, 0xaf, 0x29, /* .j.....) */ +0xaf, 0x28, 0xaf, 0xc1, 0x2e, 0x49, 0xdf, 0x3f, /* .(...I.? */ +0x2d, 0x03, 0x5b, 0xa0, 0xcf, 0x8f, 0x1c, 0x20, /* -.[.... */ +0x18, 0xa0, 0xaf, 0xa1, 0xcf, 0xdf, 0x1c, 0xa1, /* ........ */ +0xaf, 0xed, 0x80, 0x02, 0x47, 0x06, 0x5a, 0x0a, /* ....G.Z. */ +0x41, 0x04, 0x5a, 0x0a, 0xdf, 0x30, 0x1d, 0x30, /* A.Z..0.0 */ +0x1f, 0x00, 0x54, 0x01, 0xef, 0x44, 0xaf, 0x09, /* ..T..D.. */ +0xef, 0x60, 0xaf, 0xa7, 0xef, 0x40, 0xaf, 0x2d, /* .`...@.- */ +0xef, 0x41, 0xaf, 0x0a, 0x40, 0x06, 0x5a, 0x10, /* .A..@.Z. */ +0xcf, 0x27, 0xaf, 0xe2, 0x23, 0x6e, 0x23, 0x08, /* .'..#n#. */ +0xef, 0xe3, 0xaf, 0x6f, 0xaf, 0xe2, 0x23, 0x08, /* ...o..#. */ +0xef, 0xe3, 0xaf, 0x79, 0x82, 0x4d, 0xaf, 0xdf, /* ...y.M.. */ +0x96, 0x64, 0xdf, 0x8b, 0x82, 0x93, 0xbf, 0xdd, /* .d...... */ +0x97, 0x77, 0xff, 0x8b, 0x82, 0x94, 0xbf, 0x9e, /* .w...... */ +0x23, 0xe4, 0x23, 0x9f, 0x22, 0x6d, 0x2e, 0x6b, /* #.#."m.k */ +0xbf, 0x6d, 0x2e, 0x6a, 0xbf, 0x6d, 0x2e, 0x6c, /* .m.j.m.l */ +0xbf, 0xa5, 0xcf, 0xf3, 0x1c, 0xa5, 0xaf, 0x05, /* ........ */ +0x27 /* ' */ +}; + +static const unsigned char pkt267[] = { +0x42, 0x2c, 0x00, +0x64, 0x2e, 0xf9, 0x32, 0xf9, /* B,.d..2. */ +0x3a, 0xaf, 0xef, 0x00, 0xff, 0x1b, 0x27, 0xf6, /* :.....'. */ +0x97, 0xcf, 0xaf, 0x0f, 0xef, 0x06, 0xaf, 0xce, /* ........ */ +0x30, 0x0f, 0x27, 0x0f, 0x27, 0xfa, 0x97, 0xcf, /* 0.'.'... */ +0xaf, 0xce, 0x32, 0x06, 0x25, 0xf8, 0x55, 0xce, /* ..2.%.U. */ +0x43, 0xfd, 0x5b, 0xce, 0x31, 0x05, 0x27 /* C.[.1.' */ +}; + +static const unsigned char pkt269[] = { +0x42, 0x26, 0x00, +0x79, 0x2e, 0xbf, 0x22, 0xff, /* B&.y..". */ +0xef, 0x1b, 0x27, 0xdd, 0x97, 0xdd, 0x9f, 0x06, /* ..'..... */ +0xaf, 0x4e, 0xbf, 0xff, 0x22, 0x04, 0x54, 0xbd, /* .N..".T. */ +0x9d, 0x06, 0x25, 0xfc, 0x53, 0x4e, 0x25, 0xfa, /* ..%.SN%. */ +0x55, 0xbd, 0x9d, 0x06, 0x25, 0xfc, 0x55, 0x05, /* U...%.U. */ +0x27 /* ' */ +}; + +static const unsigned char pkt271[] = { +0x42, 0x3c, 0x00, +0x8b, 0x2e, 0xbf, 0x22, 0xff, /* B<....". */ +0xef, 0x1b, 0x27, 0xdc, 0x99, 0x28, 0x28, 0x28, /* ..'..((( */ +0x2a, 0x68, 0x2c, 0xfd, 0x5b, 0xa9, 0x9d, 0x6a, /* *h,.[..j */ +0x28, 0x06, 0x25, 0xf6, 0x53, 0x4e, 0x25, 0xf4, /* (.%.SN%. */ +0x55, 0xdc, 0x99, 0x28, 0x28, 0x28, 0x2a, 0x68, /* U..(((*h */ +0x2c, 0xfd, 0x5b, 0xa9, 0x9d, 0x6a, 0x28, 0x06, /* ,.[..j(. */ +0x25, 0xf6, 0x55, 0x01, 0x2e, 0xe4, 0x85, 0xbf, /* %.U..... */ +0x22, 0xbf, 0x99, 0x7f, 0x99, 0x05, 0x27 /* ".....' */ +}; + +static const unsigned char pkt273[] = { +0x67, 0x05, 0x00, 0x00, 0x02, 0x2e, 0x00, 0x70, /* g......p */ +0x67, 0x05, 0x00, 0x02, 0x02, 0x2e, 0x88, 0x70, /* g......p */ +0x67, 0x05, 0x00, 0x01, 0x02, 0x2e, 0x3c, 0x71, /* g..... Date: Sun, 25 Nov 2012 21:13:01 +0300 Subject: [PATCH 40/49] Update AUTHORS file https://bugs.freedesktop.org/show_bug.cgi?id=57426 --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 1cd2e51a..6ce0375d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,7 +4,7 @@ Copyright (C) 2006 Pavel Machek Copyright (C) 1999 Erik Walthinsen Copyright (C) 2004,2006 Thomas Vander Stichele Copyright (C) 2007 Cyrille Bagard -Copyright (C) 2007 Vasily Khoruzhick +Copyright (C) 2007-2008,2012 Vasily Khoruzhick Copyright (C) 2007 Jan-Michael Brummer Copyright (C) 2007 Anthony Bretaudeau Copyright (C) 2010 Hugo Grostabussiat From 2084724115fd470c2e5f446b25829636fa17e493 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 24 Nov 2012 16:05:58 +0300 Subject: [PATCH 41/49] upektc: add support for Eikon Touch 300 https://bugs.freedesktop.org/show_bug.cgi?id=45197 --- libfprint/drivers/upektc.c | 77 ++- libfprint/drivers/upektc.h | 1206 +++++++++++++++++++++++++++++++++++- 2 files changed, 1262 insertions(+), 21 deletions(-) diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index a254a140..271cffb7 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -28,13 +28,25 @@ #include "upektc.h" #include "driver_ids.h" -#define EP_IN (2 | LIBUSB_ENDPOINT_IN) -#define EP_OUT (3 | LIBUSB_ENDPOINT_OUT) +#define UPEKTC_EP_IN (2 | LIBUSB_ENDPOINT_IN) +#define UPEKTC_EP_OUT (3 | LIBUSB_ENDPOINT_OUT) +#define UPEKET_EP_IN (1 | LIBUSB_ENDPOINT_IN) +#define UPEKET_EP_OUT (2 | LIBUSB_ENDPOINT_OUT) #define BULK_TIMEOUT 4000 struct upektc_dev { gboolean deactivating; + const struct setup_cmd *setup_commands; + size_t setup_commands_len; + int ep_in; + int ep_out; int init_idx; + int sum_threshold; +}; + +enum upektc_driver_data { + UPEKTC_2015, + UPEKTC_3001, }; static void start_capture(struct fp_img_dev *dev); @@ -55,7 +67,7 @@ static void upektc_next_init_cmd(struct fpi_ssm *ssm) struct upektc_dev *upekdev = dev->priv; upekdev->init_idx += 1; - if (upekdev->init_idx == array_n_elements(setup_commands)) + if (upekdev->init_idx == upekdev->setup_commands_len) fpi_ssm_mark_completed(ssm); else fpi_ssm_jump_to_state(ssm, WRITE_INIT); @@ -69,7 +81,7 @@ static void write_init_cb(struct libusb_transfer *transfer) if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (transfer->length == transfer->actual_length)) { - if (setup_commands[upekdev->init_idx].response_len) + if (upekdev->setup_commands[upekdev->init_idx].response_len) fpi_ssm_next_state(ssm); else upektc_next_init_cmd(ssm); @@ -105,8 +117,8 @@ static void activate_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, - (unsigned char*)setup_commands[upekdev->init_idx].cmd, + libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out, + (unsigned char*)upekdev->setup_commands[upekdev->init_idx].cmd, UPEKTC_CMD_LEN, write_init_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -125,9 +137,9 @@ static void activate_run_state(struct fpi_ssm *ssm) break; } - 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, + data = g_malloc(upekdev->setup_commands[upekdev->init_idx].response_len); + libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_in, data, + upekdev->setup_commands[upekdev->init_idx].response_len, read_init_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -155,7 +167,7 @@ static void activate_sm_complete(struct fpi_ssm *ssm) /****** FINGER PRESENCE DETECTION ******/ -static int finger_present(unsigned char *img, size_t len) +static int finger_present(unsigned char *img, size_t len, int sum_threshold) { int i, sum; @@ -168,12 +180,13 @@ static int finger_present(unsigned char *img, size_t len) } fp_dbg("finger_present: sum is %d\n", sum); - return sum < SUM_THRESHOLD ? 0 : 1; + return sum < sum_threshold ? 0 : 1; } static void finger_det_data_cb(struct libusb_transfer *transfer) { struct fp_img_dev *dev = transfer->user_data; + struct upektc_dev *upekdev = dev->priv; unsigned char *data = transfer->buffer; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -186,7 +199,7 @@ static void finger_det_data_cb(struct libusb_transfer *transfer) fpi_imgdev_session_error(dev, -EPROTO); } - if (finger_present(data, IMAGE_SIZE)) { + if (finger_present(data, IMAGE_SIZE, upekdev->sum_threshold)) { /* finger present, start capturing */ fpi_imgdev_report_finger_status(dev, TRUE); start_capture(dev); @@ -206,6 +219,7 @@ static void finger_det_cmd_cb(struct libusb_transfer *t) unsigned char *data; int r; struct fp_img_dev *dev = t->user_data; + struct upektc_dev *upekdev = dev->priv; if (t->status != LIBUSB_TRANSFER_COMPLETED) { fp_dbg("req transfer status %d\n", t->status); @@ -224,7 +238,7 @@ static void finger_det_cmd_cb(struct libusb_transfer *t) } data = g_malloc(IMAGE_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, IMAGE_SIZE, + libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_in, data, IMAGE_SIZE, finger_det_data_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -254,7 +268,7 @@ static void start_finger_detection(struct fp_img_dev *dev) fpi_imgdev_session_error(dev, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, + libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out, (unsigned char *)scan_cmd, UPEKTC_CMD_LEN, finger_det_cmd_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -315,6 +329,7 @@ out: static void capture_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) { @@ -325,7 +340,7 @@ static void capture_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, + libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out, (unsigned char *)scan_cmd, UPEKTC_CMD_LEN, capture_cmd_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -346,7 +361,7 @@ static void capture_run_state(struct fpi_ssm *ssm) } data = g_malloc(IMAGE_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, IMAGE_SIZE, + libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_in, data, IMAGE_SIZE, capture_read_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -422,6 +437,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { /* TODO check that device has endpoints we're using */ int r; + struct upektc_dev *upekdev; r = libusb_claim_interface(dev->udev, 0); if (r < 0) { @@ -429,7 +445,29 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) return r; } - dev->priv = g_malloc0(sizeof(struct upektc_dev)); + dev->priv = upekdev = g_malloc0(sizeof(struct upektc_dev)); + switch (driver_data) { + case UPEKTC_2015: + upekdev->ep_in = UPEKTC_EP_IN; + upekdev->ep_out = UPEKTC_EP_OUT; + upekdev->setup_commands = upektc_setup_commands; + upekdev->setup_commands_len = array_n_elements(upektc_setup_commands); + upekdev->sum_threshold = UPEKTC_SUM_THRESHOLD; + break; + case UPEKTC_3001: + upekdev->ep_in = UPEKET_EP_IN; + upekdev->ep_out = UPEKET_EP_OUT; + upekdev->setup_commands = upeket_setup_commands; + upekdev->setup_commands_len = array_n_elements(upeket_setup_commands); + upekdev->sum_threshold = UPEKET_SUM_THRESHOLD; + break; + default: + fp_err("Device variant %d is not known\n", driver_data); + g_free(upekdev); + dev->priv = NULL; + return -ENODEV; + break; + } fpi_imgdev_open_complete(dev, 0); return 0; } @@ -442,7 +480,8 @@ static void dev_deinit(struct fp_img_dev *dev) } static const struct usb_id id_table[] = { - { .vendor = 0x0483, .product = 0x2015 }, + { .vendor = 0x0483, .product = 0x2015, .driver_data = UPEKTC_2015 }, + { .vendor = 0x147e, .product = 0x3001, .driver_data = UPEKTC_3001 }, { 0, 0, 0, }, }; @@ -450,7 +489,7 @@ struct fp_img_driver upektc_driver = { .driver = { .id = UPEKTC_ID, .name = FP_COMPONENT, - .full_name = "UPEK TouchChip", + .full_name = "UPEK TouchChip/Eikon Touch 300", .id_table = id_table, .scan_type = FP_SCAN_TYPE_PRESS, }, diff --git a/libfprint/drivers/upektc.h b/libfprint/drivers/upektc.h index a1980184..143916e3 100644 --- a/libfprint/drivers/upektc.h +++ b/libfprint/drivers/upektc.h @@ -1,6 +1,8 @@ /* * UPEK TouchChip driver for libfprint + * * Copyright (C) 2012 Vasily Khoruzhick + * Copyright (C) 2012 Moganeshwaran Rajasegaran * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,14 +26,15 @@ #define IMAGE_WIDTH 208 #define IMAGE_HEIGHT 288 #define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT) -#define SUM_THRESHOLD 10000 +#define UPEKTC_SUM_THRESHOLD 10000 +#define UPEKET_SUM_THRESHOLD 5000 struct setup_cmd { unsigned char cmd[0x40]; int response_len; }; -static const struct setup_cmd setup_commands[] = { +static const struct setup_cmd upektc_setup_commands[] = { { .cmd = { 0x03, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x00, 0x01, @@ -723,6 +726,1205 @@ static const struct setup_cmd setup_commands[] = { } }; +static const struct setup_cmd upeket_setup_commands[] = { + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF3, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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 = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x98, 0xf1, 0x12, 0x00, + 0x03, 0xd4, 0xa9, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x14, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x84, 0xf1, 0x12, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x90, 0xf1, 0x12, 0x00, + 0xac, 0x0d, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xf7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0xf1, 0x12, 0x00, + 0x92, 0xc5, 0xa9, 0x00, 0x48, 0xf1, 0x12, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xa2, 0xc5, 0xa9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x98, 0xf1, 0x12, 0x00, + 0x03, 0xd4, 0xa9, 0x00, 0x64, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xf7, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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 = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xf8, 0xa9, 0x00, + 0x28, 0xf1, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xbb, 0xc4, 0xa9, 0x00, 0x02, 0xfa, 0x3f, 0x05, + 0x05, 0x02, 0x05, 0x23, 0x27, 0xe5, 0x13, 0x10, + 0x08, 0xff, 0x04, 0x6c, 0xc1, 0x41, 0x1c, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xf1, 0x12, 0x00, 0x89, 0xae, 0xa9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8b, 0x00, 0x00, 0x00, 0x3a, 0x8c, 0xf1, 0x12, + 0x00, 0x64, 0xa8, 0xa7, 0x00, 0x84, 0xf1, 0x12, + 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xf1, 0x12, + 0x00, 0x51, 0xa6, 0xa7, 0x00, 0xf8, 0x00, 0x00, + 0x00, 0x7e, 0xa6, 0xa7, 0x00, 0x24, 0x5a, 0xac, + 0x00, 0x01, 0xf1, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2f, 0x00, 0x00, 0x00, 0x08, 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, 0x7c, + }, + .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, 0x00, + 0x34, 0xf1, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf1, 0x12, 0x00, 0x57, 0xcc, 0xa9, 0x00, + 0x34, 0xf1, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xbd, 0xcc, 0xa9, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, + 0x34, 0xf1, 0x12, 0x00, 0x3a, 0x00, 0x00, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x0a, 0x37, 0x6a, 0x3d, + 0x73, 0x3d, 0x71, 0x0e, 0x01, 0x0e, 0x81, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x12, 0x00, + 0x57, 0xcc, 0xa9, 0x00, 0x34, 0xf1, 0x12, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xbd, 0xcc, 0xa9, 0x00, + 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x34, 0xf1, 0x12, 0x00, + }, + .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, 0x3d, 0x51, 0x0e, + 0x01, 0x0e, 0x81, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf1, 0x12, 0x00, 0x57, 0xcc, 0xa9, 0x00, + 0x34, 0xf1, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xbd, 0xcc, 0xa9, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, + 0x34, 0xf1, 0x12, 0x00, 0x3a, 0x00, 0x00, 0x00, + }, + .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, 0x04, 0x78, 0x3A, 0x34, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x24, 0x1A, 0x80, + 0x7C, 0x04, 0xF1, 0x12, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0xCC, 0xEF, 0x12, + 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xB0, 0xEF, 0x12, 0x00, 0x0C, 0x00, 0x0C, + 0x00, 0x84, 0x21, 0x15, 0x00, 0x48, 0x00, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x04, 0xB2, 0x3A, 0x0B, 0x88, 0x01, + 0xB4, 0x01, 0x20, 0x91, 0x04, 0x07, 0x02, 0x24, + 0x20, 0xE2, 0x15, 0x0D, 0x10, 0x0F, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, + 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, + 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x04, 0xEC, 0x3A, 0x0B, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, + 0x1E, 0x1D, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1F, 0x1F, 0x20, + 0x20, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x20, 0x21, + 0x20, 0x21, 0x20, 0x20, 0x20, 0x21, 0x20, 0x21, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, + 0x21, 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0x26, 0x3A, 0x0B, 0x22, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x21, 0x22, 0x21, 0x22, 0x21, 0x21, 0x21, + 0x22, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x20, 0x20, 0x21, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0x60, 0x3A, 0x0B, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1D, 0x1D, + 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1B, 0x1B, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0x9A, 0x3A, 0x0B, 0x1B, 0x1B, + 0x1B, 0x1A, 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1A, 0x19, 0x1A, 0x1A, 0x1A, + 0x1A, 0x19, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19, + 0x19, 0x19, 0x19, 0x18, 0x19, 0x18, 0x18, 0x19, + 0x18, 0x17, 0x18, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x16, 0x17, 0x16, 0x16, 0x15, + 0x15, 0x16, 0x15, 0x16, 0x15, 0x15, 0x14, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0xD4, 0x2C, 0x0B, 0x14, 0x15, + 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6E, 0x12, 0x00, 0x2B, 0xC5, 0xA9, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x7C, 0xEF, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x01, 0x68, 0x0A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xD0, 0xFD, 0x7F, 0xDC, 0x6D, 0x12, 0x00, + 0x2A, 0x26, 0x80, 0x7C, 0x98, 0x6D, 0x12, 0x00, + 0x00, 0x26, 0x80, 0x7C, 0xB8, 0x00, 0x00, 0x00, + 0x0C, 0x80, 0x01, 0x10, 0x90, 0x3E, 0x94, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x03, 0xB4, 0x3A, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1D, + 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x03, 0xEE, 0x06, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x85, 0xB7, 0xA9, 0x00, + 0xB8, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x18, 0x70, 0x12, 0x00, 0x2B, 0xC5, 0xA9, 0x00, + 0x64, 0x00, 0x00, 0x00, 0xD4, 0xF0, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x07, 0x00, 0x20, 0x00, 0x3a, 0x32, 0x2b, 0x07, + 0x2e, 0x29, 0x07, 0x2b, 0x27, 0x07, 0x27, 0x25, + 0x07, 0x23, 0x23, 0x07, 0x20, 0x21, 0x07, 0x1c, + 0x1d, 0x07, 0x19, 0x1a, 0x07, 0x15, 0x17, 0x07, + 0x12, 0x15, 0x07, 0x0e, 0x14, 0x07, 0x12, 0x17, + 0x07, 0x15, 0x19, 0x07, 0x19, 0x1c, 0x07, 0x1c, + 0x1f, 0x07, 0x20, 0x23, 0x07, 0x23, 0x25, 0x07, + 0x27, 0x27, 0x07, 0x2b, 0x29, 0x07, 0x2e, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x07, 0x00, 0x20, 0x3a, 0x26, 0x2b, 0x07, 0x32, + 0x2d, 0x07, 0x32, 0x2f, 0x07, 0x2e, 0x2d, 0x07, + 0x2b, 0x2b, 0x07, 0x27, 0x29, 0x07, 0x23, 0x27, + 0x07, 0x20, 0x25, 0x07, 0x1c, 0x22, 0x07, 0x19, + 0x1e, 0x07, 0x15, 0x1b, 0x07, 0x12, 0x19, 0x07, + 0x0e, 0x16, 0x07, 0x07, 0x19, 0x1c, 0x07, 0x1c, + 0x1f, 0x07, 0x20, 0x23, 0x07, 0x23, 0x25, 0x07, + 0x27, 0x27, 0x07, 0x2b, 0x29, 0x07, 0x2e, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x81, 0x0e, + 0x81, 0x09, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0x20, 0x3a, + 0x26, 0x2b, 0x07, 0x32, 0x2d, 0x07, 0x32, 0x2f, + 0x07, 0x2e, 0x2d, 0x07, 0x2b, 0x2b, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + 0x1c, 0x22, 0x07, 0x19, 0x1e, 0x07, 0x15, 0x1b, + 0x07, 0x12, 0x19, 0x07, 0x0e, 0x16, 0x07, 0x07, + }, + .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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x20, 0x3a, 0x26, 0x2b, 0x07, 0x32, + 0x2d, 0x07, 0x32, 0x2f, 0x07, 0x2e, 0x2d, 0x07, + 0x2b, 0x2b, 0x07, 0x29, 0x07, 0x23, 0x27, 0x07, + 0x20, 0x25, 0x07, 0x1c, 0x22, 0x07, 0x19, 0x1e, + 0x07, 0x15, 0x1b, 0x07, 0x12, 0x19, 0x07, 0x1f, + 0x0e, 0x16, 0x07, 0x07, 0x19, 0x1c, 0x07, 0x1c, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x62, 0x62, + 0x51, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x3a, 0x41, 0x0e, 0x2b, 0x00, 0x00, 0x00, 0x00, + 0x78, 0xf1, 0x12, 0x00, 0x1a, 0xaa, 0xa7, 0x1f, + 0x00, 0x3a, 0x09, 0x00, 0x00, 0x00, 0x12, 0x41, + 0x0e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4c, 0xf1, 0x12, 0x00, 0x89, 0xae, + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0x20, 0x6C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x20, 0x3A, 0x26, 0x2B, 0x07, 0x32, + 0x2D, 0x07, 0x32, 0x2F, 0x07, 0x2E, 0x2D, 0x07, + 0x2B, 0x2B, 0x07, 0x27, 0x29, 0x07, 0x23, 0x27, + 0x07, 0x20, 0x25, 0x07, 0x1C, 0x22, 0x07, 0x19, + 0x1E, 0x07, 0x15, 0x1B, 0x07, 0x12, 0x19, 0x07, + 0x0E, 0x16, 0x07, 0x07, 0x19, 0x1C, 0x07, 0x1C, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF9, 0x6C, 0x6C, + 0x6C, 0x6C, 0x40, 0x40, 0x2E, 0x6D, 0x64, 0xED, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0xF1, 0x12, 0x00, 0x89, 0xAE, 0xA9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE8, 0x3D, 0xAC, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0xF1, 0x12, 0x00, + 0x14, 0xAB, 0xA7, 0x00, 0x03, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF9, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0x20, 0x3A, + 0x26, 0x2B, 0x07, 0x32, 0x2D, 0x07, 0x32, 0x2F, + 0x07, 0x2E, 0x2D, 0x07, 0x2B, 0x2B, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + 0x1C, 0x22, 0x07, 0x19, 0x1E, 0x07, 0x15, 0x1B, + 0x07, 0x12, 0x19, 0x07, 0x0E, 0x16, 0x07, 0x07, + 0x19, 0x1C, 0x07, 0x1C, 0xBA, 0xEC, 0x64, 0xED, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x16, 0x1C, 0x13, 0x1B, + 0x0B, 0x1A, 0x0A, 0x30, 0x08, 0x09, 0x6D, 0x08, + 0xA7, 0x00, 0x9E, 0x00, 0x1E, 0x0C, 0x08, 0x1D, + 0x04, 0x23, 0x42, 0x2F, 0x07, 0x2E, 0x2D, 0x07, + 0x2B, 0x2B, 0x07, 0x27, 0x29, 0x07, 0x23, 0x27, + 0x07, 0x20, 0x25, 0x07, 0x1C, 0x22, 0x07, 0x19, + 0x1E, 0x07, 0x15, 0x1B, 0x07, 0x12, 0x19, 0x07, + 0x0E, 0x16, 0x07, 0x07, 0x19, 0x1C, 0x07, 0x1C, + }, + .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, 0x30, + 0x08, 0x09, 0x6D, 0x08, 0xA7, 0x00, 0x9E, 0x00, + 0x1E, 0x0C, 0x08, 0x1D, 0x04, 0x23, 0x42, 0x2F, + 0x07, 0x2E, 0x2D, 0x07, 0x2B, 0x2B, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + 0x1C, 0x22, 0x07, 0x19, 0x1E, 0x07, 0x15, 0x1B, + 0x07, 0x12, 0x19, 0x07, 0x0E, 0x16, 0x07, 0x07, + 0x19, 0x1C, 0x07, 0x1C, 0xBA, 0xEC, 0x64, 0xED, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF7, 0x64, 0xED, + 0x00, 0x00, 0x00, 0x00, 0x7C, 0xF1, 0x12, 0x00, + 0x1A, 0xAA, 0xA7, 0x00, 0x3A, 0x00, 0x00, 0x00, + 0x2A, 0x6D, 0x64, 0xED, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0xF1, 0x12, 0x00, + 0x89, 0xAE, 0xA9, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x3D, 0xAC, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF7, 0xA9, 0x00, + 0x02, 0xFA, 0x3F, 0x05, 0x05, 0xC2, 0x85, 0xA6, + 0xA7, 0x6D, 0x10, 0x10, 0x08, 0xFF, 0x85, 0x6C, + 0x00, 0x00, 0xCF, 0x00, 0x01, 0x00, 0x00, 0x1F, + 0x01, 0x01, 0x0A, 0x0B, 0x13, 0x04, 0x6C, 0x6C, + 0x6C, 0x6C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, + 0x42, 0x42, 0x42, 0x42, 0x6C, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF7, 0xF3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x0D, 0xFF, 0x30, + 0x08, 0x09, 0x6D, 0x08, 0xA7, 0x00, 0x9E, 0x00, + 0x1E, 0x0C, 0x08, 0x1D, 0x04, 0x23, 0x42, 0x2F, + 0x07, 0x2E, 0x2D, 0x07, 0x2B, 0x2B, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + 0x1C, 0x22, 0x07, 0x19, 0x1E, 0x07, 0x15, 0x1B, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x3D, 0xAC, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5C, 0xF1, 0x12, 0x00, 0x14, 0xAB, 0xA7, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x5C, 0xF1, 0x12, 0x00, + 0x20, 0xAB, 0xA7, 0x00, 0x58, 0xF1, 0x12, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x99, 0xA9, 0xA7, 0x00, + 0xE8, 0x3D, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF0, 0x8F, 0x2F, + 0x07, 0x2E, 0x2D, 0x07, 0x2B, 0x2B, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + 0x1C, 0x22, 0x07, 0x19, 0x1E, 0x07, 0x15, 0x1B, + 0x07, 0x12, 0x19, 0x07, 0x82, 0xEC, 0x64, 0xED, + 0x24, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x3D, 0xAC, 0x00, 0xBD, 0xCC, 0xA9, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x08, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0xCF, + 0x00, 0x01, 0x00, 0x00, 0x1F, 0x01, 0x01, 0x00, + 0x0C, 0xCF, 0xA9, 0x00, 0x74, 0x70, 0x12, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x1C, 0xCF, 0xA9, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF0, 0x8F, 0x2F, + 0x07, 0x2E, 0x2D, 0x07, 0x2B, 0x2B, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x06, 0x0E, 0x85, 0x09, + 0xED, 0x09, 0x6D, 0x2F, 0x07, 0x2E, 0x2D, 0x07, + 0x2B, 0x2B, 0x07, 0x27, 0x29, 0x07, 0x23, 0x27, + 0x07, 0x20, 0x25, 0x07, 0x1C, 0x22, 0x07, 0x19, + 0x8A, 0xEC, 0x64, 0xED, 0x1C, 0xF1, 0x12, 0x00, + 0xFA, 0xCB, 0xA9, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x72, 0xF1, 0x12, 0x00, + 0xBD, 0xCC, 0xA9, 0x00, 0x0A, 0x00, 0x00, 0x00, + }, + .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, 0x09, 0xED, 0x2F, + 0x07, 0x2E, 0x2D, 0x07, 0x2B, 0x2B, 0x07, 0x27, + 0x29, 0x07, 0x23, 0x27, 0x07, 0x20, 0x25, 0x07, + 0x1C, 0x22, 0x07, 0x19, 0x8A, 0xEC, 0x64, 0xED, + 0x1C, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0xF1, 0x12, 0x00, 0xBD, 0xCC, 0xA9, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0xBD, 0xCC, 0xA9, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF3, 0x00, 0x00, + 0x8C, 0xF1, 0x12, 0x00, 0x1A, 0xAA, 0xA7, 0x00, + 0x3A, 0x00, 0x00, 0x00, 0x5A, 0x6D, 0x64, 0xED, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xF1, 0x12, 0x00, 0x89, 0xAE, 0xA9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE8, 0x3D, 0xAC, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7C, 0xF1, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x84, 0x00, 0x00, 0x00, 0x32, 0x02, 0xE0, 0xAD, + 0x00, 0xFC, 0xDF, 0xAD, 0x00, 0xDB, 0xDF, 0xAD, + 0x00, 0xBA, 0xDF, 0xAD, 0x00, 0x99, 0xDF, 0x6F, + 0x44, 0xC2, 0xE8, 0x20, 0x65, 0x73, 0x83, 0xAC, + 0xD7, 0x88, 0x6D, 0x59, 0x61, 0xE0, 0x3B, 0x3D, + 0xB7, 0xF4, 0xDE, 0xAD, 0x00, 0xD3, 0xDE, 0xAD, + 0x00, 0xB2, 0xDE, 0xAD, 0x00, 0x91, 0xDE, 0x00, + 0xA6, 0xEC, 0x64, 0xED, 0xA2, 0xEC, 0x64, 0xED, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x06, 0x1A, 0x0A, 0x1B, + 0x0B, 0x1C, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x92, 0xD5, 0x90, 0x7C, 0xBB, 0x9B, 0x80, 0x7C, + 0xB8, 0x00, 0x00, 0x00, 0xAC, 0x70, 0x12, 0x00, + 0x85, 0xB7, 0xA9, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x08, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0xCF, + 0x00, 0x01, 0x00, 0x00, 0x1F, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, + 0x4C, 0x70, 0x12, 0x00, 0xEB, 0xC4, 0xA9, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x68, 0x70, 0x12, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xE8, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB0, 0x70, 0x12, 0x00, + 0x0C, 0xCF, 0xA9, 0x00, 0x68, 0x70, 0x12, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0x0D, 0x00, 0x00, + 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, + 0xD0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xA6, 0xB5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x28, 0x6F, 0x44, 0xC2, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x04, 0x78, 0x3A, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xD0, 0xFD, 0x7F, 0x94, 0xF0, 0x12, + 0x00, 0x2A, 0x26, 0x80, 0x7C, 0x50, 0xF0, 0x12, + 0x00, 0x00, 0x26, 0x80, 0x7C, 0x08, 0x00, 0x00, + 0x00, 0x0C, 0x80, 0x01, 0x10, 0x90, 0x3E, 0x94, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x69, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x04, 0xB2, 0x3A, 0x0B, 0x88, 0x01, + 0xB4, 0x01, 0x20, 0x91, 0x04, 0x07, 0x02, 0x24, + 0x20, 0xE2, 0x15, 0x0D, 0x10, 0x0F, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, + 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, + 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x04, 0xEC, 0x3A, 0x0B, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, + 0x1E, 0x1D, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1F, 0x1F, 0x20, + 0x20, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x20, 0x21, + 0x20, 0x21, 0x20, 0x20, 0x20, 0x21, 0x20, 0x21, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, + 0x21, 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0x26, 0x3A, 0x0B, 0x22, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x21, 0x22, 0x21, 0x22, 0x21, 0x21, 0x21, + 0x22, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x20, 0x20, 0x21, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0x60, 0x3A, 0x0B, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1D, 0x1D, + 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1B, 0x1B, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0x9A, 0x3A, 0x0B, 0x1B, 0x1B, + 0x1B, 0x1A, 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1A, 0x19, 0x1A, 0x1A, 0x1A, + 0x1A, 0x19, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19, + 0x19, 0x19, 0x19, 0x18, 0x19, 0x18, 0x18, 0x19, + 0x18, 0x17, 0x18, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x16, 0x17, 0x16, 0x16, 0x15, + 0x15, 0x16, 0x15, 0x16, 0x15, 0x15, 0x14, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x05, 0xD4, 0x2C, 0x0B, 0x14, 0x15, + 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6F, 0x12, 0x00, 0x2B, 0xC5, 0xA9, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x2C, 0xF0, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF7, 0x1C, 0x1C, + 0x1B, 0x1B, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1A, 0x1B, 0x1B, 0x1A, 0x1A, + 0x1A, 0x1B, 0x1B, 0x1B, 0x1B, 0x1A, 0x19, 0x1A, + 0x1A, 0x1A, 0x1A, 0x19, 0x1A, 0x1A, 0x1A, 0x19, + 0x19, 0x19, 0x19, 0x19, 0x19, 0x18, 0x19, 0x18, + 0x18, 0x19, 0x18, 0x17, 0x18, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x17, 0x16, 0x17, 0x16, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF7, 0xF3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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 = { + 0x03, 0x00, 0x00, 0x00, 0x04, 0x3D, 0x40, 0x0A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x52, 0xED, 0x64, 0xED, + 0xD4, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + }, + .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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x52, 0xED, 0x64, 0xED, 0xD4, 0xF1, 0x12, 0x00, + 0xFA, 0xCB, 0xA9, 0x00, 0x03, 0x00, 0x00, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x8B, 0x00, 0x00, 0xA8, 0x3A, 0x00, 0x00, 0x00, + 0x00, 0xDC, 0x00, 0xEA, 0x00, 0x20, 0xED, 0x12, + 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0xDC, 0xFD, + 0x7F, 0x20, 0xED, 0x12, 0x00, 0x05, 0x00, 0x00, + 0x00, 0xA0, 0x20, 0x15, 0x00, 0xC8, 0x00, 0x00, + 0x01, 0x43, 0x00, 0x3A, 0x00, 0x5C, 0x00, 0x44, + 0x00, 0x6F, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6D, + 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x00, 0xE2, 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, 0x1C, 0x3A, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x75, 0xB3, 0x05, + 0xE2, 0xBC, 0x74, 0x68, 0xAD, 0xAC, 0x7B, 0xB1, + 0xF8, 0x52, 0xD5, 0x8F, 0xF7, 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, 0x56, 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, 0x90, 0x3A, 0x0B, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xA5, 0x00, 0x22, 0x8E, 0xA3, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0xA5, 0xC8, 0xC8, 0x41, 0x50, 0x52, 0x39, + 0x07, 0x01, 0x00, 0x5F, 0x00, 0x00, 0xFF, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x01, 0xCA, 0x3A, 0x0B, 0x01, 0x48, + 0x34, 0x33, 0x00, 0x00, 0x00, 0x00, 0x76, 0x3E, + 0x84, 0x10, 0x2E, 0x48, 0x54, 0x0D, 0x98, 0x4C, + 0x14, 0x12, 0x72, 0x7A, 0x88, 0x0F, 0x9F, 0x84, + 0x98, 0x03, 0x52, 0xA6, 0xA4, 0x0A, 0x6E, 0xA8, + 0x54, 0x0C, 0x13, 0xB6, 0xE8, 0x0A, 0x77, 0xC0, + 0x94, 0x04, 0x73, 0xC6, 0x14, 0x07, 0x80, 0xCA, + 0xA8, 0x08, 0x31, 0xD2, 0x44, 0x09, 0x1E, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x02, 0x04, 0x3A, 0x0B, 0x74, 0x09, + 0x7A, 0xE4, 0x78, 0x17, 0xA5, 0xE4, 0x24, 0x09, + 0x45, 0xE8, 0x68, 0x07, 0xBA, 0xEC, 0xE8, 0x05, + 0xC2, 0xF0, 0x58, 0x16, 0x78, 0xF6, 0x98, 0x15, + 0x7C, 0xFC, 0xB8, 0x19, 0xAD, 0xFC, 0x74, 0x09, + 0x8C, 0x02, 0x39, 0x0D, 0x36, 0x06, 0x99, 0x06, + 0x9B, 0x08, 0x09, 0x0B, 0xA1, 0x0C, 0x25, 0x19, + 0x57, 0x10, 0x29, 0x05, 0x1A, 0x1C, 0x45, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x02, 0x3E, 0x3A, 0x0B, 0x55, 0x1E, + 0x69, 0x16, 0xA4, 0x24, 0xB9, 0x09, 0x1C, 0x44, + 0x55, 0x08, 0x9C, 0x44, 0xC9, 0x0B, 0x9F, 0x4A, + 0xF9, 0x19, 0x4C, 0x4C, 0xF9, 0x13, 0x5E, 0x50, + 0x09, 0x13, 0xB7, 0x6A, 0x09, 0x0A, 0x7C, 0x7A, + 0x75, 0x0F, 0x0E, 0x7E, 0x95, 0x00, 0x81, 0xA6, + 0x99, 0x0E, 0xC0, 0xAE, 0xE5, 0x19, 0xA0, 0xCC, + 0x35, 0x0D, 0x63, 0xE2, 0x85, 0x1F, 0x8E, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x02, 0x78, 0x3A, 0x0B, 0x35, 0x1D, + 0xC1, 0xE8, 0xA9, 0x0C, 0x7A, 0x06, 0xCA, 0x0E, + 0xAD, 0x12, 0xD6, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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, 0xB2, 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, + 0x40, 0x6C, 0x12, 0x00, 0x2B, 0xC5, 0xA9, 0x00, + 0x64, 0x00, 0x00, 0x00, 0xFC, 0xEC, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF1, 0x42, 0x42, + 0x40, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0xCE, 0x6D, 0x64, 0xED, 0x00, 0x00, 0x00, 0x00, + 0x30, 0xF2, 0x12, 0x00, 0x1A, 0xAA, 0xA7, 0x00, + 0x3A, 0x00, 0x00, 0x00, 0xF6, 0x6D, 0x64, 0xED, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xF2, 0x12, 0x00, 0x89, 0xAE, 0xA9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF1, 0x01, 0x00, + 0x1C, 0xCF, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 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, 0x00, 0xFC, 0x3A, 0x1E, 0xDC, 0x74, + 0x09, 0x7A, 0xE4, 0x78, 0x17, 0xA5, 0xE4, 0x24, + 0x09, 0x45, 0xE8, 0x68, 0x07, 0xBA, 0xEC, 0xE8, + 0x05, 0xC2, 0xF0, 0x58, 0x16, 0x78, 0xF6, 0x98, + 0x15, 0x7C, 0xFC, 0xB8, 0x19, 0xAD, 0xFC, 0x74, + 0x09, 0x8C, 0x02, 0x39, 0x0D, 0x36, 0x06, 0x99, + 0x06, 0x9B, 0x08, 0x09, 0x0B, 0xA1, 0x0C, 0x25, + 0x19, 0x57, 0x10, 0x29, 0x05, 0x1A, 0x1C, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x8B, 0x00, 0x01, 0x36, 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, 0x2B, 0xC5, 0xA9, 0x00, + 0x64, 0x00, 0x00, 0x00, 0xD8, 0xEE, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF0, 0xAC, 0x00, + 0xF0, 0xF1, 0x12, 0x00, 0x6A, 0xB1, 0xA7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0xA5, 0x00, 0x01, + 0x00, 0x00, 0x12, 0x00, 0x14, 0xAB, 0xA7, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0C, 0xF2, 0x12, 0x00, + 0x20, 0xAB, 0xA7, 0x00, 0x08, 0xF2, 0x12, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x99, 0xA9, 0xA7, 0x00, + 0xE8, 0x3D, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF0, 0x8F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x52, 0xED, 0x64, 0xED, + 0xD4, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x3D, 0xAC, 0x00, 0xBD, 0xCC, 0xA9, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF7, 0x12, 0x00, + 0x88, 0xC4, 0xA9, 0x00, 0xD8, 0xF1, 0x12, 0x00, + 0x40, 0x00, 0x00, 0x00, 0xBB, 0xC4, 0xA9, 0x00, + 0x02, 0x00, 0x3F, 0x05, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEA, 0x6D, 0x64, 0xED, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xF2, 0x12, 0x00, + 0x89, 0xAE, 0xA9, 0x00, 0x03, 0x00, 0x00, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xF7, 0xA9, 0x00, + 0x02, 0xFA, 0x3F, 0x05, 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, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF7, 0xF3, 0x00, + 0x0C, 0xCF, 0xA9, 0x00, 0x24, 0x71, 0x12, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x1C, 0xCF, 0xA9, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF0, 0x8F, 0x00, + 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 = { + 0x82, 0x00, 0x00, 0x00, 0x01, 0xFB, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF1, 0x12, 0x00, + 0x89, 0xAE, 0xA9, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE8, 0x3D, 0xAC, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0xF2, 0x12, 0x00, 0x14, 0xAB, 0xA7, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0C, 0xF2, 0x12, 0x00, + 0x20, 0xAB, 0xA7, 0x00, 0x08, 0xF2, 0x12, 0x00, + }, + .response_len = 0x40 + }, + { + .cmd = { + 0x03, 0x00, 0x00, 0x00, 0x02, 0xFB, 0x0F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0xF0, 0x8F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x52, 0xED, 0x64, 0xED, + 0xD4, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + }, + .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, 0x07, 0xA4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x52, 0xED, 0x64, 0xED, + 0xD4, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x42, 0xED, 0x64, 0xED, + 0xE4, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + }, + .response_len = 0x00 + }, + { + .cmd = { + 0x08, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0xCF, + 0x00, 0x01, 0x00, 0x00, 0x1F, 0x01, 0x01, 0x00, + 0xEB, 0xC4, 0xA9, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x24, 0x71, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, + 0xE8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6C, 0x71, 0x12, 0x00, 0x0C, 0xCF, 0xA9, 0x00, + 0x24, 0x71, 0x12, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x1C, 0xCF, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .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 = { + 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, 0x00, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x36, 0xED, 0x64, 0xED, + 0xB0, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF2, 0x12, 0x00, 0xBD, 0xCC, 0xA9, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x52, 0xED, 0x64, 0xED, 0xFC, 0xF1, 0x12, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x06, 0xF2, 0x12, 0x00, + }, + .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 = { + 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, 0x00, 0x20, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x36, 0xED, 0x64, 0xED, + 0xB0, 0xF1, 0x12, 0x00, 0xFA, 0xCB, 0xA9, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0xF2, 0x12, 0x00, 0xBD, 0xCC, 0xA9, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x52, 0xED, 0x64, 0xED, 0xFC, 0xF1, 0x12, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x06, 0xF2, 0x12, 0x00, + }, + .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 + }, +}; + static const unsigned char scan_cmd[0x40] = { 0x0e, 0x00, 0x03, 0xa8, 0x00, 0xb6, 0xbb, 0xbb, 0xb8, 0xb7, 0xb8, 0xb5, 0xb8, 0xb9, 0xb8, 0xb9, From c02cb3083d90099f8993d2531ffa1ff357cfc963 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 29 Nov 2012 17:16:33 +0300 Subject: [PATCH 42/49] AES-drivers: drop redudant type cast in g_slist_free_full call https://bugs.freedesktop.org/show_bug.cgi?id=57688 --- libfprint/drivers/aes1610.c | 2 +- libfprint/drivers/aes2501.c | 2 +- libfprint/drivers/aes2550.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index c074137e..2e04c593 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -616,7 +616,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) aesdev->strips = g_slist_reverse(aesdev->strips); img = aes_assemble(aesdev->strips, aesdev->strips_len, FRAME_WIDTH, FRAME_HEIGHT); - g_slist_free_full(aesdev->strips, (GFunc) g_free); + g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; aesdev->blanks_count = 0; diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index ff03f174..75d19fcd 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -485,7 +485,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) aesdev->strips = g_slist_reverse(aesdev->strips); img = aes_assemble(aesdev->strips, aesdev->strips_len, FRAME_WIDTH, FRAME_HEIGHT); - g_slist_free_full(aesdev->strips, (GFunc) g_free); + g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; fpi_imgdev_image_captured(dev, img); diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 2ffe8529..96ce5900 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -252,7 +252,7 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) aesdev->strips = g_slist_reverse(aesdev->strips); img = aes_assemble(aesdev->strips, aesdev->strips_len, FRAME_WIDTH, FRAME_HEIGHT); - g_slist_free_full(aesdev->strips, (GFunc) g_free); + g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; fpi_imgdev_image_captured(dev, img); From f335256cbe9743e405851a001f494a72536e2471 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 30 Nov 2012 12:26:51 +0300 Subject: [PATCH 43/49] build: Don't build unneeded aesX660 routines When neither of the AES drivers are built, no need to build the common routines. https://bugs.freedesktop.org/show_bug.cgi?id=57724 --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 3c88fe8b..fdea8b68 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ all_drivers="upeke2 upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes16 require_imaging='no' require_aeslib='no' +require_aesX660='no' enable_upeke2='no' enable_upekts='no' enable_upektc='no' From 31cf7a93833f99f3eccc70c198538e975e732fac Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 30 Nov 2012 09:38:57 +0300 Subject: [PATCH 44/49] build: Add common routines to the dist Fixes dist when aesX660 drivers are disabled from the build. https://bugs.freedesktop.org/show_bug.cgi?id=57724 --- libfprint/Makefile.am | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index ed4f337e..7a167825 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -4,7 +4,7 @@ MOSTLYCLEANFILES = $(udev_rules_DATA) UPEKE2_SRC = drivers/upeke2.c UPEKTS_SRC = drivers/upekts.c -UPEKTC_SRC = drivers/upektc.c +UPEKTC_SRC = drivers/upektc.c drivers/upektc.h UPEKSONLY_SRC = drivers/upeksonly.c URU4000_SRC = drivers/uru4000.c AES1610_SRC = drivers/aes1610.c @@ -34,8 +34,10 @@ EXTRA_DIST = \ $(VCOM5S_SRC) \ $(VFS101_SRC) \ $(VFS301_SRC) \ + drivers/aesx660.c \ + drivers/aesx660.h \ + drivers/driver_ids.h \ aeslib.c aeslib.h \ - aesx660.c aesx660.h \ imagemagick.c \ gdkpixbuf.c \ 60-fprint-autosuspend.rules From 258ac2d4da1f7a3beecbeb257e85e19965f4fd58 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sat, 1 Dec 2012 15:10:13 +0100 Subject: [PATCH 45/49] build: Build all the drivers by default --- Makefile.am | 2 +- configure.ac | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index f14189d4..7084de87 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ endif DIST_SUBDIRS = libfprint doc examples -DISTCHECK_CONFIGURE_FLAGS = --with-drivers=upekts,upeke2,upeksonly,uru4000,vcom5s,aes2501,aes1610,aes4000,vfs101 --enable-examples-build --enable-x11-examples-build --with-udev-rules-dir='$${libdir}/udev/rules.d-distcheck' +DISTCHECK_CONFIGURE_FLAGS = --with-drivers=all --enable-examples-build --enable-x11-examples-build --with-udev-rules-dir='$${libdir}/udev/rules.d-distcheck' pkgconfigdir=$(libdir)/pkgconfig pkgconfig_DATA=libfprint.pc diff --git a/configure.ac b/configure.ac index fdea8b68..36553e4d 100644 --- a/configure.ac +++ b/configure.ac @@ -49,6 +49,10 @@ AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [drivers="$withval"], [drivers="$all_drivers"]) +if test x$drivers = xall ; then + drivers=$all_drivers +fi + for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do case ${driver} in upekts) From a7d6b7c30a7c8de7c1bd306d3766033e1f49397e Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 30 Nov 2012 15:17:32 +0300 Subject: [PATCH 46/49] nbis: Fix crash in gen_initial_maps() If the image is too small some coordinates can become negative. Handle this to avoid memory corruption. https://bugs.freedesktop.org/show_bug.cgi?id=57730 --- libfprint/nbis/mindtct/maps.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libfprint/nbis/mindtct/maps.c b/libfprint/nbis/mindtct/maps.c index 6f49e3c6..43929a4b 100644 --- a/libfprint/nbis/mindtct/maps.c +++ b/libfprint/nbis/mindtct/maps.c @@ -307,6 +307,10 @@ int gen_initial_maps(int **odmap, int **olcmap, int **olfmap, xmaxlimit = pw - dftgrids->pad - lfsparms->windowsize - 1; ymaxlimit = ph - dftgrids->pad - lfsparms->windowsize - 1; + /* max limits should not be negative */ + xmaxlimit = MAX(xmaxlimit, 0); + ymaxlimit = MAX(ymaxlimit, 0); + /* Foreach block in image ... */ for(bi = 0; bi < bsize; bi++){ /* Adjust block offset from pointing to block origin to pointing */ From 7892c943e68478b9ef4efaa83b5795ce1d45311d Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 3 Dec 2012 16:18:07 +0100 Subject: [PATCH 47/49] build: Create .tar.xz distribution by default --- Makefile.am | 1 - configure.ac | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7084de87..74f0971d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,3 @@ -AUTOMAKE_OPTIONS = dist-bzip2 ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = THANKS TODO HACKING libfprint.pc.in DISTCLEANFILES = ChangeLog libfprint.pc diff --git a/configure.ac b/configure.ac index 36553e4d..4415e7bf 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_INIT([libfprint], [0.4.0]) -AM_INIT_AUTOMAKE([1.11 dist-bzip2 no-dist-gzip check-news]) +AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz check-news]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([libfprint/core.c]) AM_CONFIG_HEADER([config.h]) From 29cf86a02e8cef9363fd247f40c17710a88bd57e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 3 Dec 2012 16:22:33 +0100 Subject: [PATCH 48/49] build: Fix configure-time warning Due to missing quotes --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4415e7bf..56b42b65 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,7 @@ AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [drivers="$withval"], [drivers="$all_drivers"]) -if test x$drivers = xall ; then +if test "x$drivers" = "xall" ; then drivers=$all_drivers fi From a5ec0b30e18275a4fae632c9382d01d5493d5dc6 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 3 Dec 2012 16:16:41 +0100 Subject: [PATCH 49/49] 0.5.0 --- NEWS | 25 +++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b8335a4a..fc99c1a5 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,31 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2012-12-03: v0.5.0 release + +* Drivers: + - New VFS300/VFS301 driver + - New AES2550/AES2810 drivers + - New AES1660 driver + - New AES2660 driver + - New DigitalPersona URU4500 driver + - Avoid empty capture and improve image contrast in the + AES2501 and AES2550 drivers + - Update upektc driver, add support for Eikon Touch 300 + - Fix UrU4000 image capture on ARM + +* Library: + - Fix global variable collisions with libusb and other system headers + - Fix possible crash in NBIS image processing with some fingerprints + +* Udev rules: + - Fix power control path for newer kernels + - Move udev rules to the correct directory + - Don't print duplicated udev rules + - Include udev rules in the tarball + - Allow disabling of udev rules for cross-compiling + - Add driver names in the generated rules + 2011-04-18: v0.4.0 release * Add support for Validity VFS101 (USB ID 138a:0001) * Fix crasher when resizing a fingerprint image diff --git a/configure.ac b/configure.ac index 56b42b65..3c779f40 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([libfprint], [0.4.0]) +AC_INIT([libfprint], [0.5.0]) AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz check-news]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([libfprint/core.c])