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 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. diff --git a/Makefile.am b/Makefile.am index aff8410c..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 @@ -9,6 +8,10 @@ if BUILD_EXAMPLES SUBDIRS += examples endif +DIST_SUBDIRS = libfprint doc examples + +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/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/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 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 diff --git a/configure.ac b/configure.ac index f5c26f90..3c779f40 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]) +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]) AM_CONFIG_HEADER([config.h]) @@ -23,10 +23,11 @@ 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 aes1660 aes2501 aes2550 aes2660 aes4000 vfs101 vfs301" require_imaging='no' require_aeslib='no' +require_aesX660='no' enable_upeke2='no' enable_upekts='no' enable_upektc='no' @@ -35,15 +36,23 @@ enable_vcom5s='no' enable_uru4000='no' enable_fdu2000='no' enable_aes1610='no' +enable_aes1660='no' enable_aes2501='no' +enable_aes2550='no' +enable_aes2660='no' enable_aes4000='no' enable_vfs101='no' +enable_vfs301='no' AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [List of drivers to enable])], [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) @@ -56,8 +65,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]) @@ -81,11 +89,28 @@ 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" enable_aes1610="yes" ;; + aes1660) + AC_DEFINE([ENABLE_AES1660], [], [Build AuthenTec AES1660 driver]) + require_aeslib="yes" + 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" @@ -96,21 +121,30 @@ 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 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"]) 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_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"]) 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]) @@ -129,6 +163,27 @@ 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], + [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]) if test "$gdkpixbuf_found" != "yes"; then @@ -171,17 +226,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 @@ -262,11 +317,26 @@ 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 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_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 @@ -277,11 +347,21 @@ 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 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/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; diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 656a2f43..7a167825 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -4,15 +4,19 @@ 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 +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 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) \ @@ -21,14 +25,22 @@ EXTRA_DIST = \ $(UPEKSONLY_SRC) \ $(URU4000_SRC) \ $(AES1610_SRC) \ + $(AES1660_SRC) \ $(AES2501_SRC) \ + $(AES2550_SRC) \ + $(AES2660_SRC) \ $(AES4000_SRC) \ $(FDU2000_SRC) \ $(VCOM5S_SRC) \ $(VFS101_SRC) \ + $(VFS301_SRC) \ + drivers/aesx660.c \ + drivers/aesx660.h \ + drivers/driver_ids.h \ aeslib.c aeslib.h \ imagemagick.c \ - gdkpixbuf.c + gdkpixbuf.c \ + 60-fprint-autosuspend.rules DRIVER_SRC = OTHER_SRC = @@ -79,10 +91,11 @@ 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/ +if ENABLE_UDEV_RULES $(udev_rules_DATA): fprint-list-udev-rules $(builddir)/fprint-list-udev-rules > $@ +endif if ENABLE_UPEKE2 DRIVER_SRC += $(UPEKE2_SRC) @@ -96,9 +109,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) @@ -116,10 +129,22 @@ if ENABLE_AES1610 DRIVER_SRC += $(AES1610_SRC) endif +if ENABLE_AES1660 +DRIVER_SRC += $(AES1660_SRC) +endif + if ENABLE_AES2501 DRIVER_SRC += $(AES2501_SRC) endif +if ENABLE_AES2550 +DRIVER_SRC += $(AES2550_SRC) +endif + +if ENABLE_AES2660 +DRIVER_SRC += $(AES2660_SRC) +endif + if ENABLE_AES4000 DRIVER_SRC += $(AES4000_SRC) endif @@ -128,6 +153,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) @@ -144,6 +173,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/aeslib.c b/libfprint/aeslib.c index da9be012..00ddfd91 100644 --- a/libfprint/aeslib.c +++ b/libfprint/aeslib.c @@ -20,6 +20,7 @@ #define FP_COMPONENT "aeslib" #include +#include #include #include @@ -164,10 +165,120 @@ 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++; } } } +/* 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/core.c b/libfprint/core.c index 401c491d..5315fdc7 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; @@ -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 @@ -368,13 +371,22 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_AES1610 &aes1610_driver, #endif +#ifdef ENABLE_AES1660 + &aes1660_driver, +#endif +#ifdef ENABLE_AES2660 + &aes2660_driver, +#endif #ifdef ENABLE_VFS101 &vfs101_driver, #endif -/*#ifdef ENABLE_UPEKTC +#ifdef ENABLE_VFS301 + &vfs301_driver, +#endif +#ifdef ENABLE_UPEKTC &upektc_driver, #endif -#ifdef ENABLE_FDU2000 +/*#ifdef ENABLE_FDU2000 &fdu2000_driver, #endif */ diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 8b81a80c..2e04c593 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. * @@ -32,6 +33,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); @@ -110,103 +113,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 +123,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) @@ -244,150 +148,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) -{ - 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 ******/ @@ -416,15 +176,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 +212,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; @@ -500,7 +245,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 +524,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 +559,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); @@ -826,17 +569,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++) @@ -876,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, 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); @@ -987,26 +727,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; @@ -1018,14 +741,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;*/ } } @@ -1106,7 +821,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/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/aes2501.c b/libfprint/drivers/aes2501.c index 617bb64f..75d19fcd 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-2008, 2012 Vasily Khoruzhick * * Based on code from http://home.gna.org/aes2501, relicensed with permission * @@ -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); @@ -67,6 +69,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, @@ -245,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[] = { @@ -514,13 +404,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 }, }; @@ -559,12 +449,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 +456,54 @@ 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 < 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); - /* 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) { + 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, 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); + } 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 +588,9 @@ static void start_capture(struct fp_img_dev *dev) return; } + 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; @@ -945,7 +859,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/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 */ diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c new file mode 100644 index 00000000..96ce5900 --- /dev/null +++ b/libfprint/drivers/aes2550.c @@ -0,0 +1,650 @@ +/* + * 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" +#include "driver_ids.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; + int heartbeat_cnt; +}; + +/****** 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; + struct aes2550_dev *aesdev = dev->priv; + + if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && + (transfer->length == transfer->actual_length)) { + 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, 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); + } 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; + struct aes2550_dev *aesdev = dev->priv; + 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; + } + 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 => 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: + 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; + } + + aesdev->heartbeat_cnt = 0; + ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + fp_dbg(""); + ssm->priv = dev; + fpi_ssm_start(ssm, capture_sm_complete); +} + +/****** 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 = AES2550_ID, + .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/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..... #include +#include "driver_ids.h" + #define CTRL_TIMEOUT 1000 #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) @@ -153,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); @@ -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/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 diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h new file mode 100644 index 00000000..0f45beb6 --- /dev/null +++ b/libfprint/drivers/driver_ids.h @@ -0,0 +1,41 @@ +/* + * 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, + AES1660_ID = 14, + AES2660_ID = 15, +}; + +#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 3a7c2d89..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 @@ -738,14 +740,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); @@ -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 6ca97067..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 @@ -467,7 +469,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 +479,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 +1019,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 +1180,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; @@ -1272,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 e115537f..271cffb7 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,400 +18,488 @@ * 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 -#define SENSOR_FULL_IMAGE 59904 -#define WAIT_COUNT 5 +#include "upektc.h" +#include "driver_ids.h" -typedef char sint8; -typedef unsigned char uint8; -typedef int sint32; -typedef unsigned int uint32; +#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 -/** 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; + const struct setup_cmd *setup_commands; + size_t setup_commands_len; + int ep_in; + int ep_out; + int init_idx; + int sum_threshold; }; -/** 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 +enum upektc_driver_data { + UPEKTC_2015, + UPEKTC_3001, }; -/** - * \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 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); - nRet = libusb_bulk_transfer(dev->udev, &msg1, &transferred, 1003); - if (transferred != 0x40) { - return -1; - } +/****** INITIALIZATION/DEINITIALIZATION ******/ - if ( !nLen ) { - return 0; - } +enum activate_states { + WRITE_INIT, + READ_DATA, + ACTIVATE_NUM_STATES, +}; - nRet = libusb_bulk_transfer(dev->udev, &msg2, &transferred, 1003); - if ( ( transferred == nLen ) && ( pnBuffer != NULL ) ) { - memcpy( pnBuffer, anBuf, nLen ); - return transferred; - } +static void upektc_next_init_cmd(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct upektc_dev *upekdev = dev->priv; - return nRet; + upekdev->init_idx += 1; + if (upekdev->init_idx == upekdev->setup_commands_len) + 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 (upekdev->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, 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) { + 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(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); + 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 sum_threshold) +{ + 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; + struct upektc_dev *upekdev = dev->priv; + 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, upekdev->sum_threshold)) { + /* 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; + struct upektc_dev *upekdev = dev->priv; + + 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, upekdev->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, upekdev->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; + struct upektc_dev *upekdev = dev->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, upekdev->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, upekdev->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; + struct upektc_dev *upekdev; - 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; -} - -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; + 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; } - - nResult = SetupSensor( dev ); - - return nResult; + fpi_imgdev_open_complete(dev, 0); + return 0; } -static void dev_exit( struct fp_img_dev *dev ) { +static void dev_deinit(struct fp_img_dev *dev) +{ + g_free(dev->priv); libusb_release_interface(dev->udev, 0); + fpi_imgdev_close_complete(dev); } static const struct usb_id id_table[] = { - { .vendor = 0x0483, .product = 0x2015 }, + { .vendor = 0x0483, .product = 0x2015, .driver_data = UPEKTC_2015 }, + { .vendor = 0x147e, .product = 0x3001, .driver_data = UPEKTC_3001 }, { 0, 0, 0, }, }; struct fp_img_driver upektc_driver = { .driver = { - .id = 5, + .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, }, - .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..143916e3 --- /dev/null +++ b/libfprint/drivers/upektc.h @@ -0,0 +1,1939 @@ +/* + * 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 + * 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 UPEKTC_SUM_THRESHOLD 10000 +#define UPEKET_SUM_THRESHOLD 5000 + +struct setup_cmd { + unsigned char cmd[0x40]; + int response_len; +}; + +static const struct setup_cmd upektc_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 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, + 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 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 0dbea965..541245a2 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 @@ -29,19 +30,21 @@ #include +#include "driver_ids.h" + #define EP_INTR (1 | LIBUSB_ENDPOINT_IN) #define EP_DATA (2 | LIBUSB_ENDPOINT_IN) #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 +54,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 +68,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 +85,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 +110,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 +122,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 +225,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 +248,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 +284,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 +319,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 +463,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 +491,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 +521,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 +545,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 +579,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 +857,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 +940,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 +954,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 +972,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 +982,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 +1034,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 +1052,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 +1082,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 +1101,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 +1109,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 +1137,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 *****/ @@ -1276,15 +1361,15 @@ 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", + .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/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 new file mode 100644 index 00000000..c0e36123 --- /dev/null +++ b/libfprint/drivers/vfs301.c @@ -0,0 +1,308 @@ +/* + * 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 + +#include "driver_ids.h" + +/************************** 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 = VFS301_ID, + .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 e6134d4d..04d304f4 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -28,15 +28,17 @@ #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) );}) 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 +55,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) \ @@ -158,7 +160,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 { @@ -253,9 +255,18 @@ 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 +#ifdef ENABLE_AES2550 +extern struct fp_img_driver aes2550_driver; +#endif +#ifdef ENABLE_AES2660 +extern struct fp_img_driver aes2660_driver; +#endif #ifdef ENABLE_AES4000 extern struct fp_img_driver aes4000_driver; #endif @@ -268,6 +279,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; @@ -325,8 +339,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) @@ -354,7 +368,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/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) 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 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/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/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..deadf291 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); @@ -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/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..3792b88d 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; @@ -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/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 */ 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); 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, 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) {