diff --git a/AUTHORS b/AUTHORS index 6ce0375d..2b9f2676 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,3 +8,4 @@ Copyright (C) 2007-2008,2012 Vasily Khoruzhick Copyright (C) 2007 Jan-Michael Brummer Copyright (C) 2007 Anthony Bretaudeau Copyright (C) 2010 Hugo Grostabussiat +Copyright (C) 2012 Timo Teräs diff --git a/NEWS b/NEWS index fc99c1a5..c9d2b9ce 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,17 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2013-08-11: v0.5.1 release + +* Drivers + - Add support for 147e:2020 to upeke2 driver + - Fix possible race condition, and cancellation in uru4000 driver + +* Udev rules: + - Add Microsoft keyboard to the suspend blacklist + +* Plenty of build fixes + 2012-12-03: v0.5.0 release * Drivers: diff --git a/configure.ac b/configure.ac index 3c779f40..d4536f69 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ -AC_INIT([libfprint], [0.5.0]) +AC_INIT([libfprint], [0.5.1]) 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]) +AC_CONFIG_HEADERS([config.h]) # Enable silent build when available (Automake 1.11) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) @@ -156,7 +156,7 @@ PKG_CHECK_MODULES(CRYPTO, nss) AC_SUBST(CRYPTO_CFLAGS) AC_SUBST(CRYPTO_LIBS) -PKG_CHECK_MODULES(GLIB, "glib-2.0") +PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.28]) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) @@ -173,6 +173,10 @@ AC_ARG_ENABLE(udev-rules, [ENABLE_UDEV_RULES=yes]) dnl Default value AM_CONDITIONAL(ENABLE_UDEV_RULES, test x$ENABLE_UDEV_RULES = "xyes") +if test $ENABLE_UDEV_RULES = no && test -d .git/ ; then + AC_MSG_ERROR(--disable-udev-rules can only be used when building from tarballs) +fi + 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], @@ -260,7 +264,7 @@ fi # Restore gnu89 inline semantics on gcc 4.3 and newer saved_cflags="$CFLAGS" CFLAGS="$CFLAGS -fgnu89-inline" -AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="") +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])], inline_cflags="-fgnu89-inline", inline_cflags="") CFLAGS="$saved_cflags" AC_DEFINE([API_EXPORTED], [__attribute__((visibility("default")))], [Default visibility]) diff --git a/examples/Makefile.am b/examples/Makefile.am index b045ddb0..8aa486c5 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I$(top_srcdir) +AM_CFLAGS = -I$(top_srcdir) noinst_PROGRAMS = verify_live enroll verify img_capture cpp-test verify_live_SOURCES = verify_live.c diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 7a167825..4dee3011 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -88,7 +88,7 @@ libfprint_la_LIBADD = -lm $(LIBUSB_LIBS) $(GLIB_LIBS) $(CRYPTO_LIBS) 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 +fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la $(GLIB_LIBS) udev_rules_DATA = 60-fprint-autosuspend.rules diff --git a/libfprint/data.c b/libfprint/data.c index 3371a0c2..bfbf8fb5 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -97,9 +97,8 @@ static const char *finger_num_to_str(enum fp_finger finger) static struct fp_print_data *print_data_new(uint16_t driver_id, uint32_t devtype, enum fp_print_data_type type, size_t length) { - struct fp_print_data *data = g_malloc(sizeof(*data) + length); + struct fp_print_data *data = g_malloc0(sizeof(*data) + length); fp_dbg("length=%zd driver=%02x devtype=%04x", length, driver_id, devtype); - memset(data, 0, sizeof(*data)); data->driver_id = driver_id; data->devtype = devtype; data->type = type; diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index e647ea56..250ca52d 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -48,16 +48,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) } 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); diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 96ce5900..dcfbc824 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -215,10 +215,6 @@ static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data) 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++; diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index bc1dd007..4be7475d 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -47,16 +47,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) } 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; diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index ff4f50c5..d030d0e7 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -278,10 +278,6 @@ static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) 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]); diff --git a/libfprint/drivers/upeke2.c b/libfprint/drivers/upeke2.c index ed8f43d1..a7db54d2 100644 --- a/libfprint/drivers/upeke2.c +++ b/libfprint/drivers/upeke2.c @@ -46,6 +46,11 @@ #define MSG_READ_BUF_SIZE 0x40 #define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9) +enum { + UPEKE2_2016, + UPEKE2_2020, +}; + struct upeke2_dev { gboolean enroll_passed; gboolean first_verify_iteration; @@ -848,8 +853,10 @@ static struct fpi_ssm *deinitsm_new(struct fp_dev *dev) static int discover(struct libusb_device_descriptor *dsc, uint32_t *devtype) { - /* Revision 2 is what we're interested in */ - if (dsc->bcdDevice == 2) + if (dsc->idProduct == 0x2016 && dsc->bcdDevice == 2) + return 1; + + if (dsc->idProduct == 0x2020 && dsc->bcdDevice == 1) return 1; return 0; @@ -1453,7 +1460,8 @@ static int verify_stop(struct fp_dev *dev, gboolean iterating) } static const struct usb_id id_table[] = { - { .vendor = 0x147e, .product = 0x2016 }, + { .vendor = 0x147e, .product = 0x2016, .driver_data = UPEKE2_2016 }, + { .vendor = 0x147e, .product = 0x2020, .driver_data = UPEKE2_2020 }, { 0, 0, 0, }, /* terminating entry */ }; diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 541245a2..ccaa87f8 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -789,15 +789,18 @@ static void imaging_complete(struct fpi_ssm *ssm) int r = ssm->error; fpi_ssm_free(ssm); + /* Report error before exiting imaging loop - the error handler + * can request state change, which needs to be postponed to end of + * this function. */ + if (r) + fpi_imgdev_session_error(dev, r); + 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); @@ -994,16 +997,19 @@ static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status, uint16_t type, void *user_data) { struct fpi_ssm *ssm = user_data; + struct uru4k_dev *urudev = dev->priv; if (status) fpi_ssm_mark_aborted(ssm, status); else if (type != IRQDATA_SCANPWR_ON) fp_dbg("ignoring interrupt"); - else if (ssm->cur_state != INIT_AWAIT_SCAN_POWER) - fp_err("ignoring scanpwr interrupt due to being in wrong state %d", - ssm->cur_state); - else + else if (ssm->cur_state != INIT_AWAIT_SCAN_POWER) { + fp_dbg("early scanpwr interrupt"); + urudev->scanpwr_irq_timeouts = -1; + } else { + fp_dbg("late scanpwr interrupt"); fpi_ssm_next_state(ssm); + } } static void init_scanpwr_timeout(void *user_data) @@ -1053,14 +1059,21 @@ static void init_run_state(struct fpi_ssm *ssm) fpi_ssm_next_state(ssm); break; case INIT_POWERUP: ; + if (!IRQ_HANDLER_IS_RUNNING(urudev)) { + fpi_ssm_mark_aborted(ssm, -EIO); + break; + } + urudev->irq_cb_data = ssm; + urudev->irq_cb = init_scanpwr_irq_cb; + struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state, POWERUP_NUM_STATES); powerupsm->priv = dev; fpi_ssm_start_subsm(ssm, powerupsm); break; case INIT_AWAIT_SCAN_POWER: - if (!IRQ_HANDLER_IS_RUNNING(urudev)) { - fpi_ssm_mark_aborted(ssm, -EIO); + if (urudev->scanpwr_irq_timeouts < 0) { + fpi_ssm_next_state(ssm); break; } @@ -1073,13 +1086,12 @@ static void init_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ETIME); break; } - - urudev->irq_cb_data = ssm; - urudev->irq_cb = init_scanpwr_irq_cb; break; case INIT_DONE: - fpi_timeout_cancel(urudev->scanpwr_irq_timeout); - urudev->scanpwr_irq_timeout = NULL; + if (urudev->scanpwr_irq_timeout) { + fpi_timeout_cancel(urudev->scanpwr_irq_timeout); + urudev->scanpwr_irq_timeout = NULL; + } urudev->irq_cb_data = NULL; urudev->irq_cb = NULL; fpi_ssm_next_state(ssm); diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c index 791a4575..71c0b598 100644 --- a/libfprint/fprint-list-udev-rules.c +++ b/libfprint/fprint-list-udev-rules.c @@ -30,6 +30,8 @@ static const struct usb_id whitelist_id_table[] = { static const struct usb_id blacklist_id_table[] = { { .vendor = 0x0483, .product = 0x2016 }, + /* https://bugs.freedesktop.org/show_bug.cgi?id=66659 */ + { .vendor = 0x045e, .product = 0x00bb }, { 0, 0, 0 }, }; @@ -52,7 +54,7 @@ static void print_driver (struct fp_driver *driver) 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) { + driver->id_table[i].product == blacklist_id_table[j].product) { blacklist = 1; break; } diff --git a/libfprint/img.c b/libfprint/img.c index 64a6240b..b1d32edc 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -47,8 +47,7 @@ struct fp_img *fpi_img_new(size_t length) { - struct fp_img *img = g_malloc(sizeof(*img) + length); - memset(img, 0, sizeof(*img)); + struct fp_img *img = g_malloc0(sizeof(*img) + length); fp_dbg("length=%zd", length); img->length = length; return img; diff --git a/libfprint/imgdev.c b/libfprint/imgdev.c index 14e41ae7..1ed3f6dd 100644 --- a/libfprint/imgdev.c +++ b/libfprint/imgdev.c @@ -145,7 +145,10 @@ void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, case IMG_ACTION_ENROLL: fp_dbg("reporting enroll result"); fpi_drvcb_enroll_stage_completed(imgdev->dev, r, data, img); - if (r > 0 && r != FP_ENROLL_COMPLETE && r != FP_ENROLL_FAIL) { + /* the callback can cancel enrollment, so recheck current + * action and the status to see if retry is needed */ + if (imgdev->action == IMG_ACTION_ENROLL && + r > 0 && r != FP_ENROLL_COMPLETE && r != FP_ENROLL_FAIL) { imgdev->action_result = 0; imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_ON; dev_change_state(imgdev, IMG_ACQUIRE_STATE_AWAIT_FINGER_ON);