diff --git a/configure.ac b/configure.ac index 58ea9e9..830e749 100644 --- a/configure.ac +++ b/configure.ac @@ -25,6 +25,9 @@ AC_SUBST(lt_age) all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes3500 aes4000 vfs101 vfs301 vfs5011 upektc_img etes603 vfs0050" +# XXX: VCS +all_drivers="$all_drivers vcs" + require_imaging='no' require_aeslib='no' require_aesX660='no' @@ -50,6 +53,9 @@ enable_upektc_img='no' enable_etes603='no' enable_vfs0050='no' +# XXX: VCS +enable_vcs='no' + AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [List of drivers to enable])], [drivers="$withval"], @@ -155,6 +161,12 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do AC_DEFINE([ENABLE_VFS0050], [], [Build Validity VFS0050 driver]) enable_vfs0050="yes" ;; + + # XXX: VCS + vcs) + AC_DEFINE([ENABLE_VCS], [], [Build Validity Sensors driver]) + enable_vcs="yes" + ;; esac done @@ -182,6 +194,9 @@ AM_CONDITIONAL([ENABLE_UPEKTC_IMG], [test "$enable_upektc_img" = "yes"]) AM_CONDITIONAL([ENABLE_ETES603], [test "$enable_etes603" = "yes"]) AM_CONDITIONAL([ENABLE_VFS0050], [test "$enable_vfs0050" = "yes"]) +# XXX: VCS +AM_CONDITIONAL([ENABLE_VCS], [test "$enable_vcs" = "yes"]) + PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) AC_SUBST(LIBUSB_CFLAGS) @@ -407,6 +422,14 @@ if test x$enable_vfs0050 != xno ; then else AC_MSG_NOTICE([ vfs0050 driver disabled]) fi + +# XXX: VCS +if test x$enable_vcs != xno ; then + AC_MSG_NOTICE([** validity sensors driver enabled]) +else + AC_MSG_NOTICE([ validity sensors driver disabled]) +fi + if test x$require_aeslib != xno ; then AC_MSG_NOTICE([** aeslib helper functions enabled]) else diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index a7fb162..a473179 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -23,6 +23,11 @@ UPEKTC_IMG_SRC = drivers/upektc_img.c drivers/upektc_img.h ETES603_SRC = drivers/etes603.c VFS0050_SRC = drivers/vfs0050.c drivers/vfs0050.h +# XXX: VCS +VCS_SRCS = drivers/validity/vfsDriver.c \ + drivers/validity/vfsDriver.h \ + drivers/validity/vfsWrapper.h + EXTRA_DIST = \ $(UPEKE2_SRC) \ $(UPEKTS_SRC) \ @@ -37,6 +42,7 @@ EXTRA_DIST = \ $(AES3500_SRC) \ $(AES4000_SRC) \ $(FDU2000_SRC) \ + $(VCS_SRCS) \ $(VCOM5S_SRC) \ $(VFS101_SRC) \ $(VFS301_SRC) \ @@ -190,6 +196,12 @@ if ENABLE_VFS0050 DRIVER_SRC += $(VFS0050_SRC) endif + +# XXX: VCS +if ENABLE_VCS +DRIVER_SRC += $(VCS_SRCS) +endif + if REQUIRE_PIXMAN OTHER_SRC += pixman.c libfprint_la_CFLAGS += $(IMAGING_CFLAGS) diff --git a/libfprint/core.c b/libfprint/core.c index 8b6fe43..5e28d63 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -405,6 +405,11 @@ static struct fp_img_driver * const img_drivers[] = { &fdu2000_driver, #endif */ + +/* XXX: VCS */ +#ifdef ENABLE_VCS + &validity_driver, +#endif }; static void register_drivers(void) diff --git a/libfprint/drivers/validity/vfsDriver.c b/libfprint/drivers/validity/vfsDriver.c new file mode 100644 index 0000000..ebc0f7e --- /dev/null +++ b/libfprint/drivers/validity/vfsDriver.c @@ -0,0 +1,288 @@ + + +/*! @file vfsDriver.c +******************************************************************************* +* libfprint Interface Functions +* +* This file contains the libfprint interface functions for validity fingerprint sensor device. +* +* Copyright 2006 Validity Sensors, Inc. + +* 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 +#include +#include +#include +#include "vfsDriver.h" +#include "vfsWrapper.h" +#include + +/* Maximum image height */ +#define VFS_IMG_MAX_HEIGHT 1023 + +/* Minimum image height */ +#define VFS_IMG_MIN_HEIGHT 200 + +/* Number of enroll stages */ +#define VFS_NR_ENROLL 1 + +#define VAL_MIN_ACCEPTABLE_MINUTIAE (2*MIN_ACCEPTABLE_MINUTIAE) +#define VAL_DEFAULT_THRESHOLD 60 + +static const struct usb_id id_table[] = { + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_301, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_451, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_5111, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_5011, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_471, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_5131, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_491, }, + { .vendor = VALIDITY_VENDOR_ID, .product = VALIDITY_PRODUCT_ID_495, }, + { 0, 0, 0, }, /* terminating entry */ +}; + +#define VFS_ASSERT(_state, _message, _err) ({ \ + if (__builtin_expect(!(_state), 0)) \ + { \ + fp_err((_message)); \ + fpi_imgdev_session_error(dev, (_err)); \ + if (img) \ + { \ + fp_img_free(img); \ + } \ + result = (_err); \ + goto cleanup; \ + } \ +}) + +static int vfs_extract_image(struct fp_img_dev *dev, + void *const handle, + struct fp_img *img, + const size_t data_len) +{ + validity_dev *vdev = dev->priv; + unsigned char *data; + + vfs_get_img_width_t vfs_get_img_width; + vfs_get_img_height_t vfs_get_img_height; + vfs_get_img_data_t vfs_get_img_data; + vfs_free_img_data_t vfs_free_img_data; + + vfs_get_img_width = dlsym(handle, "vfs_get_img_width"); + if (__builtin_expect(!vfs_get_img_width, 0)) + { + fp_err(dlerror()); + return -ENODEV; + } + + img->width =(* vfs_get_img_width)(vdev); + + vfs_get_img_height = dlsym(handle, "vfs_get_img_height"); + if (__builtin_expect(!vfs_get_img_height, 0)) + { + fp_err(dlerror()); + return -ENODEV; + } + + img->height =(*vfs_get_img_height)(vdev); + + fp_dbg("%d x %d image returned\n", img->width, img->height ); + + vfs_get_img_data = dlsym(handle, "vfs_get_img_data"); + if (__builtin_expect(!vfs_get_img_data, 0)) + { + fp_err(dlerror()); + return -ENODEV; + } + + data =(*vfs_get_img_data)(vdev); + + if (data) + { + g_memmove(img->data, data, data_len); + + img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED; + + vfs_free_img_data = dlsym(handle, "vfs_free_img_data"); + if (__builtin_expect(!vfs_free_img_data, 0)) + { + fp_err(dlerror()); + return -ENODEV; + } + + (*vfs_free_img_data)(data); + } + else + { + fp_err("Failed to get finger print image data"); + return -ENODATA; + } + + return 0; +} + +/* Activate device */ +static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +{ + validity_dev *vdev = dev->priv; + void *handle; + size_t data_len; + struct fp_img *img = NULL; + int result = 0; + + vfs_wait_for_service_t vfs_wait_for_service; + vfs_set_matcher_type_t vfs_set_matcher_type; + vfs_dev_init_t vfs_dev_init; + vfs_capture_t vfs_capture; + vfs_get_img_datasize_t vfs_get_img_datasize; + vfs_clean_handles_t vfs_clean_handles; + vfs_dev_exit_t vfs_dev_exit; + + /* Notify activate complete */ + fpi_imgdev_activate_complete(dev, 0); + + handle = dlopen("libvfsFprintWrapper.so", + RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE); + VFS_ASSERT(handle, dlerror(), -ENODEV); + + /* wait for validity device to come up and be ready to take a finger swipe + * Wait will happen for a stipulated time(10s - 40s), then errors + */ + vfs_wait_for_service = dlsym(handle, "vfs_wait_for_service"); + VFS_ASSERT(vfs_wait_for_service, dlerror(), -ENODEV); + + result = (*vfs_wait_for_service)(); + VFS_ASSERT(result == VFS_RESULT_WRAPPER_OK, + "VFS module failed to wait for service", -EPERM); + + /* Set the matcher type */ + vfs_set_matcher_type = dlsym(handle, "vfs_set_matcher_type"); + VFS_ASSERT(vfs_set_matcher_type, dlerror(), -ENODEV); + + (*vfs_set_matcher_type)(VFS_FPRINT_MATCHER); + + vfs_dev_init = dlsym(handle, "vfs_dev_init"); + VFS_ASSERT(vfs_dev_init, dlerror(), -ENODEV); + + result = (*vfs_dev_init)(vdev); + VFS_ASSERT(result == VFS_RESULT_WRAPPER_OK, + "VFS module failed to initialize", -EPERM); + + vfs_capture = dlsym(handle, "vfs_capture"); + VFS_ASSERT(vfs_capture, dlerror(), -ENODEV); + + result = (*vfs_capture)(vdev, 1); + VFS_ASSERT(result == VFS_FP_CAPTURE_COMPLETE, + "Could not capture fingerprint", -EIO); + + vfs_get_img_datasize = dlsym(handle, "vfs_get_img_datasize"); + VFS_ASSERT(vfs_get_img_datasize, dlerror(), -ENODEV); + + data_len = (*vfs_get_img_datasize)(vdev); + VFS_ASSERT(data_len, "Zero image size", -ENOMEM); + + img = fpi_img_new(data_len); + VFS_ASSERT(img, "Could not get new fpi img", -ENOMEM); + + /* Fingerprint is present, load image from reader */ + fpi_imgdev_report_finger_status(dev, TRUE); + + result = vfs_extract_image(dev, handle, img, data_len); + VFS_ASSERT(!result, "", result); + + fpi_imgdev_image_captured(dev, img); + + /* NOTE: finger off is expected only after submitting image... */ + fpi_imgdev_report_finger_status(dev, FALSE); + + result = 0; + +cleanup: + if (result != -ENODEV) + { + vfs_clean_handles = dlsym(handle, "vfs_clean_handles"); + if (vfs_clean_handles) + { + (*vfs_clean_handles)(vdev); + } + + vfs_dev_exit = dlsym(handle, "vfs_dev_exit"); + if (vfs_dev_exit) + { + (*vfs_dev_exit)(vdev); + } + } + + dlclose(handle); + + return result; +} + +/* 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) +{ + validity_dev *vdev = NULL; + + /* Set enroll stage number */ + dev->dev->nr_enroll_stages = VFS_NR_ENROLL; + + /* Initialize private structure */ + vdev = g_malloc0(sizeof(validity_dev)); + dev->priv = vdev; + + /* Notify open complete */ + fpi_imgdev_open_complete(dev, 0); + + return 0; +} + +static void dev_close(struct fp_img_dev *dev) +{ + /* Release private structure */ + g_free(dev->priv); + + /* Notify close complete */ + fpi_imgdev_close_complete(dev); +} + +struct fp_img_driver validity_driver = { + .driver = { + .id = VALIDITY_DRIVER_ID, + .name = VALIDITY_FP_COMPONENT, + .full_name = VALIDITY_DRIVER_FULLNAME, + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + + /* Image specification */ + .flags = 0, + .img_width = -1, + .img_height = -1, + + .open = dev_open, + .close = dev_close, + .activate = dev_activate, + .deactivate = dev_deactivate +}; + diff --git a/libfprint/drivers/validity/vfsDriver.h b/libfprint/drivers/validity/vfsDriver.h new file mode 100644 index 0000000..81be112 --- /dev/null +++ b/libfprint/drivers/validity/vfsDriver.h @@ -0,0 +1,65 @@ + +/*! @file vfsDriver.h +******************************************************************************* +* libfprint Interface Functions +* +* This file contains the libfprint interface functions and definitions +* +* Copyright 2006 Validity Sensors, Inc. + +* 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 __vfsDriver_h__ +#define __vcsDriver_h__ + +#define VCS_MAX_FINGER 10 +#define VALIDITY_DRIVER_ID 10 +#define VALIDITY_VENDOR_ID 0x138A +#define VALIDITY_PRODUCT_ID_301 0x0005 +#define VALIDITY_PRODUCT_ID_451 0x0007 +#define VALIDITY_PRODUCT_ID_5111 0x0010 +#define VALIDITY_PRODUCT_ID_5011 0x0011 +#define VALIDITY_PRODUCT_ID_471 0x003c +#define VALIDITY_PRODUCT_ID_5131 0x0018 +#define VALIDITY_PRODUCT_ID_491 0x003d +#define VALIDITY_PRODUCT_ID_495 0x003f +#define VALIDITY_DRIVER_FULLNAME "Validity Sensors" +#define VALIDITY_FP_COMPONENT "Validity" +#define MAX_ENROLLMENT_PRINTS 3 +#define MAX_TEMPLATES 10 +#define VFS_NT_MATCHER 1 +#define VFS_COGENT_MATCHER 2 +#define VFS_FPRINT_MATCHER 3 + +#define VFS_RESULT_WRAPPER_OK 0 + +enum vfs_fp_capture_result +{ + VFS_FP_CAPTURE_ERROR = -1, + VFS_FP_CAPTURE_COMPLETE = 1, + VFS_FP_CAPTURE_FAIL +}; + +typedef struct validity_dev_s +{ + void *pValidityCtx; + void *hImage; + void *pEnrollData; +}validity_dev; + +#endif // __vfsDriver_h__ + + diff --git a/libfprint/drivers/validity/vfsWrapper.h b/libfprint/drivers/validity/vfsWrapper.h new file mode 100644 index 0000000..55d1f43 --- /dev/null +++ b/libfprint/drivers/validity/vfsWrapper.h @@ -0,0 +1,39 @@ +/******************************************************************************* +* Helper functions for Validity driver interface functions +* +* This file contains the Helper functions for Validity driver interface functions +* and their definitions +* +* Copyright 2006 Validity Sensors, Inc. +* +* 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 __vfsWrapper_h__ +#define __vfsWrapper_h__ + +typedef int (*vfs_dev_init_t)(void *); +typedef int (*vfs_wait_for_service_t)(void); +typedef int (*vfs_set_matcher_type_t)(int); +typedef int (*vfs_capture_t)(void *, int); +typedef int (*vfs_get_img_datasize_t) (void *); +typedef int (*vfs_get_img_width_t) (void *); +typedef int (*vfs_get_img_height_t) (void *); +typedef unsigned char* (*vfs_get_img_data_t)(void *); +typedef void (*vfs_free_img_data_t)(unsigned char *); +typedef void (*vfs_clean_handles_t)(void *); +typedef void (*vfs_dev_exit_t)(void *); + +#endif /*vfsWrapper */ diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index e309ea9..2310d03 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -233,6 +233,9 @@ enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv); /* flags for fp_img_driver.flags */ #define FP_IMGDRV_SUPPORTS_UNCONDITIONAL_CAPTURE (1 << 0) +#define BOZORTH3_DEFAULT_THRESHOLD 40 +#define MIN_ACCEPTABLE_MINUTIAE 10 + struct fp_img_driver { struct fp_driver driver; uint16_t flags; @@ -309,6 +312,11 @@ extern struct fp_img_driver etes603_driver; extern struct fp_img_driver vfs0050_driver; #endif +/* XXX: VCS */ +#ifdef ENABLE_VCS +extern struct fp_img_driver validity_driver; +#endif + extern libusb_context *fpi_usb_ctx; extern GSList *opened_devices;