From a7b011649749e250295c3abb8e9bdc228cf26179 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 19 Aug 2010 17:11:28 +0100 Subject: [PATCH] * Thu Aug 19 2010 Bastien Nocera 0.2.0-1 - Update to 0.2.0 --- 0001-Add-gdk-pixbuf-support.patch | 228 --- ...-rules-to-set-devices-to-autosuspend.patch | 126 -- aes1610.c | 552 -------- libfprint-aes1610-driver.patch | 1254 ----------------- libfprint.spec | 23 +- sources | 2 +- 6 files changed, 8 insertions(+), 2177 deletions(-) delete mode 100644 0001-Add-gdk-pixbuf-support.patch delete mode 100644 0001-Add-udev-rules-to-set-devices-to-autosuspend.patch delete mode 100644 aes1610.c delete mode 100644 libfprint-aes1610-driver.patch diff --git a/0001-Add-gdk-pixbuf-support.patch b/0001-Add-gdk-pixbuf-support.patch deleted file mode 100644 index b0aad20..0000000 --- a/0001-Add-gdk-pixbuf-support.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 2028670e54184aa57a30b7b800ae19671db5deb9 Mon Sep 17 00:00:00 2001 -From: Bastien Nocera -Date: Wed, 29 Oct 2008 12:53:24 +0000 -Subject: [PATCH] Add gdk-pixbuf support - -When imaging support is required, we prefer to use gdk-pixbuf, -as it's already on things like Live CDs. -Also fix the examples building against the system libfprint. ---- - configure.ac | 30 ++++++++++++---- - examples/Makefile.am | 10 +++--- - libfprint/Makefile.am | 10 ++++- - libfprint/gdkpixbuf.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 123 insertions(+), 15 deletions(-) - create mode 100644 libfprint/gdkpixbuf.c - -diff --git a/configure.ac b/configure.ac -index d77340f..b3942ff 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -20,7 +20,7 @@ AC_SUBST(lt_age) - - all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000" - --require_imagemagick='no' -+require_imaging='no' - require_aeslib='no' - enable_upekts='no' - enable_upektc='no' -@@ -76,7 +76,7 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do - aes4000) - AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver]) - require_aeslib="yes" -- require_imagemagick="yes" -+ require_imaging="yes" - enable_aes4000="yes" - ;; - esac -@@ -91,7 +91,6 @@ AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" != "no"]) - #AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" != "no"]) - AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" != "no"]) - AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" != "no"]) --AM_CONDITIONAL([REQUIRE_IMAGEMAGICK], [test "$require_imagemagick" != "no"]) - AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" != "no"]) - - -@@ -108,11 +107,26 @@ PKG_CHECK_MODULES(GLIB, "glib-2.0") - AC_SUBST(GLIB_CFLAGS) - AC_SUBST(GLIB_LIBS) - --if test "$require_imagemagick" != "no"; then --PKG_CHECK_MODULES(IMAGEMAGICK, "ImageMagick") --AC_SUBST(IMAGEMAGICK_CFLAGS) --AC_SUBST(IMAGEMAGICK_LIBS) --fi; -+imagemagick_found=no -+gdkpixbuf_found=no -+ -+if test "$require_imaging" != "no"; then -+ PKG_CHECK_MODULES(IMAGING, gthread-2.0 gdk-pixbuf-2.0, [gdkpixbuf_found=yes], [gdkpixbuf_found=no]) -+ if test "$gdkpixbuf_found" != "yes"; then -+ PKG_CHECK_MODULES(IMAGING, ImageMagick, [imagemagick_found=yes], [imagemagick_found=no]) -+ fi -+fi -+ -+if test "$require_imaging" != "no"; then -+ if test "$gdkpixbuf_found" != "yes" && test "$imagemagick_found" != "yes"; then -+ AC_MSG_ERROR([gdk-pixbuf or ImageMagick is required for imaging support]) -+ fi -+fi -+ -+AM_CONDITIONAL([REQUIRE_GDKPIXBUF], [test "$gdkpixbuf_found" != "no"]) -+AM_CONDITIONAL([REQUIRE_IMAGEMAGICK], [test "$imagemagick_found" != "no"]) -+AC_SUBST(IMAGING_CFLAGS) -+AC_SUBST(IMAGING_LIBS) - - # Examples build - AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build], -diff --git a/examples/Makefile.am b/examples/Makefile.am -index eb6dedb..3f89134 100644 ---- a/examples/Makefile.am -+++ b/examples/Makefile.am -@@ -2,22 +2,22 @@ INCLUDES = -I$(top_srcdir) - noinst_PROGRAMS = verify_live enroll verify img_capture - - verify_live_SOURCES = verify_live.c --verify_live_LDADD = ../libfprint/libfprint.la -lfprint -+verify_live_LDADD = ../libfprint/libfprint.la - - enroll_SOURCES = enroll.c --enroll_LDADD = ../libfprint/libfprint.la -lfprint -+enroll_LDADD = ../libfprint/libfprint.la - - verify_SOURCES = verify.c --verify_LDADD = ../libfprint/libfprint.la -lfprint -+verify_LDADD = ../libfprint/libfprint.la - - img_capture_SOURCES = img_capture.c --img_capture_LDADD = ../libfprint/libfprint.la -lfprint -+img_capture_LDADD = ../libfprint/libfprint.la - - if BUILD_X11_EXAMPLES - noinst_PROGRAMS += img_capture_continuous - - img_capture_continuous_CFLAGS = $(X_CFLAGS) $(XV_CFLAGS) - img_capture_continuous_SOURCES = img_capture_continuous.c --img_capture_continuous_LDADD = ../libfprint/libfprint.la -lfprint $(X_LIBS) $(X_PRE_LIBS) $(XV_LIBS) -lX11 $(X_EXTRA_LIBS); -+img_capture_continuous_LDADD = ../libfprint/libfprint.la $(X_LIBS) $(X_PRE_LIBS) $(XV_LIBS) -lX11 $(X_EXTRA_LIBS); - endif - -diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am -index 844b09e..0ffa0f6 100644 ---- a/libfprint/Makefile.am -+++ b/libfprint/Makefile.am -@@ -92,8 +92,14 @@ endif - - if REQUIRE_IMAGEMAGICK - OTHER_SRC += imagemagick.c --libfprint_la_CFLAGS += $(IMAGEMAGICK_CFLAGS) --libfprint_la_LIBADD += $(IMAGEMAGICK_LIBS) -+libfprint_la_CFLAGS += $(IMAGING_CFLAGS) -+libfprint_la_LIBADD += $(IMAGING_LIBS) -+endif -+ -+if REQUIRE_GDKPIXBUF -+OTHER_SRC += gdkpixbuf.c -+libfprint_la_CFLAGS += $(IMAGING_CFLAGS) -+libfprint_la_LIBADD += $(IMAGING_LIBS) - endif - - if REQUIRE_AESLIB -diff --git a/libfprint/gdkpixbuf.c b/libfprint/gdkpixbuf.c -new file mode 100644 -index 0000000..7ffc099 ---- /dev/null -+++ b/libfprint/gdkpixbuf.c -@@ -0,0 +1,88 @@ -+/* -+ * Imaging utility functions for libfprint -+ * Copyright (C) 2007-2008 Daniel Drake -+ * -+ * 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 -+#include -+ -+#include "fp_internal.h" -+ -+struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int factor) -+{ -+ int new_width = img->width * factor; -+ int new_height = img->height * factor; -+ GdkPixbuf *orig, *resized; -+ struct fp_img *newimg; -+ guchar *pixels; -+ guint y; -+ int rowstride; -+ -+ g_type_init (); -+ -+ /* It is possible to implement resizing using a simple algorithm, however -+ * we use gdk-pixbuf because it applies some kind of smoothing to the -+ * result, which improves matching performances in my experiments. */ -+ -+ /* Create the original pixbuf, and fill it in from the grayscale data */ -+ orig = gdk_pixbuf_new (GDK_COLORSPACE_RGB, -+ FALSE, -+ 8, -+ img->width, -+ img->height); -+ rowstride = gdk_pixbuf_get_rowstride (orig); -+ pixels = gdk_pixbuf_get_pixels (orig); -+ for (y = 0; y < img->height; y++) { -+ guint x; -+ for (x = 0; x < img->width; x++) { -+ guchar *p, *r; -+ -+ p = pixels + y * rowstride + x * 3; -+ r = img->data + y * img->width + x; -+ p[0] = r[0]; -+ p[1] = r[0]; -+ p[2] = r[0]; -+ } -+ } -+ -+ /* Resize the pixbuf, and create the new fp_img */ -+ resized = gdk_pixbuf_scale_simple (orig, new_width, new_height, GDK_INTERP_HYPER); -+ g_object_unref (orig); -+ -+ newimg = fpi_img_new(new_width * new_height); -+ newimg->width = new_width; -+ newimg->height = new_height; -+ newimg->flags = img->flags; -+ -+ rowstride = gdk_pixbuf_get_rowstride (resized); -+ pixels = gdk_pixbuf_get_pixels (resized); -+ for (y = 0; y < newimg->height; y++) { -+ guint x; -+ for (x = 0; x < newimg->width; x++) { -+ guchar *p, *r; -+ -+ r = img->data + y * img->width + x; -+ p = pixels + y * rowstride + x * 3; -+ r[0] = p[0]; -+ } -+ } -+ -+ g_object_unref (resized); -+ -+ return newimg; -+} -+ --- -1.6.0.3 - diff --git a/0001-Add-udev-rules-to-set-devices-to-autosuspend.patch b/0001-Add-udev-rules-to-set-devices-to-autosuspend.patch deleted file mode 100644 index c61ba94..0000000 --- a/0001-Add-udev-rules-to-set-devices-to-autosuspend.patch +++ /dev/null @@ -1,126 +0,0 @@ -From c60d18b9e5e7d62c27d29d4f386a296edc3c491d Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Thu, 1 Oct 2009 15:08:41 +0100 -Subject: [PATCH] Add udev rules to set devices to autosuspend - -Most fingerprint readers can be suspended safely, so use -the udev rules to autosuspend them when they appear. - -The script itself contains whitelists and blacklists. ---- - libfprint/Makefile.am | 13 +++++- - libfprint/fprint-list-udev-rules.c | 73 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 84 insertions(+), 2 deletions(-) - create mode 100644 libfprint/fprint-list-udev-rules.c - -diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am -index 0eb5ca6..7f05468 100644 ---- a/libfprint/Makefile.am -+++ b/libfprint/Makefile.am -@@ -1,6 +1,6 @@ - lib_LTLIBRARIES = libfprint.la --noinst_PROGRAMS = fprint-list-hal-info --MOSTLYCLEANFILES = $(hal_fdi_DATA) -+noinst_PROGRAMS = fprint-list-hal-info fprint-list-udev-rules -+MOSTLYCLEANFILES = $(hal_fdi_DATA) $(udev_rules_DATA) - - UPEKTS_SRC = drivers/upekts.c - UPEKTC_SRC = drivers/upektc.c -@@ -66,6 +66,15 @@ hal_fdidir = $(datadir)/hal/fdi/information/20thirdparty/ - $(hal_fdi_DATA): fprint-list-hal-info - $(builddir)/fprint-list-hal-info > $@ - -+fprint_list_udev_rules_SOURCES = fprint-list-udev-rules.c -+fprint_list_udev_rules_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(IMAGEMAGICK_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS) -+fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la -+ -+udev_rules_DATA = 60-fprint-autosuspend.rules -+udev_rulesdir = $(sysconfdir)/udev/rules.d/ -+ -+$(udev_rules_DATA): fprint-list-udev-rules -+ $(builddir)/fprint-list-udev-rules > $@ - - if ENABLE_UPEKTS - DRIVER_SRC += $(UPEKTS_SRC) -diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c -new file mode 100644 -index 0000000..874e41a ---- /dev/null -+++ b/libfprint/fprint-list-udev-rules.c -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2009 Red Hat -+ * Copyright (C) 2008 Bastien Nocera -+ * Copyright (C) 2008 Timo Hoenig , -+ * -+ * 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 -+#include -+ -+#include "fp_internal.h" -+ -+static const struct usb_id whitelist_id_table[] = { -+ { .vendor = 0x08ff, .product = 0x2810 }, -+ { 0, 0, 0, }, -+}; -+ -+static const struct usb_id blacklist_id_table[] = { -+ { .vendor = 0x0483, .product = 0x2016 }, -+ { 0, 0, 0 }, -+}; -+ -+struct fp_driver whitelist = { -+ .id_table = whitelist_id_table, -+}; -+ -+static void print_driver (struct fp_driver *driver) -+{ -+ int i, j, blacklist; -+ -+ for (i = 0; driver->id_table[i].vendor != 0; i++) { -+ blacklist = 0; -+ for (j = 0; blacklist_id_table[j].vendor != 0; j++) { -+ if (driver->id_table[i].vendor == blacklist_id_table[j].vendor && -+ driver->id_table[j].product == blacklist_id_table[j].product) { -+ blacklist = 1; -+ } -+ } -+ if (blacklist) -+ continue; -+ -+ printf ("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ATTRS{dev}==\"*\", ATTR{power/level}=\"auto\"\n", driver->id_table[i].vendor, driver->id_table[i].product); -+ } -+} -+ -+int main (int argc, char **argv) -+{ -+ struct fp_driver **list; -+ guint i; -+ -+ list = fprint_get_drivers (); -+ -+ for (i = 0; list[i] != NULL; i++) { -+ print_driver (list[i]); -+ } -+ -+ print_driver (&whitelist); -+ -+ return 0; -+} --- -1.6.4.4 - diff --git a/aes1610.c b/aes1610.c deleted file mode 100644 index 318195f..0000000 --- a/aes1610.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * AuthenTec AES1610 driver for libfprint - * Copyright (C) 2007 Anthony Bretaudeau - * Copyright (C) 2007 Daniel Drake - * Copyright (C) 2007 Cyrille Bagard - * Copyright (C) 2007 Vasily Khoruzhick - * - * Based on code from http://home.gna.org/aes2501, relicensed with permission - * - * 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 "aes1610" - -#include -#include - -#include - -#include -#include - -/* FIXME these need checking */ -#define EP_IN (1 | LIBUSB_ENDPOINT_IN) -#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) - -#define BULK_TIMEOUT 4000 - -#define FIRST_AES1610_REG 0x1B -#define LAST_AES1610_REG 0xFF - -/* - * The AES1610 is an imaging device using a swipe-type sensor. It samples - * the finger at preprogrammed intervals, sending a 128x8 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 128 -#define FRAME_HEIGHT 8 -#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) -/* maximum number of frames to read during a scan */ -/* FIXME reduce substantially */ -#define MAX_FRAMES 350 - -static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len) -{ - int r; - int transferred; - struct libusb_bulk_transfer msg = { - .endpoint = EP_IN, - .data = data, - .length = len, - }; - fp_dbg("len=%zd", len); - - r = libusb_bulk_transfer(dev->udev, &msg, &transferred, BULK_TIMEOUT); - if (r < 0) { - fp_err("bulk read error %d", r); - return r; - } else if (transferred < len) { - fp_err("unexpected short read %d/%zd", r, len); - return -EIO; - } - return 0; -} - -static const struct aes_regwrite init[] = { - { 0x82, 0x00 } -}; - -static const struct aes_regwrite stop_reader[] = { - { 0xFF, 0x00 } -}; - -static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) -{ - int r; - - r = libusb_claim_interface(dev->udev, 0); - if (r < 0) { - fp_err("could not claim interface 0"); - return r; - } - - /* FIXME check endpoints */ - - return aes_write_regv(dev, init, G_N_ELEMENTS(init)); -} - -static int do_exit(struct fp_img_dev *dev) -{ - return aes_write_regv(dev, stop_reader, G_N_ELEMENTS(stop_reader)); -} - -static void dev_exit(struct fp_img_dev *dev) -{ - do_exit(dev); - libusb_release_interface(dev->udev, 0); -} - -static const struct aes_regwrite finger_det_reqs[] = { - { 0x80, 0x01 }, - { 0x80, 0x12 }, - { 0x85, 0x00 }, - { 0x8A, 0x00 }, - { 0x8B, 0x0E }, - { 0x8C, 0x90 }, - { 0x8D, 0x83 }, - { 0x8E, 0x07 }, - { 0x8F, 0x07 }, - { 0x96, 0x00 }, - { 0x97, 0x48 }, - { 0xA1, 0x00 }, - { 0xA2, 0x50 }, - { 0xA6, 0xE4 }, - { 0xAD, 0x08 }, - { 0xAE, 0x5B }, - { 0xAF, 0x54 }, - { 0xB1, 0x28 }, - { 0xB5, 0xAB }, - { 0xB6, 0x0E }, - { 0x1B, 0x2D }, - { 0x81, 0x04 } -}; - -static const struct aes_regwrite finger_det_none[] = { - { 0x80, 0x01 }, - { 0x82, 0x00 }, - { 0x86, 0x00 }, - { 0xB1, 0x28 }, - { 0x1D, 0x00 } -}; - -static int detect_finger(struct fp_img_dev *dev) -{ - unsigned char buffer[19]; - int r; - int i; - int sum = 0; - - r = aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs)); - if (r < 0) - return r; - - r = read_data(dev, buffer, 19); - if (r < 0) - return r; - - for (i = 3; i < 17; i++) - sum += (buffer[i] & 0xf) + (buffer[i] >> 4); - - /* We need to answer something if no finger has been detected */ - if (sum <= 20) { - r = aes_write_regv(dev, finger_det_none, G_N_ELEMENTS(finger_det_none)); - if (r < 0) - return r; - } - - return sum > 20; -} - -static int await_finger_on(struct fp_img_dev *dev) -{ - int r; - do { - r = detect_finger(dev); - } while (r == 0); - return (r < 0) ? r : 0; -} - -/* 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(unsigned char *input, unsigned char *output, - int num_strips, gboolean reverse, unsigned int *errors_sum) -{ - uint8_t *assembled = output; - int frame; - uint32_t image_height = FRAME_HEIGHT; - unsigned int min_error; - *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(input, FRAME_WIDTH, FRAME_HEIGHT, output); - input += FRAME_WIDTH * (FRAME_HEIGHT / 2); - - if (reverse) - output -= FRAME_SIZE; - else - output += FRAME_SIZE; - } - - /* 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 const struct aes_regwrite capture_reqs[] = { - { 0x80, 0x01 }, - { 0x80, 0x12 }, - { 0x84, 0x01 }, - { 0x85, 0x00 }, - { 0x89, 0x64 }, - { 0x8A, 0x00 }, - { 0x8B, 0x0E }, - { 0x8C, 0x90 }, - { 0xBE, 0x23 }, - { 0x29, 0x06 }, - { 0x2A, 0x35 }, - { 0x96, 0x00 }, - { 0x98, 0x03 }, - { 0x99, 0x00 }, - { 0x9C, 0xA5 }, - { 0x9D, 0x40 }, - { 0x9E, 0xC6 }, - { 0x9F, 0x8E }, - { 0xA2, 0x50 }, - { 0xA3, 0xF0 }, - { 0xAD, 0x08 }, - { 0xBD, 0x4F }, - { 0xAF, 0x54 }, - { 0xB1, 0x08 }, - { 0xB5, 0xAB }, - { 0x1B, 0x2D }, - { 0xB6, 0x4E }, - { 0xB8, 0x70 }, - { 0x2B, 0xB3 }, - { 0x2C, 0x5D }, - { 0x2D, 0x98 }, - { 0x2E, 0xB0 }, - { 0x2F, 0x20 }, - { 0xA2, 0xD0 }, - { 0x1D, 0x21 }, - { 0x1E, 0xBE }, - { 0x1C, 0x00 }, - { 0x1D, 0x30 }, - { 0x1E, 0x29 }, - { 0x1C, 0x01 }, - { 0x1D, 0x00 }, - { 0x1E, 0x9E }, - { 0x1C, 0x02 }, - { 0x1D, 0x30 }, - { 0x1E, 0xBB }, - { 0x1C, 0x03 }, - { 0x1D, 0x00 }, - { 0x1E, 0x9D }, - { 0x1C, 0x04 }, - { 0x1D, 0x22 }, - { 0x1E, 0xFF }, - { 0x1C, 0x05 }, - { 0x1D, 0x1B }, - { 0x1E, 0x4E }, - { 0x1C, 0x06 }, - { 0x1D, 0x16 }, - { 0x1E, 0x28 }, - { 0x1C, 0x07 }, - { 0x1D, 0x22 }, - { 0x1E, 0xFF }, - { 0x1C, 0x08 }, - { 0x1D, 0x15 }, - { 0x1E, 0xF1 }, - { 0x1C, 0x09 }, - { 0x1D, 0x30 }, - { 0x1E, 0xD5 }, - { 0x1C, 0x0A }, - { 0x1D, 0x00 }, - { 0x1E, 0x9E }, - { 0x1C, 0x0B }, - { 0x1D, 0x17 }, - { 0x1E, 0x9D }, - { 0x1C, 0x0C }, - { 0x1D, 0x28 }, - { 0x1E, 0xD7 }, - { 0x1C, 0x0D }, - { 0x1D, 0x17 }, - { 0x1E, 0xD7 }, - { 0x1C, 0x0E }, - { 0x1D, 0x0A }, - { 0x1E, 0xCB }, - { 0x1C, 0x0F }, - { 0x1D, 0x24 }, - { 0x1E, 0x14 }, - { 0x1C, 0x10 }, - { 0x1D, 0x17 }, - { 0x1E, 0x85 }, - { 0x1C, 0x11 }, - { 0x1D, 0x15 }, - { 0x1E, 0x71 }, - { 0x1C, 0x12 }, - { 0x1D, 0x2B }, - { 0x1E, 0x36 }, - { 0x1C, 0x13 }, - { 0x1D, 0x12 }, - { 0x1E, 0x06 }, - { 0x1C, 0x14 }, - { 0x1D, 0x30 }, - { 0x1E, 0x97 }, - { 0x1C, 0x15 }, - { 0x1D, 0x21 }, - { 0x1E, 0x32 }, - { 0x1C, 0x16 }, - { 0x1D, 0x06 }, - { 0x1E, 0xE6 }, - { 0x1C, 0x17 }, - { 0x1D, 0x16 }, - { 0x1E, 0x06 }, - { 0x1C, 0x18 }, - { 0x1D, 0x30 }, - { 0x1E, 0x01 }, - { 0x1C, 0x19 }, - { 0x1D, 0x21 }, - { 0x1E, 0x37 }, - { 0x1C, 0x1A }, - { 0x1D, 0x00 }, - { 0x1E, 0x08 }, - { 0x1C, 0x1B }, - { 0x1D, 0x80 }, - { 0x1E, 0xD5 }, - { 0xA2, 0x50 }, - { 0xA2, 0x50 }, - { 0x81, 0x01 } -}; - -static const struct aes_regwrite strip_scan_reqs[] = { - { 0xBE, 0x23 }, - { 0x29, 0x06 }, - { 0x2A, 0x35 }, - { 0xBD, 0x4F }, - { 0xFF, 0x00 } -}; - -static const struct aes_regwrite capture_stop[] = { - { 0x81,0x00 } -}; - -static int capture(struct fp_img_dev *dev, gboolean unconditional, - struct fp_img **ret) -{ - int r; - struct fp_img *img; - unsigned int nstrips; - unsigned int errors_sum, r_errors_sum; - unsigned char *cooked; - unsigned char *imgptr; - unsigned char buf[665]; - int final_size; - int sum; - unsigned int count_blank = 0; - int i; - - /* FIXME can do better here in terms of buffer management? */ - fp_dbg(""); - - r = aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs)); - if (r < 0) - return r; - - /* FIXME: use histogram data above for gain calibration (0x8e xx) */ - - img = fpi_img_new((3 * MAX_FRAMES * FRAME_SIZE) / 2); - imgptr = img->data; - cooked = imgptr + (MAX_FRAMES * FRAME_SIZE) / 2; - - r = read_data(dev, buf, 665); - if (r < 0) - goto err; - memcpy(imgptr, buf + 1, 128*4); - imgptr += 128*4; - - r = read_data(dev, buf, 665); - if (r < 0) - goto err; - memcpy(imgptr, buf + 1, 128*4); - imgptr += 128*4; - - /* we start at 2 because we captured 2 frames above. the above captures - * should possibly be moved into the loop below, or discarded altogether */ - for (nstrips = 2; nstrips < MAX_FRAMES - 2; nstrips++) { - r = aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs)); - if (r < 0) - goto err; - r = read_data(dev, buf, 665); - if (r < 0) - goto err; - memcpy(imgptr, buf + 1, 128*4); - imgptr += 128*4; - - r = read_data(dev, buf, 665); - if (r < 0) - goto err; - memcpy(imgptr, buf + 1, 128*4); - imgptr += 128*4; - - sum = 0; - for (i = 515; i != 530; i++) - { - /* histogram[i] = number of pixels of value i - Only the pixel values from 10 to 15 are used to detect finger. */ - sum += buf[i]; - } - if (sum < 0) { - r = sum; - goto err; - } - fp_dbg("sum=%d", sum); - if (sum == 0) - count_blank++; - else - count_blank = 0; - - /* if we got 50 blank frames, assume scan has ended. */ - if (count_blank >= 50) - break; - } - - r = aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop)); - if (r < 0) - goto err; - r = read_data(dev, buf, 665); - if (r < 0) - goto err; - memcpy(imgptr, buf + 1, 128*4); - imgptr += 128*4; - nstrips++; - - r = read_data(dev, buf, 665); - if (r < 0) - goto err; - memcpy(imgptr, buf + 1, 128*4); - imgptr += 128*4; - nstrips++; - - if (nstrips == MAX_FRAMES) - fp_warn("swiping finger too slow?"); - - img->flags = FP_IMG_COLORS_INVERTED; - img->height = assemble(img->data, cooked, nstrips, FALSE, &errors_sum); - img->height = assemble(img->data, cooked, nstrips, TRUE, &r_errors_sum); - - if (r_errors_sum > errors_sum) { - img->height = assemble(img->data, cooked, nstrips, FALSE, &errors_sum); - img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; - fp_dbg("normal scan direction"); - } else { - fp_dbg("reversed scan direction"); - } - - final_size = img->height * FRAME_WIDTH; - memcpy(img->data, cooked, final_size); - img = fpi_img_resize(img, final_size); - *ret = img; - return 0; -err: - fp_img_free(img); - return r; -} - -static const struct usb_id id_table[] = { - { .vendor = 0x08ff, .product = 0x1600 }, - { 0, 0, 0, }, -}; - -struct fp_img_driver aes1610_driver = { - .driver = { - .id = 6, - .name = FP_COMPONENT, - .full_name = "AuthenTec AES1610", - .id_table = id_table, - .scan_type = FP_SCAN_TYPE_SWIPE, - }, - .flags = 0, - .img_height = -1, - .img_width = 128, - - /* 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 = 10, - - .init = dev_init, - .exit = dev_exit, - .await_finger_on = await_finger_on, - .capture = capture, -}; - diff --git a/libfprint-aes1610-driver.patch b/libfprint-aes1610-driver.patch deleted file mode 100644 index 46b710a..0000000 --- a/libfprint-aes1610-driver.patch +++ /dev/null @@ -1,1254 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index 052ef0e..a892a96 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -89,7 +89,7 @@ AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" != "no"]) - AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" != "no"]) - AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" != "no"]) - #AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" != "no"]) --#AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" != "no"]) -+AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" != "no"]) - AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" != "no"]) - AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" != "no"]) - AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" != "no"]) -diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am -index c79012b..8316796 100644 ---- a/libfprint/Makefile.am -+++ b/libfprint/Makefile.am -@@ -100,9 +100,9 @@ endif - #DRIVER_SRC += $(FDU2000_SRC) - #endif - --#if ENABLE_AES1610 --#DRIVER_SRC += $(AES1610_SRC) --#endif -+if ENABLE_AES1610 -+DRIVER_SRC += $(AES1610_SRC) -+endif - - if ENABLE_AES2501 - DRIVER_SRC += $(AES2501_SRC) -diff --git a/libfprint/core.c b/libfprint/core.c -index 37a4e03..724d5e5 100644 ---- a/libfprint/core.c -+++ b/libfprint/core.c -@@ -361,11 +361,11 @@ static struct fp_img_driver * const img_drivers[] = { - #ifdef ENABLE_UPEKSONLY - &upeksonly_driver, - #endif -- /* -+ - #ifdef ENABLE_AES1610 - &aes1610_driver, - #endif --#ifdef ENABLE_UPEKTC -+/*#ifdef ENABLE_UPEKTC - &upektc_driver, - #endif - #ifdef ENABLE_FDU2000 -diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c -index 318195f..8b81a80 100644 ---- a/libfprint/drivers/aes1610.c -+++ b/libfprint/drivers/aes1610.c -@@ -1,11 +1,11 @@ - /* - * AuthenTec AES1610 driver for libfprint -- * Copyright (C) 2007 Anthony Bretaudeau -- * Copyright (C) 2007 Daniel Drake -+ * Copyright (C) 2007-2008 Daniel Drake - * Copyright (C) 2007 Cyrille Bagard - * Copyright (C) 2007 Vasily Khoruzhick -+ * Copyright (C) 2009 Guido Grazioli - * -- * Based on code from http://home.gna.org/aes2501, relicensed with permission -+ * Based on code from libfprint aes2501 driver. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -32,15 +32,22 @@ - #include - #include - -+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); -+ -+#define FIRST_AES1610_REG 0x1B -+#define LAST_AES1610_REG 0xFF -+ -+#define GAIN_STATUS_FIRST 1 -+#define GAIN_STATUS_NORMAL 2 -+ - /* FIXME these need checking */ - #define EP_IN (1 | LIBUSB_ENDPOINT_IN) - #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) - - #define BULK_TIMEOUT 4000 - --#define FIRST_AES1610_REG 0x1B --#define LAST_AES1610_REG 0xFF -- - /* - * The AES1610 is an imaging device using a swipe-type sensor. It samples - * the finger at preprogrammed intervals, sending a 128x8 frame to the -@@ -53,140 +60,212 @@ - * images returned from this driver vary in height. - */ - --#define FRAME_WIDTH 128 -+#define FRAME_WIDTH 128 - #define FRAME_HEIGHT 8 --#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) -+#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) - /* maximum number of frames to read during a scan */ - /* FIXME reduce substantially */ - #define MAX_FRAMES 350 - --static int read_data(struct fp_img_dev *dev, unsigned char *data, size_t len) -+/****** GENERAL FUNCTIONS ******/ -+ -+struct aes1610_dev { -+ uint8_t read_regs_retry_count; -+ GSList *strips; -+ size_t strips_len; -+ gboolean deactivating; -+ uint8_t blanks_count; -+}; -+ -+typedef void (*aes1610_read_regs_cb)(struct fp_img_dev *dev, int status, -+ unsigned char *regs, void *user_data); -+ -+struct aes1610_read_regs { -+ struct fp_img_dev *dev; -+ aes1610_read_regs_cb callback; -+ struct aes_regwrite *regwrite; -+ void *user_data; -+}; -+ -+/* FIXME: what to do here? */ -+static void stub_capture_stop_cb(struct fp_img_dev *dev, int result, void *user_data) - { -- int r; -- int transferred; -- struct libusb_bulk_transfer msg = { -- .endpoint = EP_IN, -- .data = data, -- .length = len, -- }; -- fp_dbg("len=%zd", len); - -- r = libusb_bulk_transfer(dev->udev, &msg, &transferred, BULK_TIMEOUT); -- if (r < 0) { -- fp_err("bulk read error %d", r); -- return r; -- } else if (transferred < len) { -- fp_err("unexpected short read %d/%zd", r, len); -- return -EIO; -- } -- return 0; - } - --static const struct aes_regwrite init[] = { -- { 0x82, 0x00 } --}; - --static const struct aes_regwrite stop_reader[] = { -- { 0xFF, 0x00 } --}; -+/* check that read succeeded but ignore all data */ -+static void generic_ignore_data_cb(struct libusb_transfer *transfer) -+{ -+ struct fpi_ssm *ssm = transfer->user_data; - --static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) -+ if (transfer->status != LIBUSB_TRANSFER_COMPLETED) -+ fpi_ssm_mark_aborted(ssm, -EIO); -+ else if (transfer->length != transfer->actual_length) -+ fpi_ssm_mark_aborted(ssm, -EPROTO); -+ else -+ fpi_ssm_next_state(ssm); -+ -+ g_free(transfer->buffer); -+ 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; - -- r = libusb_claim_interface(dev->udev, 0); -+ 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) { -- fp_err("could not claim interface 0"); -- return r; -+ g_free(data); -+ libusb_free_transfer(transfer); -+ result = -EIO; -+ goto err; - } - -- /* FIXME check endpoints */ -+ return; -+err: -+ rdata->callback(dev, result, NULL, rdata->user_data); -+ g_free(rdata); -+} - -- return aes_write_regv(dev, init, G_N_ELEMENTS(init)); -+ -+// 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); - } - --static int do_exit(struct fp_img_dev *dev) -+/* Read the value of a specific register from a register dump */ -+static int regval_from_dump(unsigned char *data, uint8_t target) - { -- return aes_write_regv(dev, stop_reader, G_N_ELEMENTS(stop_reader)); -+ 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 dev_exit(struct fp_img_dev *dev) -+static void generic_write_regv_cb(struct fp_img_dev *dev, int result, -+ void *user_data) - { -- do_exit(dev); -- libusb_release_interface(dev->udev, 0); -+ struct fpi_ssm *ssm = user_data; -+ if (result == 0) -+ fpi_ssm_next_state(ssm); -+ else -+ fpi_ssm_mark_aborted(ssm, result); - } - --static const struct aes_regwrite finger_det_reqs[] = { -- { 0x80, 0x01 }, -- { 0x80, 0x12 }, -- { 0x85, 0x00 }, -- { 0x8A, 0x00 }, -- { 0x8B, 0x0E }, -- { 0x8C, 0x90 }, -- { 0x8D, 0x83 }, -- { 0x8E, 0x07 }, -- { 0x8F, 0x07 }, -- { 0x96, 0x00 }, -- { 0x97, 0x48 }, -- { 0xA1, 0x00 }, -- { 0xA2, 0x50 }, -- { 0xA6, 0xE4 }, -- { 0xAD, 0x08 }, -- { 0xAE, 0x5B }, -- { 0xAF, 0x54 }, -- { 0xB1, 0x28 }, -- { 0xB5, 0xAB }, -- { 0xB6, 0x0E }, -- { 0x1B, 0x2D }, -- { 0x81, 0x04 } --}; - --static const struct aes_regwrite finger_det_none[] = { -- { 0x80, 0x01 }, -- { 0x82, 0x00 }, -- { 0x86, 0x00 }, -- { 0xB1, 0x28 }, -- { 0x1D, 0x00 } --}; - --static int detect_finger(struct fp_img_dev *dev) -+/* 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) - { -- unsigned char buffer[19]; -+ struct libusb_transfer *transfer = libusb_alloc_transfer(0); -+ unsigned char *data; - int r; -- int i; -- int sum = 0; - -- r = aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs)); -- if (r < 0) -- return r; -+ if (!transfer) { -+ fpi_ssm_mark_aborted(ssm, -ENOMEM); -+ return; -+ } - -- r = read_data(dev, buffer, 19); -- if (r < 0) -- return r; -+ data = g_malloc(bytes); -+ libusb_fill_bulk_transfer(transfer, ssm->dev->udev, EP_IN, data, bytes, -+ generic_ignore_data_cb, ssm, BULK_TIMEOUT); - -- for (i = 3; i < 17; i++) -- sum += (buffer[i] & 0xf) + (buffer[i] >> 4); -- -- /* We need to answer something if no finger has been detected */ -- if (sum <= 20) { -- r = aes_write_regv(dev, finger_det_none, G_N_ELEMENTS(finger_det_none)); -- if (r < 0) -- return r; -+ r = libusb_submit_transfer(transfer); -+ if (r < 0) { -+ g_free(data); -+ libusb_free_transfer(transfer); -+ fpi_ssm_mark_aborted(ssm, r); - } -- -- return sum > 20; - } - --static int await_finger_on(struct fp_img_dev *dev) -+/****** IMAGE PROCESSING ******/ -+ -+static int sum_histogram_values(unsigned char *data, uint8_t threshold) - { -- int r; -- do { -- r = detect_finger(dev); -- } while (r == 0); -- return (r < 0) ? r : 0; -+ 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 */ -+/* find overlapping parts of frames */ - static unsigned int find_overlap(unsigned char *first_frame, - unsigned char *second_frame, unsigned int *min_error) - { -@@ -199,11 +278,11 @@ static unsigned int find_overlap(unsigned char *first_frame, - 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]); -+ 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; -@@ -213,37 +292,39 @@ static unsigned int find_overlap(unsigned char *first_frame, - } - first_frame += FRAME_WIDTH; - } -- -- return not_overlapped_height; -+ -+ return not_overlapped_height; - } - - /* assemble a series of frames into a single image */ --static unsigned int assemble(unsigned char *input, unsigned char *output, -- int num_strips, gboolean reverse, unsigned int *errors_sum) -+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 -+ -+ /* 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(input, FRAME_WIDTH, FRAME_HEIGHT, output); -- input += FRAME_WIDTH * (FRAME_HEIGHT / 2); -+ aes_assemble_image(list_entry->data, FRAME_WIDTH, FRAME_HEIGHT, output); - - if (reverse) -- output -= FRAME_SIZE; -+ output -= FRAME_SIZE; - else -- output += FRAME_SIZE; -+ output += FRAME_SIZE; -+ list_entry = g_slist_next(list_entry); - } - - /* Detecting where frames overlaped */ -@@ -256,12 +337,183 @@ static unsigned int assemble(unsigned char *input, unsigned char *output, - *errors_sum += min_error; - image_height += not_overlapped; - assembled += FRAME_WIDTH * not_overlapped; -- memcpy(assembled, output, FRAME_SIZE); -+ memcpy(assembled, output, FRAME_SIZE); - } - return image_height; - } - --static const struct aes_regwrite capture_reqs[] = { -+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 ******/ -+ -+ -+static const struct aes_regwrite finger_det_reqs[] = { -+ { 0x80, 0x01 }, -+ { 0x80, 0x12 }, -+ { 0x85, 0x00 }, -+ { 0x8A, 0x00 }, -+ { 0x8B, 0x0E }, -+ { 0x8C, 0x90 }, -+ { 0x8D, 0x83 }, -+ { 0x8E, 0x07 }, -+ { 0x8F, 0x07 }, -+ { 0x96, 0x00 }, -+ { 0x97, 0x48 }, -+ { 0xA1, 0x00 }, -+ { 0xA2, 0x50 }, -+ { 0xA6, 0xE4 }, -+ { 0xAD, 0x08 }, -+ { 0xAE, 0x5B }, -+ { 0xAF, 0x54 }, -+ { 0xB1, 0x28 }, -+ { 0xB5, 0xAB }, -+ { 0xB6, 0x0E }, -+ { 0x1B, 0x2D }, -+ { 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) -+{ -+ struct fp_img_dev *dev = transfer->user_data; -+ unsigned char *data = transfer->buffer; -+ int i; -+ int sum = 0; -+ -+ if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { -+ fpi_imgdev_session_error(dev, -EIO); -+ goto out; -+ } else if (transfer->length != transfer->actual_length) { -+ fpi_imgdev_session_error(dev, -EPROTO); -+ goto out; -+ } -+ -+ /* examine histogram to determine finger presence */ -+ for (i = 3; i < 17; i++) -+ sum += (data[i] & 0xf) + (data[i] >> 4); -+ if (sum > 20) { -+ /* reset default gain */ -+ adjust_gain(data,GAIN_STATUS_FIRST); -+ /* 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_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; -+ unsigned char *data; -+ int r; -+ -+ if (result) { -+ fpi_imgdev_session_error(dev, result); -+ return; -+ } -+ -+ transfer = libusb_alloc_transfer(0); -+ if (!transfer) { -+ fpi_imgdev_session_error(dev, -ENOMEM); -+ return; -+ } -+ -+ data = g_malloc(19); -+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 19, -+ 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); -+ } -+ -+} -+ -+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); -+ return; -+ } -+ -+ aes_write_regv(dev, finger_det_reqs, G_N_ELEMENTS(finger_det_reqs), finger_det_reqs_cb, NULL); -+ -+} -+ -+/****** CAPTURE ******/ -+ -+static struct aes_regwrite capture_reqs[] = { - { 0x80, 0x01 }, - { 0x80, 0x12 }, - { 0x84, 0x01 }, -@@ -271,8 +523,8 @@ static const struct aes_regwrite capture_reqs[] = { - { 0x8B, 0x0E }, - { 0x8C, 0x90 }, - { 0xBE, 0x23 }, -- { 0x29, 0x06 }, -- { 0x2A, 0x35 }, -+ { 0x29, 0x04 }, -+ { 0x2A, 0xFF }, - { 0x96, 0x00 }, - { 0x98, 0x03 }, - { 0x99, 0x00 }, -@@ -387,10 +639,10 @@ static const struct aes_regwrite capture_reqs[] = { - { 0x81, 0x01 } - }; - --static const struct aes_regwrite strip_scan_reqs[] = { -+static struct aes_regwrite strip_scan_reqs[] = { - { 0xBE, 0x23 }, -- { 0x29, 0x06 }, -- { 0x2A, 0x35 }, -+ { 0x29, 0x04 }, -+ { 0x2A, 0xFF }, - { 0xBD, 0x4F }, - { 0xFF, 0x00 } - }; -@@ -399,130 +651,456 @@ static const struct aes_regwrite capture_stop[] = { - { 0x81,0x00 } - }; - --static int capture(struct fp_img_dev *dev, gboolean unconditional, -- struct fp_img **ret) -+/* -+ * The different possible values for 0xBE register */ -+static unsigned char list_BE_values[10] = { -+ 0x23, 0x43, 0x63, 0x64, 0x65, 0x67, 0x6A, 0x6B -+}; -+ -+/* -+ * The different possible values for 0xBD register */ -+static unsigned char list_BD_values[10] = { -+ 0x48, 0x4B, 0x4F, 0x52, 0x57, 0x59, 0x5B -+}; -+ -+/* -+ * Adjust the gain according to the histogram data -+ * 0xbd, 0xbe, 0x29 and 0x2A registers are affected -+ * Returns 0 if no problem occured -+ * TODO: This is a basic support for gain. It needs testing/tweaking. */ -+static int adjust_gain(unsigned char *buffer, int status) - { -- int r; -- struct fp_img *img; -- unsigned int nstrips; -- unsigned int errors_sum, r_errors_sum; -- unsigned char *cooked; -- unsigned char *imgptr; -- unsigned char buf[665]; -- int final_size; -- int sum; -- unsigned int count_blank = 0; -- int i; -+ // The position in the array of possible values for 0xBE and 0xBD registers -+ static int pos_list_BE = 0; -+ static int pos_list_BD = 0; - -- /* FIXME can do better here in terms of buffer management? */ -- fp_dbg(""); -+ // This is the first adjustement (we begin acquisition) -+ // We adjust strip_scan_reqs for future strips and capture_reqs that is sent just after this step -+ if (status == GAIN_STATUS_FIRST) { -+ if (buffer[1] > 0x78) { // maximum gain needed -+ strip_scan_reqs[0].value = 0x6B; -+ strip_scan_reqs[1].value = 0x06; -+ strip_scan_reqs[2].value = 0x35; -+ strip_scan_reqs[3].value = 0x5B; -+ } -+ else if (buffer[1] > 0x55) { -+ strip_scan_reqs[0].value = 0x63; -+ strip_scan_reqs[1].value = 0x15; -+ strip_scan_reqs[2].value = 0x35; -+ strip_scan_reqs[3].value = 0x4F; -+ } -+ else if (buffer[1] > 0x40 || buffer[16] > 0x19) { -+ strip_scan_reqs[0].value = 0x43; -+ strip_scan_reqs[1].value = 0x13; -+ strip_scan_reqs[2].value = 0x35; -+ strip_scan_reqs[3].value = 0x4B; -+ } -+ else { // minimum gain needed -+ strip_scan_reqs[0].value = 0x23; -+ strip_scan_reqs[1].value = 0x07; -+ strip_scan_reqs[2].value = 0x35; -+ strip_scan_reqs[3].value = 0x48; -+ } - -- r = aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs)); -- if (r < 0) -- return r; -- -- /* FIXME: use histogram data above for gain calibration (0x8e xx) */ -+ // Now copy this values in capture_reqs -+ capture_reqs[8].value = strip_scan_reqs[0].value; -+ capture_reqs[9].value = strip_scan_reqs[1].value; -+ capture_reqs[10].value = strip_scan_reqs[2].value; -+ capture_reqs[21].value = strip_scan_reqs[3].value; - -- img = fpi_img_new((3 * MAX_FRAMES * FRAME_SIZE) / 2); -- imgptr = img->data; -- cooked = imgptr + (MAX_FRAMES * FRAME_SIZE) / 2; -+ fp_dbg("first gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value); -+ } - -- r = read_data(dev, buf, 665); -- if (r < 0) -- goto err; -- memcpy(imgptr, buf + 1, 128*4); -- imgptr += 128*4; -+ // Every 2/3 strips -+ // We try to soften big changes of the gain (at least for 0xBE and 0xBD -+ // FIXME: This softenning will need testing and tweaking too -+ else if (status == GAIN_STATUS_NORMAL) { -+ if (buffer[514] > 0x78) { // maximum gain needed -+ if (pos_list_BE < 7) -+ pos_list_BE++; - -- r = read_data(dev, buf, 665); -- if (r < 0) -- goto err; -- memcpy(imgptr, buf + 1, 128*4); -- imgptr += 128*4; -- -- /* we start at 2 because we captured 2 frames above. the above captures -- * should possibly be moved into the loop below, or discarded altogether */ -- for (nstrips = 2; nstrips < MAX_FRAMES - 2; nstrips++) { -- r = aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs)); -- if (r < 0) -- goto err; -- r = read_data(dev, buf, 665); -- if (r < 0) -- goto err; -- memcpy(imgptr, buf + 1, 128*4); -- imgptr += 128*4; -- -- r = read_data(dev, buf, 665); -- if (r < 0) -- goto err; -- memcpy(imgptr, buf + 1, 128*4); -- imgptr += 128*4; -- -- sum = 0; -- for (i = 515; i != 530; i++) -- { -- /* histogram[i] = number of pixels of value i -- Only the pixel values from 10 to 15 are used to detect finger. */ -- sum += buf[i]; -+ if (pos_list_BD < 6) -+ pos_list_BD++; -+ -+ strip_scan_reqs[1].value = 0x04; -+ strip_scan_reqs[2].value = 0x35; -+ } -+ else if (buffer[514] > 0x55) { -+ if (pos_list_BE < 2) -+ pos_list_BE++; -+ else if (pos_list_BE > 2) -+ pos_list_BE--; -+ -+ if (pos_list_BD < 2) -+ pos_list_BD++; -+ else if (pos_list_BD > 2) -+ pos_list_BD--; -+ -+ strip_scan_reqs[1].value = 0x15; -+ strip_scan_reqs[2].value = 0x35; - } -- if (sum < 0) { -- r = sum; -- goto err; -+ else if (buffer[514] > 0x40 || buffer[529] > 0x19) { -+ if (pos_list_BE < 1) -+ pos_list_BE++; -+ else if (pos_list_BE > 1) -+ pos_list_BE--; -+ -+ if (pos_list_BD < 1) -+ pos_list_BD++; -+ else if (pos_list_BD > 1) -+ pos_list_BD--; -+ -+ strip_scan_reqs[1].value = 0x13; -+ strip_scan_reqs[2].value = 0x35; - } -- fp_dbg("sum=%d", sum); -- if (sum == 0) -- count_blank++; -+ else { // minimum gain needed -+ if (pos_list_BE > 0) -+ pos_list_BE--; -+ -+ if (pos_list_BD > 0) -+ pos_list_BD--; -+ -+ strip_scan_reqs[1].value = 0x07; -+ strip_scan_reqs[2].value = 0x35; -+ } -+ -+ strip_scan_reqs[0].value = list_BE_values[pos_list_BE]; -+ strip_scan_reqs[3].value = list_BD_values[pos_list_BD]; -+ -+ fp_dbg("gain: %x %x %x %x %x %x %x %x", strip_scan_reqs[0].reg, strip_scan_reqs[0].value, strip_scan_reqs[1].reg, strip_scan_reqs[1].value, strip_scan_reqs[2].reg, strip_scan_reqs[2].value, strip_scan_reqs[3].reg, strip_scan_reqs[3].value); -+ } -+ // Unknown status -+ else { -+ fp_err("Unexpected gain status."); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Restore the default gain values */ -+static void restore_gain() -+{ -+ strip_scan_reqs[0].value = list_BE_values[0]; -+ strip_scan_reqs[1].value = 0x04; -+ strip_scan_reqs[2].value = 0xFF; -+ strip_scan_reqs[3].value = list_BD_values[0]; -+ -+ capture_reqs[8].value = list_BE_values[0]; -+ capture_reqs[9].value = 0x04; -+ capture_reqs[10].value = 0xFF; -+ capture_reqs[21].value = list_BD_values[0]; -+} -+ -+ -+/* capture SM movement: -+ * request and read strip, -+ * jump back to request UNLESS theres no finger, in which case exit SM, -+ * report lack of finger presence, and move to finger detection */ -+ -+enum capture_states { -+ CAPTURE_WRITE_REQS, -+ CAPTURE_READ_DATA, -+ CAPTURE_REQUEST_STRIP, -+ CAPTURE_READ_STRIP, -+ CAPTURE_NUM_STATES, -+}; -+ -+static void capture_read_strip_cb(struct libusb_transfer *transfer) -+{ -+ unsigned char *stripdata; -+ struct fpi_ssm *ssm = transfer->user_data; -+ struct fp_img_dev *dev = ssm->priv; -+ 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); -+ goto out; -+ } else if (transfer->length != transfer->actual_length) { -+ fpi_ssm_mark_aborted(ssm, -EPROTO); -+ goto out; -+ } -+ -+ /* 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++) -+ { -+ /* histogram[i] = number of pixels of value i -+ Only the pixel values from 10 to 15 are used to detect finger. */ -+ sum += data[i]; -+ } -+ -+ if (sum > 0) { -+ /* 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++; -+ aesdev->blanks_count = 0; -+ } -+ -+ 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? */ -+ -+ /* If sum is 0 for a reasonable # of frames, finger has been removed */ -+ if (sum == 0) { -+ aesdev->blanks_count++; -+ fp_dbg("got blank frame"); -+ } -+ -+ /* use histogram data above for gain calibration (0xbd, 0xbe, 0x29 and 0x2A ) */ -+ adjust_gain(data, GAIN_STATUS_NORMAL); -+ -+ /* stop capturing if MAX_FRAMES is reached */ -+ if (aesdev->blanks_count > 10 || g_slist_length(aesdev->strips) >= MAX_FRAMES) { -+ 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); -+ fpi_imgdev_report_finger_status(dev, FALSE); -+ /* marking machine complete will re-trigger finger detection loop */ -+ fpi_ssm_mark_completed(ssm); -+ /* Acquisition finished: restore default gain values */ -+ restore_gain(); -+ } else { -+ /* obtain next strip */ -+ fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP); -+ } -+ -+out: -+ g_free(data); -+ libusb_free_transfer(transfer); -+} -+ -+static void capture_run_state(struct fpi_ssm *ssm) -+{ -+ struct fp_img_dev *dev = ssm->priv; -+ struct aes1610_dev *aesdev = dev->priv; -+ int r; -+ -+ switch (ssm->cur_state) { -+ case CAPTURE_WRITE_REQS: -+ fp_dbg("write reqs"); -+ aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs), -+ generic_write_regv_cb, ssm); -+ break; -+ case CAPTURE_READ_DATA: -+ fp_dbg("read data"); -+ generic_read_ignore_data(ssm, 665); -+ break; -+ case CAPTURE_REQUEST_STRIP: -+ fp_dbg("request strip"); -+ if (aesdev->deactivating) -+ fpi_ssm_mark_completed(ssm); - else -- count_blank = 0; -- -- /* if we got 50 blank frames, assume scan has ended. */ -- if (count_blank >= 50) -+ aes_write_regv(dev, strip_scan_reqs, G_N_ELEMENTS(strip_scan_reqs), -+ generic_write_regv_cb, ssm); -+ break; -+ case CAPTURE_READ_STRIP: ; -+ struct libusb_transfer *transfer = libusb_alloc_transfer(0); -+ unsigned char *data; -+ -+ if (!transfer) { -+ fpi_ssm_mark_aborted(ssm, -ENOMEM); - break; -+ } -+ -+ data = g_malloc(665); -+ libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 665, -+ capture_read_strip_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 aes1610_dev *aesdev = dev->priv; -+ -+ fp_dbg(""); -+ 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 aes1610_dev *aesdev = dev->priv; -+ struct fpi_ssm *ssm; -+ -+ if (aesdev->deactivating) { -+ complete_deactivation(dev); -+ return; - } -- -- r = aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop)); -- if (r < 0) -- goto err; -- r = read_data(dev, buf, 665); -- if (r < 0) -- goto err; -- memcpy(imgptr, buf + 1, 128*4); -- imgptr += 128*4; -- nstrips++; - -- r = read_data(dev, buf, 665); -- if (r < 0) -- goto err; -- memcpy(imgptr, buf + 1, 128*4); -- imgptr += 128*4; -- nstrips++; -- -- if (nstrips == MAX_FRAMES) -- fp_warn("swiping finger too slow?"); -+ ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); -+ fp_dbg(""); -+ ssm->priv = dev; -+ fpi_ssm_start(ssm, capture_sm_complete); -+} - -- img->flags = FP_IMG_COLORS_INVERTED; -- img->height = assemble(img->data, cooked, nstrips, FALSE, &errors_sum); -- img->height = assemble(img->data, cooked, nstrips, TRUE, &r_errors_sum); -- -- if (r_errors_sum > errors_sum) { -- img->height = assemble(img->data, cooked, nstrips, FALSE, &errors_sum); -- img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; -- fp_dbg("normal scan direction"); -+/****** INITIALIZATION/DEINITIALIZATION ******/ -+ -+static const struct aes_regwrite init[] = { -+ { 0x82, 0x00 } -+}; -+ -+static const struct aes_regwrite stop_reader[] = { -+ { 0xFF, 0x00 } -+}; -+ -+ -+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 { -- fp_dbg("reversed scan direction"); -+ fpi_ssm_next_state(ssm); - } -+} -+*/ - -- final_size = img->height * FRAME_WIDTH; -- memcpy(img->data, cooked, final_size); -- img = fpi_img_resize(img, final_size); -- *ret = img; -+static void activate_run_state(struct fpi_ssm *ssm) -+{ -+ struct fp_img_dev *dev = ssm->priv; -+ -+ /* activation on aes1610 seems much more straightforward compared to aes2501 */ -+ /* verify theres anything missing here */ -+ switch (ssm->cur_state) { -+ case WRITE_INIT: -+ 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;*/ -+ } -+} -+ -+/* jump to finger detection */ -+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 aes1610_dev *aesdev = dev->priv; -+ struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, -+ ACTIVATE_NUM_STATES); -+ ssm->priv = dev; -+ aesdev->read_regs_retry_count = 0; -+ fpi_ssm_start(ssm, activate_sm_complete); - return 0; --err: -- fp_img_free(img); -- return r; -+} -+ -+static void dev_deactivate(struct fp_img_dev *dev) -+{ -+ struct aes1610_dev *aesdev = dev->priv; -+ /* FIXME: audit cancellation points, probably need more, specifically -+ * in error handling paths? */ -+ aesdev->deactivating = TRUE; -+} -+ -+static void complete_deactivation(struct fp_img_dev *dev) -+{ -+ struct aes1610_dev *aesdev = dev->priv; -+ fp_dbg(""); -+ -+ /* FIXME: if we're in the middle of a scan, we should cancel the scan. -+ * maybe we can do this with a master reset, unconditionally? */ -+ -+ aesdev->deactivating = FALSE; -+ g_slist_free(aesdev->strips); -+ aesdev->strips = NULL; -+ aesdev->strips_len = 0; -+ aesdev->blanks_count = 0; -+ fpi_imgdev_deactivate_complete(dev); -+} -+ -+static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) -+{ -+ /* FIXME check endpoints */ -+ 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 aes1610_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 = 0x1600 }, -+ { .vendor = 0x08ff, .product = 0x1600 }, /* AES1600 */ - { 0, 0, 0, }, - }; - -@@ -544,9 +1122,9 @@ struct fp_img_driver aes1610_driver = { - * area) */ - .bz3_threshold = 10, - -- .init = dev_init, -- .exit = dev_exit, -- .await_finger_on = await_finger_on, -- .capture = capture, -+ .open = dev_init, -+ .close = dev_deinit, -+ .activate = dev_activate, -+ .deactivate = dev_deactivate, - }; - diff --git a/libfprint.spec b/libfprint.spec index 006c07d..978f0dc 100644 --- a/libfprint.spec +++ b/libfprint.spec @@ -1,20 +1,13 @@ Name: libfprint -Version: 0.1.0 -Release: 16.pre3%{?dist} +Version: 0.2.0 +Release: 1%{?dist} Summary: Tool kit for fingerprint scanner Group: System Environment/Libraries License: LGPLv2+ URL: http://www.reactivated.net/fprint/wiki/Main_Page -Source0: http://downloads.sourceforge.net/fprint/%{name}-0.1.0-pre2.tar.bz2 +Source0: http://freedesktop.org/~hadess/%{name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -# http://thread.gmane.org/gmane.linux.fprint/1321 -Patch1: 0001-Add-udev-rules-to-set-devices-to-autosuspend.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=472103 -Patch2: 0001-Add-gdk-pixbuf-support.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=499732 -Source1: aes1610.c -Patch3: libfprint-aes1610-driver.patch ExcludeArch: s390 s390x BuildRequires: libusb1-devel glib2-devel gtk2-devel openssl-devel @@ -38,14 +31,9 @@ developing applications that use %{name}. %prep -%setup -q -n %{name}-0.1.0-pre2 -%patch1 -p1 -%patch2 -p1 -cp -a %{SOURCE1} libfprint/drivers -%patch3 -p1 -b .aes1610 +%setup -q %build -autoreconf -f -i %configure --disable-static make %{?_smp_mflags} pushd doc @@ -82,6 +70,9 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/pkgconfig/%{name}.pc %changelog +* Thu Aug 19 2010 Bastien Nocera 0.2.0-1 +- Update to 0.2.0 + * Wed Jun 30 2010 Matthew Garrett 0.1.0-16.pre3 - Fix #505438 to avoid message on boot on some systems diff --git a/sources b/sources index 8d7ca8e..5b47199 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f0e7fb9438fe17fba642fe59778d668e libfprint-0.1.0-pre2.tar.bz2 +f4cd1daf59b79f4f02ee77f0603189e9 libfprint-0.2.0.tar.bz2