diff --git a/.ci/check-abi b/.ci/check-abi new file mode 100755 index 00000000..06eb1aca --- /dev/null +++ b/.ci/check-abi @@ -0,0 +1,113 @@ +#!/usr/bin/python3 + + +import argparse +import contextlib +import os +import shutil +import subprocess +import sys + + +def format_title(title): + box = { + 'tl': '╔', 'tr': '╗', 'bl': '╚', 'br': '╝', 'h': '═', 'v': '║', + } + hline = box['h'] * (len(title) + 2) + + return '\n'.join([ + f"{box['tl']}{hline}{box['tr']}", + f"{box['v']} {title} {box['v']}", + f"{box['bl']}{hline}{box['br']}", + ]) + + +def rm_rf(path): + try: + shutil.rmtree(path) + except FileNotFoundError: + pass + + +def sanitize_path(name): + return name.replace('/', '-') + + +def get_current_revision(): + revision = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], + encoding='utf-8').strip() + + if revision == 'HEAD': + # This is a detached HEAD, get the commit hash + revision = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8') + + return revision + + +@contextlib.contextmanager +def checkout_git_revision(revision): + current_revision = get_current_revision() + subprocess.check_call(['git', 'checkout', '-q', revision]) + + try: + yield + finally: + subprocess.check_call(['git', 'checkout', '-q', current_revision]) + + +def build_install(revision): + build_dir = '_build' + dest_dir = os.path.abspath(sanitize_path(revision)) + print(format_title(f'# Building and installing {revision} in {dest_dir}'), + end='\n\n', flush=True) + + with checkout_git_revision(revision): + rm_rf(build_dir) + rm_rf(revision) + + subprocess.check_call(['meson', build_dir, + '--prefix=/usr', '--libdir=lib', + '-Dx11-examples=false', '-Ddoc=false', '-Dgtk-examples=false']) + subprocess.check_call(['ninja', '-v', '-C', build_dir]) + subprocess.check_call(['ninja', '-v', '-C', build_dir, 'install'], + env={'DESTDIR': dest_dir}) + + return dest_dir + + +def compare(old_tree, new_tree): + print(format_title(f'# Comparing the two ABIs'), end='\n\n', flush=True) + + old_headers = os.path.join(old_tree, 'usr', 'include') + old_lib = os.path.join(old_tree, 'usr', 'lib', 'libfprint.so') + + new_headers = os.path.join(new_tree, 'usr', 'include') + new_lib = os.path.join(new_tree, 'usr', 'lib', 'libfprint.so') + + subprocess.check_call([ + 'abidiff', '--headers-dir1', old_headers, '--headers-dir2', new_headers, + '--drop-private-types', '--fail-no-debug-info', '--no-added-syms', old_lib, new_lib]) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + + parser.add_argument('old', help='the previous revision, considered the reference') + parser.add_argument('new', help='the new revision, to compare to the reference') + + args = parser.parse_args() + + if args.old == args.new: + print("Let's not waste time comparing something to itself") + sys.exit(0) + + old_tree = build_install(args.old) + new_tree = build_install(args.new) + + try: + compare(old_tree, new_tree) + + except Exception: + sys.exit(1) + + print(f'Hurray! {args.old} and {args.new} are ABI-compatible!') diff --git a/HACKING.md b/HACKING.md index e43cbf2b..21e17a4b 100644 --- a/HACKING.md +++ b/HACKING.md @@ -3,8 +3,29 @@ ## GLib Although the library uses GLib internally, libfprint is designed to provide -a completely neutral interface to it's application users. So, the public -APIs should never return GLib data types or anything like that. +a completely neutral interface to its application users. So, the public +APIs should never return GLib data types. + +## License clarification + +Although this library's license could allow for shims that hook up into +proprietary blobs to add driver support for some unsupported devices, the +intent of the original authors, and of current maintainers of the library, +was for this license to allow _integration into_ proprietary stacks, not +_integration of_ proprietary code in the library. + +As such, no code to integrate proprietary drivers will be accepted in libfprint +upstream. Proprietary drivers would make it impossible to debug problems in +libfprint, as we wouldn't know what the proprietary driver does behind the +library's back. The closed source nature of drivers is usually used to hide +parts of the hardware setup, such as encryption keys, or protocols, in order +to protect the hardware's integrity. Unfortunately, this is only [security through +obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity). + +We however encourage potential contributors to take advantage of libfprint's +source availability to create such shims to make it easier to reverse-engineer +proprietary drivers in order to create new free software drivers, to the extent +permitted by local laws. ## Two-faced-ness diff --git a/NEWS b/NEWS index 34d6cc2e..ba0ccc3d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,33 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2019-08-08: v1.0 release +* Library: + - Add guards to the public API and require GLib 2.50 + - Deprecate print storage API + - Better documentation for fp_discover_devs() + - Remove unused internal fpi_timeout_cancel_for_dev() + - Remove state from fp_img_driver activate handler + - Bug fixes related to restarting a failed verification immediately + +* Drivers: + - The Elan driver received a lot of bug fixes including a fix for a + hang when verifying prints with fprintd, quirks for some devices, + a memory leak fix and support for 04f3:0c42 + - Fix a probable crash in all the AES drivers + - Add support for Lenovo Preferred Pro Keyboard (KUF1256) to vfs5011 + - Prevent hang during enroll process in etes603 driver + - Fix possible integer overflow in uru4000 + - Work-around SELinux AVC warnings when uru4000 driver starts + - Remove long-unmaintained and broken fdu2000 driver + +* Tools/Examples: + - Fix examples not working due to an overly strict check + - Fix crash in GTK demo when there's no supported devices + - Disable GTK demo until we have a USB Flatpak portal + - Remove sleep() in enroll example which caused a crash in some drivers + - Add a simple storage implementation example + 2018-12-14: v0.99.0 release * Library: - All the internal API for device driver writers is now covered by the diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 00000000..a429a426 --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,3 @@ +This project and its community follow the [Freedesktop.org code of conduct] + +[Freedesktop.org code of conduct]: https://www.freedesktop.org/wiki/CodeOfConduct/ diff --git a/demo/gtk-libfprint-test.c b/demo/gtk-libfprint-test.c index b23e38dd..d0dd0c1e 100644 --- a/demo/gtk-libfprint-test.c +++ b/demo/gtk-libfprint-test.c @@ -473,8 +473,17 @@ libfprint_demo_window_init (LibfprintDemoWindow *window) setup_pollfds (); discovered_devs = fp_discover_devs(); - if (!discovered_devs) + if (!discovered_devs) { + libfprint_demo_set_mode (window, ERROR_MODE); return; + } + + /* Empty list? */ + if (discovered_devs[0] == NULL) { + fp_dscv_devs_free (discovered_devs); + libfprint_demo_set_mode (window, EMPTY_MODE); + return; + } if (!fp_driver_supports_imaging(fp_dscv_dev_get_driver(discovered_devs[0]))) { libfprint_demo_set_mode (window, NOIMAGING_MODE); diff --git a/examples/enroll.c b/examples/enroll.c index 4eea39ad..9814f68e 100644 --- a/examples/enroll.c +++ b/examples/enroll.c @@ -24,6 +24,8 @@ #include +#include "storage.h" + struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) { struct fp_dscv_dev *ddev = discovered_devs[0]; @@ -45,8 +47,7 @@ struct fp_print_data *enroll(struct fp_dev *dev) { do { struct fp_img *img = NULL; - - sleep(1); + printf("\nScan your finger now.\n"); r = fp_enroll_finger_img(dev, &enrolled_print, &img); @@ -143,7 +144,7 @@ int main(void) if (!data) goto out_close; - r = fp_print_data_save(data, RIGHT_INDEX); + r = print_data_save(data, RIGHT_INDEX); if (r < 0) fprintf(stderr, "Data save failed, code %d\n", r); diff --git a/examples/meson.build b/examples/meson.build index cba326fb..7596be64 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -2,8 +2,8 @@ examples = [ 'verify_live', 'enroll', 'verify', 'img_capture' ] foreach example: examples executable(example, - example + '.c', - dependencies: libfprint_dep, + [example + '.c', 'storage.c'], + dependencies: [libfprint_dep, glib_dep], include_directories: [ root_inc, ], diff --git a/examples/storage.c b/examples/storage.c new file mode 100644 index 00000000..aa399e0f --- /dev/null +++ b/examples/storage.c @@ -0,0 +1,136 @@ +/* + * Trivial storage driver for example programs + * + * Copyright (C) 2019 Benjamin Berg + * + * 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 + +#define STORAGE_FILE "test-storage.variant" + +static char * +get_print_data_descriptor (struct fp_print_data *data, struct fp_dev *dev, enum fp_finger finger) +{ + gint drv_id; + gint devtype; + + if (data) { + drv_id = fp_print_data_get_driver_id (data); + devtype = fp_print_data_get_devtype (data); + } else { + drv_id = fp_driver_get_driver_id(fp_dev_get_driver (dev)); + devtype = fp_dev_get_devtype (dev); + } + + return g_strdup_printf("%x/%08x/%x", + drv_id, + devtype, + finger); +} + +static GVariantDict* +load_data(void) +{ + GVariantDict *res; + GVariant *var; + gchar *contents = NULL; + gssize length = 0; + + if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL)) { + g_warning ("Error loading storage, assuming it is empty"); + return g_variant_dict_new(NULL); + } + + var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT, contents, length, FALSE, NULL, NULL); + + res = g_variant_dict_new(var); + g_variant_unref(var); + return res; +} + +static int +save_data(GVariant *data) +{ + const gchar *contents = NULL; + gsize length; + + length = g_variant_get_size(data); + contents = (gchar*) g_variant_get_data (data); + + if (!g_file_set_contents (STORAGE_FILE, contents, length, NULL)) { + g_warning ("Error saving storage,!"); + return -1; + } + + g_variant_ref_sink(data); + g_variant_unref(data); + + return 0; +} + +int +print_data_save(struct fp_print_data *fp_data, enum fp_finger finger) +{ + gchar *descr = get_print_data_descriptor (fp_data, NULL, finger); + GVariantDict *dict; + GVariant *val; + guchar *data; + gsize size; + int res; + + dict = load_data(); + + size = fp_print_data_get_data(fp_data, &data); + val = g_variant_new_fixed_array (G_VARIANT_TYPE("y"), data, size, 1); + g_variant_dict_insert_value (dict, descr, val); + + res = save_data(g_variant_dict_end(dict)); + g_variant_dict_unref(dict); + + return res; +} + +struct fp_print_data* +print_data_load(struct fp_dev *dev, enum fp_finger finger) +{ + gchar *descr = get_print_data_descriptor (NULL, dev, finger); + GVariantDict *dict; + guchar *stored_data; + gsize stored_len; + GVariant *val; + struct fp_print_data *res = NULL; + + dict = load_data(); + val = g_variant_dict_lookup_value (dict, descr, G_VARIANT_TYPE ("ay")); + + if (val) { + stored_data = (guchar*) g_variant_get_fixed_array (val, &stored_len, 1); + res = fp_print_data_from_data(stored_data, stored_len); + + g_variant_unref(val); + } + + g_variant_dict_unref(dict); + g_free(descr); + + return res; +} diff --git a/examples/storage.h b/examples/storage.h new file mode 100644 index 00000000..fc86813e --- /dev/null +++ b/examples/storage.h @@ -0,0 +1,27 @@ +/* + * Trivial storage driver for example programs + * + * Copyright (C) 2019 Benjamin Berg + * + * 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 __STORAGE_H +#define __STORAGE_H + +int print_data_save(struct fp_print_data *fp_data, enum fp_finger finger); +struct fp_print_data* print_data_load(struct fp_dev *dev, enum fp_finger finger); + +#endif /* __STORAGE_H */ diff --git a/examples/verify.c b/examples/verify.c index 26566edd..38b925c5 100644 --- a/examples/verify.c +++ b/examples/verify.c @@ -24,6 +24,8 @@ #include +#include "storage.h" + struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) { struct fp_dscv_dev *ddev = discovered_devs[0]; @@ -117,8 +119,8 @@ int main(void) printf("Opened device. Loading previously enrolled right index finger " "data...\n"); - r = fp_print_data_load(dev, RIGHT_INDEX, &data); - if (r != 0) { + data = print_data_load(dev, RIGHT_INDEX); + if (!data) { fprintf(stderr, "Failed to load fingerprint, error %d\n", r); fprintf(stderr, "Did you remember to enroll your right index finger " "first?\n"); diff --git a/examples/verify_live.c b/examples/verify_live.c index 82ec2abc..4c02ff2f 100644 --- a/examples/verify_live.c +++ b/examples/verify_live.c @@ -43,7 +43,6 @@ struct fp_print_data *enroll(struct fp_dev *dev) { "complete the process.\n", fp_dev_get_nr_enroll_stages(dev)); do { - sleep(1); printf("\nScan your finger now.\n"); r = fp_enroll_finger(dev, &enrolled_print); if (r < 0) { diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 1e7b3b9b..df5b5695 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -404,7 +404,7 @@ static unsigned char list_BD_values[10] = { /* * Adjust the gain according to the histogram data * 0xbd, 0xbe, 0x29 and 0x2A registers are affected - * Returns 0 if no problem occured + * Returns 0 if no problem occurred * TODO: This is a basic support for gain. It needs testing/tweaking. */ static int adjust_gain(unsigned char *buffer, int status) { @@ -412,7 +412,7 @@ static int adjust_gain(unsigned char *buffer, int status) static int pos_list_BE = 0; static int pos_list_BD = 0; - // This is the first adjustement (we begin acquisition) + // This is the first adjustment (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 @@ -534,7 +534,7 @@ static void restore_gain(void) /* capture SM movement: * request and read strip, - * jump back to request UNLESS theres no finger, in which case exit SM, + * jump back to request UNLESS there's no finger, in which case exit SM, * report lack of finger presence, and move to finger detection */ enum capture_states { @@ -728,7 +728,7 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat struct fp_img_dev *dev = user_data; /* activation on aes1610 seems much more straightforward compared to aes2501 */ - /* verify theres anything missing here */ + /* verify there's anything missing here */ switch (fpi_ssm_get_cur_state(ssm)) { case WRITE_INIT: fp_dbg("write init"); @@ -749,7 +749,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d fpi_ssm_free(ssm); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct aes1610_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state, diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 2a031732..91e02a39 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -415,7 +415,7 @@ static struct aes_regwrite strip_scan_reqs[] = { /* capture SM movement: * write reqs and read data 1 + 2, * request and read strip, - * jump back to request UNLESS theres no finger, in which case exit SM, + * jump back to request UNLESS there's no finger, in which case exit SM, * report lack of finger presence, and move to finger detection */ enum capture_states { @@ -792,7 +792,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d fpi_ssm_free(ssm); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct aes2501_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state, diff --git a/libfprint/drivers/aes2501.h b/libfprint/drivers/aes2501.h index 9f2f1b6e..19adcc90 100644 --- a/libfprint/drivers/aes2501.h +++ b/libfprint/drivers/aes2501.h @@ -109,7 +109,7 @@ enum aes2501_mesure_drive { /* Select (1=square | 0=sine) wave drive during measure */ #define AES2501_MEASDRV_SQUARE 0x20 -/* 0 = use mesure drive setting, 1 = when sine wave is selected */ +/* 0 = use measure drive setting, 1 = when sine wave is selected */ #define AES2501_MEASDRV_MEASURE_SQUARE 0x10 enum aes2501_measure_freq { diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index ce5b6c2b..72a86132 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -447,7 +447,7 @@ static void init_read_data_cb(struct libusb_transfer *transfer) } /* TODO: use calibration table, datasheet is rather terse on that - * need more info for implementaion */ + * need more info for implementation */ static void calibrate_read_data_cb(struct libusb_transfer *transfer) { fpi_ssm *ssm = transfer->user_data; @@ -541,7 +541,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d fpi_ssm_free(ssm); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state, ACTIVATE_NUM_STATES, dev); diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c index 59c91bcc..ddb94c9b 100644 --- a/libfprint/drivers/aes3k.c +++ b/libfprint/drivers/aes3k.c @@ -137,7 +137,7 @@ static void init_reqs_cb(struct fp_img_dev *dev, int result, void *user_data) do_capture(dev); } -int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +int aes3k_dev_activate(struct fp_img_dev *dev) { struct aes3k_dev *aesdev = FP_INSTANCE_DATA(FP_DEV(dev)); aes_write_regv(dev, aesdev->init_reqs, aesdev->init_reqs_len, init_reqs_cb, NULL); diff --git a/libfprint/drivers/aes3k.h b/libfprint/drivers/aes3k.h index 98750ede..a54199d0 100644 --- a/libfprint/drivers/aes3k.h +++ b/libfprint/drivers/aes3k.h @@ -52,7 +52,7 @@ struct aes3k_dev { }; -int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state); +int aes3k_dev_activate(struct fp_img_dev *dev); void aes3k_dev_deactivate(struct fp_img_dev *dev); #endif diff --git a/libfprint/drivers/aeslib.c b/libfprint/drivers/aeslib.c index 1ff3986d..24e307ce 100644 --- a/libfprint/drivers/aeslib.c +++ b/libfprint/drivers/aeslib.c @@ -53,12 +53,15 @@ static void write_regv_trf_complete(struct libusb_transfer *transfer) { struct write_regv_data *wdata = transfer->user_data; - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { wdata->callback(wdata->imgdev, -EIO, wdata->user_data); - else if (transfer->length != transfer->actual_length) + g_free(wdata); + } else if (transfer->length != transfer->actual_length) { wdata->callback(wdata->imgdev, -EPROTO, wdata->user_data); - else + g_free(wdata); + } else { continue_write_regv(wdata); + } g_free(transfer->buffer); libusb_free_transfer(transfer); @@ -109,6 +112,7 @@ static void continue_write_regv(struct write_regv_data *wdata) if (offset >= wdata->num_regs) { fp_dbg("all registers written"); wdata->callback(wdata->imgdev, 0, wdata->user_data); + g_free(wdata); return; } if (wdata->regs[offset].reg) @@ -132,6 +136,7 @@ static void continue_write_regv(struct write_regv_data *wdata) r = do_write_regv(wdata, upper_bound); if (r < 0) { wdata->callback(wdata->imgdev, r, wdata->user_data); + g_free(wdata); return; } @@ -155,8 +160,6 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs, wdata->callback = callback; wdata->user_data = user_data; continue_write_regv(wdata); - - g_free(wdata); } unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx, diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 852c7509..47da51f5 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -589,7 +589,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d start_finger_detection(dev); } -int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +int aesX660_dev_activate(struct fp_img_dev *dev) { fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state, ACTIVATE_NUM_STATES, dev); diff --git a/libfprint/drivers/aesx660.h b/libfprint/drivers/aesx660.h index 2106ca2d..8d8f3501 100644 --- a/libfprint/drivers/aesx660.h +++ b/libfprint/drivers/aesx660.h @@ -116,7 +116,7 @@ static const unsigned char calibrate_cmd[] = { 0x06, }; -int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state); +int aesX660_dev_activate(struct fp_img_dev *dev); void aesX660_dev_deactivate(struct fp_img_dev *dev); #endif diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h index 8839a744..012a3d06 100644 --- a/libfprint/drivers/driver_ids.h +++ b/libfprint/drivers/driver_ids.h @@ -27,7 +27,7 @@ enum { AES2501_ID = 4, UPEKTC_ID = 5, AES1610_ID = 6, - FDU2000_ID = 7, + /* FDU2000_ID = 7, */ VCOM5S_ID = 8, UPEKSONLY_ID = 9, VFS101_ID = 10, diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index ed474b05..e9dad43e 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -293,23 +293,22 @@ static void elan_process_frame_thirds(unsigned short *raw_frame, static void elan_submit_image(struct fp_img_dev *dev) { struct elan_dev *elandev = FP_INSTANCE_DATA(FP_DEV(dev)); + int num_frames; + GSList *raw_frames; GSList *frames = NULL; struct fp_img *img; G_DEBUG_HERE(); - for (int i = 0; i < ELAN_SKIP_LAST_FRAMES; i++) - elandev->frames = g_slist_next(elandev->frames); - elandev->num_frames -= ELAN_SKIP_LAST_FRAMES; + num_frames = elandev->num_frames - ELAN_SKIP_LAST_FRAMES; + raw_frames = g_slist_nth(elandev->frames, ELAN_SKIP_LAST_FRAMES); assembling_ctx.frame_width = elandev->frame_width; assembling_ctx.frame_height = elandev->frame_height; assembling_ctx.image_width = elandev->frame_width * 3 / 2; - g_slist_foreach(elandev->frames, (GFunc) elandev->process_frame, - &frames); - fpi_do_movement_estimation(&assembling_ctx, frames, - elandev->num_frames); - img = fpi_assemble_frames(&assembling_ctx, frames, elandev->num_frames); + g_slist_foreach(raw_frames, (GFunc) elandev->process_frame, &frames); + fpi_do_movement_estimation(&assembling_ctx, frames, num_frames); + img = fpi_assemble_frames(&assembling_ctx, frames, num_frames); img->flags |= FP_IMG_PARTIAL; fpi_imgdev_image_captured(dev, img); @@ -383,6 +382,12 @@ static void elan_cmd_read(fpi_ssm *ssm, struct fp_img_dev *dev) return; } + if (elandev->dev_type == ELAN_0C42) { + /* ELAN_0C42 sends an extra byte in one byte responses */ + if (elandev->cmd->response_len == 1) + response_len = 2; + } + if (elandev->cmd->cmd == get_image_cmd.cmd) /* raw data has 2-byte "pixels" and the frame is vertical */ response_len = @@ -419,7 +424,8 @@ elan_run_cmd(fpi_ssm *ssm, elandev->cmd_timeout = cmd_timeout; if (cmd->devices != ELAN_ALL_DEV && !(cmd->devices & elandev->dev_type)) { - fp_dbg("skipping for this device"); + fp_dbg("skipping command 0x%x 0x%x for this device (for devices 0x%x but device is 0x%x)", + cmd->cmd[0], cmd->cmd[1], cmd->devices, elandev->dev_type); elan_cmd_done(ssm); return; } @@ -597,6 +603,14 @@ static int elan_need_calibration(struct elan_dev *elandev) g_assert(frame_size != 0); + if (elandev->dev_type == ELAN_0C42) { + if (calib_mean > 5500 || + calib_mean < 2500) { + fp_dbg("Forcing needed recalibration"); + return 1; + } + } + for (int i = 0; i < frame_size; i++) bg_mean += elandev->background[i]; bg_mean /= frame_size; @@ -621,6 +635,14 @@ enum calibrate_states { CALIBRATE_NUM_STATES, }; +static gboolean elan_supports_calibration(struct elan_dev *elandev) +{ + if (elandev->dev_type == ELAN_0C42) + return TRUE; + + return elandev->fw_ver >= ELAN_MIN_CALIBRATION_FW; +} + static void calibrate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) { struct fp_img_dev *dev = user_data; @@ -634,7 +656,7 @@ static void calibrate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_da break; case CALIBRATE_SAVE_BACKGROUND: elan_save_background(elandev); - if (elandev->fw_ver < ELAN_MIN_CALIBRATION_FW) { + if (!elan_supports_calibration(elandev)) { fp_dbg("FW does not support calibration"); fpi_ssm_mark_completed(ssm); } else @@ -755,6 +777,14 @@ static void activate_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_dat elandev->frame_height = elandev->raw_frame_height = elandev->last_read[0]; } + /* Work-around sensors returning the sizes as zero-based index + * rather than the number of pixels. */ + if ((elandev->frame_width % 2 == 1) && + (elandev->frame_height % 2 == 1)) { + elandev->frame_width++; + elandev->frame_height++; + elandev->raw_frame_height = elandev->frame_height; + } if (elandev->frame_height > ELAN_MAX_FRAME_HEIGHT) elandev->frame_height = ELAN_MAX_FRAME_HEIGHT; fp_dbg("sensor dimensions, WxH: %dx%d", elandev->frame_width, @@ -844,7 +874,7 @@ static void dev_deinit(struct fp_img_dev *dev) fpi_imgdev_close_complete(dev); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { G_DEBUG_HERE(); elan_activate(dev); diff --git a/libfprint/drivers/elan.h b/libfprint/drivers/elan.h index 853f31de..c5f0f191 100644 --- a/libfprint/drivers/elan.h +++ b/libfprint/drivers/elan.h @@ -31,6 +31,7 @@ /* devices with quirks */ #define ELAN_0907 (1 << 0) #define ELAN_0C03 (1 << 1) +#define ELAN_0C42 (1 << 2) /* devices which don't require frame rotation before assembling */ #define ELAN_NOT_ROTATED ELAN_0C03 @@ -55,7 +56,7 @@ /* number of frames to drop at the end of capture because frames captured * while the finger is being lifted can be bad */ -#define ELAN_SKIP_LAST_FRAMES 1 +#define ELAN_SKIP_LAST_FRAMES 2 #define ELAN_CMD_LEN 0x2 #define ELAN_EP_CMD_OUT (0x1 | LIBUSB_ENDPOINT_OUT) @@ -207,6 +208,7 @@ static const struct usb_id elan_id_table[] = { {.vendor = ELAN_VEND_ID,.product = 0x0c31,.driver_data = ELAN_ALL_DEV}, {.vendor = ELAN_VEND_ID,.product = 0x0c32,.driver_data = ELAN_ALL_DEV}, {.vendor = ELAN_VEND_ID,.product = 0x0c33,.driver_data = ELAN_ALL_DEV}, + {.vendor = ELAN_VEND_ID,.product = 0x0c42,.driver_data = ELAN_0C42}, {0, 0, 0,}, }; diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 97b6913b..f82fb05f 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -1316,7 +1316,7 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) fpi_ssm_next_state(ssm); break; case INIT_SENSOR_REQ: - /* In captured traffic, those are splitted. */ + /* In captured traffic, those are split. */ msg_set_regs(dev, 18, REG_MODE_CONTROL, REG_MODE_SLEEP, REG_50, 0x0F, REG_GAIN, 0x04, REG_VRT, 0x08, REG_VRB, 0x0D, REG_VCO_CONTROL, REG_VCO_RT, @@ -1390,19 +1390,13 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) fpi_ssm_free(ssm); } -static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *idev) { struct etes603_dev *dev = FP_INSTANCE_DATA(FP_DEV(idev)); fpi_ssm *ssm; g_assert(dev); - if (state != IMGDEV_STATE_AWAIT_FINGER_ON) { - fp_err("The driver is in an unexpected state: %d.", state); - fpi_imgdev_activate_complete(idev, 1); - return -1; - } - /* Reset info and data */ dev->is_active = TRUE; @@ -1430,8 +1424,9 @@ static void dev_deactivate(struct fp_img_dev *idev) /* this can be called even if still activated. */ if (dev->is_active == TRUE) { dev->is_active = FALSE; - m_exit_start(idev); } + + m_exit_start(idev); } static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c deleted file mode 100644 index 44b993dc..00000000 --- a/libfprint/drivers/fdu2000.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Secugen FDU2000 driver for libfprint - * Copyright (C) 2007 Gustavo Chain - * - * 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 "fdu2000" - -#include "drivers_api.h" - -#ifndef HAVE_MEMMEM -gpointer -memmem(const gpointer haystack, size_t haystack_len, const gpointer needle, size_t needle_len) { - const gchar *begin; - const char *const last_possible = (const char *) haystack + haystack_len - needle_len; - - /* The first occurrence of the empty string is deemed to occur at - * the beginning of the string. */ - if (needle_len == 0) - return (void *) haystack; - - /* Sanity check, otherwise the loop might search through the whole - * memory. */ - if (haystack_len < needle_len) - return NULL; - - for (begin = (const char *) haystack; begin <= last_possible; ++begin) - if (begin[0] == ((const char *) needle)[0] && - !memcmp((const void *) &begin[1], - (const void *) ((const char *) needle + 1), - needle_len - 1)) - return (void *) begin; - - return NULL; -} -#endif /* HAVE_MEMMEM */ - -#define EP_IMAGE ( 0x02 | LIBUSB_ENDPOINT_IN ) -#define EP_REPLY ( 0x01 | LIBUSB_ENDPOINT_IN ) -#define EP_CMD ( 0x01 | LIBUSB_ENDPOINT_OUT ) -#define BULK_TIMEOUT 200 - -/* fdu_req[] index */ -typedef enum { - CAPTURE_READY, - CAPTURE_READ, - CAPTURE_END, - LED_OFF, - LED_ON -} req_index; - - -#define CMD_LEN 2 -#define ACK_LEN 8 -static const struct fdu2000_req { - const gchar cmd[CMD_LEN]; // Command to send - const gchar ack[ACK_LEN]; // Expected ACK - const guint ack_len; // ACK has variable length -} fdu_req[] = { - /* Capture */ - { - .cmd = { 0x00, 0x04 }, - .ack = { 0x00, 0x04, 0x01, 0x01 }, - .ack_len = 4 - }, - - { - .cmd = { 0x00, 0x01 }, - .ack = { 0x00, 0x01, 0x01, 0x01 }, - .ack_len = 4 - }, - - { - .cmd = { 0x00, 0x05 }, - .ack = { 0x00, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, - .ack_len = 8 - }, - - /* Led */ - { - .cmd = { 0x05, 0x00 }, - .ack = {}, - .ack_len = 0 - }, - - { - .cmd = { 0x05, 0x01 }, - .ack = {}, - .ack_len = 0 - } -}; - -/* - * Write a command and verify reponse - */ -static gint -bulk_write_safe(libusb_dev_handle *dev, req_index rIndex) { - - gchar reponse[ACK_LEN]; - gint r; - gchar *cmd = (gchar *)fdu_req[rIndex].cmd; - gchar *ack = (gchar *)fdu_req[rIndex].ack; - gint ack_len = fdu_req[rIndex].ack_len; - struct libusb_bulk_transfer wrmsg = { - .endpoint = EP_CMD, - .data = cmd, - .length = sizeof(cmd), - }; - struct libusb_bulk_transfer readmsg = { - .endpoint = EP_REPLY, - .data = reponse, - .length = sizeof(reponse), - }; - int trf; - - r = libusb_bulk_transfer(dev, &wrmsg, &trf, BULK_TIMEOUT); - if (r < 0) - return r; - - if (ack_len == 0) - return 0; - - /* Check reply from FP */ - r = libusb_bulk_transfer(dev, &readmsg, &trf, BULK_TIMEOUT); - if (r < 0) - return r; - - if (!strncmp(ack, reponse, ack_len)) - return 0; - - fp_err("Expected different ACK from dev"); - return 1; /* Error */ -} - -static gint -capture(struct fp_img_dev *dev, gboolean unconditional, - struct fp_img **ret) -{ -#define RAW_IMAGE_WIDTH 398 -#define RAW_IMAGE_HEIGTH 301 -#define RAW_IMAGE_SIZE (RAW_IMAGE_WIDTH * RAW_IMAGE_HEIGTH) - - struct fp_img *img = NULL; - int bytes, r; - const gchar SOF[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0c, 0x07 }; // Start of frame - const gchar SOL[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0b, 0x06 }; // Start of line + { L L } (L: Line num) (8 nibbles) - gchar *buffer = g_malloc0(RAW_IMAGE_SIZE * 6); - gchar *image; - gchar *p; - guint offset; - struct libusb_bulk_transfer msg = { - .endpoint = EP_IMAGE, - .data = buffer, - .length = RAW_IMAGE_SIZE * 6, - }; - - image = g_malloc0(RAW_IMAGE_SIZE); - - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_ON))) { - fp_err("Command: LED_ON"); - goto out; - } - - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_READY))) { - fp_err("Command: CAPTURE_READY"); - goto out; - } - -read: - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_READ))) { - fp_err("Command: CAPTURE_READ"); - goto out; - } - - /* Now we are ready to read from dev */ - - r = libusb_bulk_transfer(fpi_dev_get_usb_dev(FP_DEV(dev)), &msg, &bytes, BULK_TIMEOUT * 10); - if (r < 0 || bytes < 1) - goto read; - - /* - * Find SOF (start of line) - */ - p = memmem(buffer, RAW_IMAGE_SIZE * 6, - (const gpointer)SOF, sizeof SOF); - fp_dbg("Read %d byte/s from dev", bytes); - if (!p) - goto out; - - p += sizeof SOF; - - int i = 0; - bytes = 0; - while(p) { - if ( i >= RAW_IMAGE_HEIGTH ) - break; - - offset = p - buffer; - p = memmem(p, (RAW_IMAGE_SIZE * 6) - (offset), - (const gpointer)SOL, sizeof SOL); - if (p) { - p += sizeof SOL + 4; - int j; - for (j = 0; j < RAW_IMAGE_WIDTH; j++) { - /* - * Convert from 4 to 8 bits - * The SECUGEN-FDU2000 has 4 lines of data, so we need to join 2 bytes into 1 - */ - *(image + bytes + j) = *(p + (j * 2) + 0) << 4 & 0xf0; - *(image + bytes + j) |= *(p + (j * 2) + 1) & 0x0f; - } - p += RAW_IMAGE_WIDTH * 2; - bytes += RAW_IMAGE_WIDTH; - i++; - } - } - - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))) { - fp_err("Command: CAPTURE_END"); - goto out; - } - - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_OFF))) { - fp_err("Command: LED_OFF"); - goto out; - } - - img = fpi_img_new_for_imgdev(dev); - memcpy(img->data, image, RAW_IMAGE_SIZE); - img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; - *ret = img; - -out: - g_free(buffer); - g_free(image); - - return r; -} - -static -gint dev_init(struct fp_img_dev *dev, unsigned long driver_data) -{ - gint r; - //if ( (r = usb_set_configuration(fpi_dev_get_usb_dev(FP_DEV(dev)), 1)) < 0 ) - // goto out; - - if ( (r = libusb_claim_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0)) < 0 ) { - fp_err("could not claim interface 0: %s", libusb_error_name(r)); - return r; - } - - //if ( (r = usb_set_altinterface(fpi_dev_get_usb_dev(FP_DEV(dev)), 1)) < 0 ) - // goto out; - - //if ( (r = usb_clear_halt(fpi_dev_get_usb_dev(FP_DEV(dev)), EP_CMD)) < 0 ) - // goto out; - - /* Make sure sensor mode is not capture_{ready|read} */ - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END))) { - fp_err("Command: CAPTURE_END"); - goto out; - } - - if ((r = bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), LED_OFF))) { - fp_err("Command: LED_OFF"); - goto out; - } - - return 0; - -out: - fp_err("could not init dev"); - return r; -} - -static -void dev_exit(struct fp_img_dev *dev) -{ - if (bulk_write_safe(fpi_dev_get_usb_dev(FP_DEV(dev)), CAPTURE_END)) - fp_err("Command: CAPTURE_END"); - - libusb_release_interface(fpi_dev_get_usb_dev(FP_DEV(dev)), 0); -} - -static const struct usb_id id_table[] = { - { .vendor = 0x1162, .product = 0x0300 }, - { 0, 0, 0, }, -}; - -struct fp_img_driver fdu2000_driver = { - .driver = { - .id = FDU2000_ID, - .name = FP_COMPONENT, - .full_name = "Secugen FDU 2000", - .id_table = id_table, - .scan_type = FP_SCAN_TYPE_PRESS, - }, - .img_height = RAW_IMAGE_HEIGTH, - .img_width = RAW_IMAGE_WIDTH, - .bz3_threshold = 23, - - .init = dev_init, - .exit = dev_exit, - .capture = capture, -}; diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 99c5ffae..69a79e69 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -136,7 +136,7 @@ static unsigned char upeksonly_get_pixel(struct fpi_line_asmbl_ctx *ctx, unsigned char *buf; unsigned offset; - /* The scans from this device are rolled right by two colums */ + /* The scans from this device are rolled right by two columns */ if (x < ctx->line_width - 2) offset = x + 2; else if ((x > ctx->line_width - 2) && (x < ctx->line_width)) @@ -296,12 +296,12 @@ static void row_complete(struct fp_img_dev *dev) sdev->num_blank = 0; } else { sdev->num_blank++; - /* Don't consider the scan complete unless theres at least + /* Don't consider the scan complete unless there's at least * MIN_ROWS recorded or very long blank read occurred. * * Typical problem spot: one brief touch before starting the * actual scan. Happens most commonly if scan is started - * from before the first joint resulting in a gap after the inital touch. + * from before the first joint resulting in a gap after the initial touch. */ if (sdev->num_blank > FINGER_REMOVED_THRESHOLD) { sdev->finger_state = FINGER_REMOVED; @@ -1268,7 +1268,7 @@ static void initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) fpi_ssm_start(sdev->loopsm, loopsm_complete); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct sonly_dev *sdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm = NULL; diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 0042833e..00d9c553 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -377,7 +377,7 @@ static void start_capture(struct fp_img_dev *dev) fpi_ssm_start(ssm, capture_sm_complete); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct upektc_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state, diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index d749ac51..988793dc 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -287,7 +287,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) fpi_ssm_mark_completed(ssm); break; default: - fp_err("Uknown response!\n"); + fp_err("Unknown response!\n"); fpi_ssm_mark_failed(ssm, -EIO); break; } @@ -567,7 +567,7 @@ static void activate_sm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_d start_capture(dev); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct upektc_img_dev *upekdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), activate_run_state, diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 7830c562..79c48c5b 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -668,7 +668,7 @@ static uint32_t do_decode(uint8_t *data, int num_bytes, uint32_t key) data[i] = data[i+1] ^ xorbyte; } - /* the final byte is implictly zero */ + /* the final byte is implicitly zero */ data[i] = 0; return update_key(key); } @@ -710,7 +710,7 @@ static void imaging_run_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data uint32_t key; uint8_t flags, num_lines; int i, r, to, dev2; - char buf[5]; + unsigned char buf[5]; switch (fpi_ssm_get_cur_state(ssm)) { case IMAGING_CAPTURE: @@ -1161,20 +1161,10 @@ static void activate_initsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *us int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); - if (r) { - fpi_imgdev_activate_complete(dev, r); - return; - } - - r = execute_state_change(dev); fpi_imgdev_activate_complete(dev, r); } -/* FIXME: having state parameter here is kinda useless, will we ever - * see a scenario where the parameter is useful so early on in the activation - * process? asynchronity means that it'll only be used in a later function - * call. */ -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct uru4k_dev *urudev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm; @@ -1185,7 +1175,6 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) return r; urudev->scanpwr_irq_timeouts = 0; - urudev->activate_state = state; ssm = fpi_ssm_new(FP_DEV(dev), init_run_state, INIT_NUM_STATES, dev); fpi_ssm_start(ssm, activate_initsm_complete); return 0; @@ -1340,6 +1329,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) goto out; } + /* Disable loading p11-kit's user configuration */ + g_setenv ("P11_KIT_NO_USER_CONFIG", "1", TRUE); + /* Initialise NSS early */ rv = NSS_NoDB_Init("."); if (rv != SECSuccess) { diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 4ed71f69..b0c6c452 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -302,7 +302,7 @@ static void loopsm_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) fpi_imgdev_deactivate_complete(dev); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct v5s_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm = fpi_ssm_new(FP_DEV(dev), loop_run_state, diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index a437df4f..b2f8395e 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -577,7 +577,7 @@ static void activate_ssm(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) vdev->need_report = 0; } - /* Asyncronously enquire an interrupt */ + /* Asynchronously enquire an interrupt */ vdev->transfer = fpi_usb_alloc(); vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, 0x83, @@ -684,7 +684,7 @@ static void dev_activate_callback(fpi_ssm *ssm, struct fp_dev *_dev, void *user_ } /* Activate device */ -static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *idev) { struct vfs_dev_t *vdev = FP_INSTANCE_DATA(FP_DEV(idev)); diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 8faaa230..60f0a819 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -47,7 +47,7 @@ /* Minimum image height */ #define VFS_IMG_MIN_HEIGHT 200 -/* Scan level thresold */ +/* Scan level threshold */ #define VFS_IMG_SLT_BEGIN 768 #define VFS_IMG_SLT_END 64 #define VFS_IMG_SLT_LINES 4 @@ -641,7 +641,7 @@ static int action_completed(struct fp_img_dev *dev) #define offset(x, y) ((x) + ((y) * VFS_FRAME_SIZE)) -/* Screen image to remove noise and find bottom line and height od image */ +/* Screen image to remove noise and find bottom line and height of image */ static void img_screen(struct vfs101_dev *vdev) { int y, x, count, top; @@ -654,7 +654,7 @@ static void img_screen(struct vfs101_dev *vdev) /* Image returned from sensor can contain many empty lines, * for remove these lines compare byte 282-283 (scan level information) - * with two differents threshold, one for the begin of finger image and + * with two different thresholds, one for the begin of finger image and * one for the end. To increase stability of the code use a counter * of lines that satisfy the threshold. */ @@ -700,7 +700,7 @@ static void img_screen(struct vfs101_dev *vdev) vdev->height = top - vdev->bottom + 1; - /* Checkk max height */ + /* Check max height */ if (vdev->height > VFS_IMG_MAX_HEIGHT) vdev->height = VFS_IMG_MAX_HEIGHT; @@ -1178,7 +1178,7 @@ static void m_init_state(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) switch (fpi_ssm_get_cur_state(ssm)) { case M_INIT_0_RECV_DIRTY: - /* Recv eventualy dirty data */ + /* Recv eventually dirty data */ vdev->ignore_error = TRUE; async_recv(ssm, dev); break; @@ -1424,7 +1424,7 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) } /* Activate device */ -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct vfs101_dev *vdev = FP_INSTANCE_DATA(FP_DEV(dev)); fpi_ssm *ssm; @@ -1463,7 +1463,7 @@ static void dev_deactivate(struct fp_img_dev *dev) /* Reset active state */ vdev->active = FALSE; - /* Handle eventualy existing events */ + /* Handle eventually existing events */ while (vdev->transfer) fp_handle_events(); diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 4116e71e..94837de0 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -191,7 +191,7 @@ static void m_init_complete(fpi_ssm *ssm, struct fp_dev *_dev, void *user_data) } /* Activate device */ -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { fpi_ssm *ssm; diff --git a/libfprint/drivers/vfs301_proto.h b/libfprint/drivers/vfs301_proto.h index daa629aa..2ae587a1 100644 --- a/libfprint/drivers/vfs301_proto.h +++ b/libfprint/drivers/vfs301_proto.h @@ -109,7 +109,7 @@ typedef struct { unsigned char scan[VFS301_FP_WIDTH]; - /* A offseted, stretched, inverted copy of scan... probably could + /* A offsetted, 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]; diff --git a/libfprint/drivers/vfs301_proto_fragments.h b/libfprint/drivers/vfs301_proto_fragments.h index c000441c..39441a13 100644 --- a/libfprint/drivers/vfs301_proto_fragments.h +++ b/libfprint/drivers/vfs301_proto_fragments.h @@ -1147,7 +1147,7 @@ static const unsigned char vfs301_24[] = { /* 119 B */ * * 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 + * to be used also here. Not necessarily 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? diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 2fcb822a..c7121f9d 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -371,7 +371,7 @@ static int process_chunk(struct vfs5011_data *data, int transferred) VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) { data->lastline = g_malloc(VFS5011_LINE_SIZE); data->rows = g_slist_prepend(data->rows, data->lastline); - g_memmove(data->lastline, linebuf, VFS5011_LINE_SIZE); + memmove(data->lastline, linebuf, VFS5011_LINE_SIZE); data->lines_recorded++; if (data->lines_recorded >= data->max_lines_recorded) { fp_dbg("process_chunk: recorded %d lines, finishing", @@ -405,7 +405,7 @@ submit_image(fpi_ssm *ssm, g_slist_free_full(data->rows, g_free); data->rows = NULL; - fp_dbg("Image captured, commiting"); + fp_dbg("Image captured, committing"); fpi_imgdev_image_captured(dev, img); } @@ -846,7 +846,7 @@ static void start_scan(struct fp_img_dev *dev) fp_dbg("ssm done, getting out"); } -static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *dev) { struct vfs5011_data *data; @@ -879,6 +879,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static const struct usb_id id_table[] = { { .vendor = 0x138a, .product = 0x0010 /* Validity device from some Toshiba laptops */ }, { .vendor = 0x138a, .product = 0x0011 /* vfs5011 */ }, + { .vendor = 0x138a, .product = 0x0015 /* Validity device from Lenovo Preferred Pro USB Fingerprint Keyboard KUF1256 */ }, { .vendor = 0x138a, .product = 0x0017 /* Validity device from Lenovo T440 laptops */ }, { .vendor = 0x138a, .product = 0x0018 /* one more Validity device */ }, { 0, 0, 0, }, diff --git a/libfprint/fpi-assembling.c b/libfprint/fpi-assembling.c index e33dafe5..65fad4d7 100644 --- a/libfprint/fpi-assembling.c +++ b/libfprint/fpi-assembling.c @@ -365,7 +365,7 @@ static void median_filter(int *data, int size, int filtersize) i1 = 0; if (i2 >= size) i2 = size-1; - g_memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int)); + memmove(sortbuf, data+i1, (i2-i1+1)*sizeof(int)); g_qsort_with_data(sortbuf, i2-i1+1, sizeof(int), cmpint, NULL); result[i] = sortbuf[(i2-i1+1)/2]; } @@ -480,7 +480,7 @@ out: img->height = line_ind; img->width = ctx->line_width; img->flags = FP_IMG_V_FLIPPED; - g_memmove(img->data, output, ctx->line_width * line_ind); + memmove(img->data, output, ctx->line_width * line_ind); g_free(offsets); g_free(output); return img; diff --git a/libfprint/fpi-async.c b/libfprint/fpi-async.c index ddf5230b..6339c9ca 100644 --- a/libfprint/fpi-async.c +++ b/libfprint/fpi-async.c @@ -387,9 +387,21 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, g_return_val_if_fail(dev != NULL, -ENODEV); + G_DEBUG_HERE(); + + if (dev->state == DEV_STATE_VERIFY_STOPPING) { + fp_dbg ("Already stopping verification, returning -EINPROGRESS"); + return -EINPROGRESS; + } + + if (dev->state == DEV_STATE_INITIALIZED) { + if (callback) + callback(dev, user_data); + return 0; + } + drv = dev->drv; - G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_ERROR && dev->state != DEV_STATE_VERIFYING && dev->state != DEV_STATE_VERIFY_DONE); @@ -511,9 +523,21 @@ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev, g_return_val_if_fail(dev != NULL, -ENODEV); + G_DEBUG_HERE(); + + if (dev->state == DEV_STATE_IDENTIFY_STOPPING) { + fp_dbg ("Already stopping identification, returning -EINPROGRESS"); + return -EINPROGRESS; + } + + if (dev->state == DEV_STATE_INITIALIZED) { + if (callback) + callback(dev, user_data); + return 0; + } + drv = dev->drv; - G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_IDENTIFYING && dev->state != DEV_STATE_IDENTIFY_DONE); diff --git a/libfprint/fpi-core.c b/libfprint/fpi-core.c index 2b5d3c6f..6009c82d 100644 --- a/libfprint/fpi-core.c +++ b/libfprint/fpi-core.c @@ -270,10 +270,12 @@ static struct fp_dscv_dev *discover_dev(libusb_device *udev) * fp_discover_devs: * * Scans the system and returns a list of discovered devices. This is your - * entry point into finding a fingerprint reader to operate. + * entry point into finding a fingerprint reader to operate. Note that %NULL + * is only returned on error. When there are no supported readers available, + * an empty list is returned instead. * - * Returns: a nul-terminated list of discovered devices. Must be freed with - * fp_dscv_devs_free() after use. + * Returns: a nul-terminated list of discovered devices or %NULL on error. + * Must be freed with fp_dscv_devs_free() after use. */ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) { @@ -344,6 +346,8 @@ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs) */ API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev) { + g_return_val_if_fail(dev, NULL); + return dev->drv; } @@ -358,6 +362,8 @@ API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev) */ API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev) { + g_return_val_if_fail(dev, 0); + return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)); } @@ -371,6 +377,8 @@ API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev) */ API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev) { + g_return_val_if_fail(dev, 0); + return dev->devtype; } @@ -400,6 +408,9 @@ enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv) API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, struct fp_print_data *print) { + g_return_val_if_fail(dev, 0); + g_return_val_if_fail(print, 0); + return fpi_print_data_compatible(dev->drv->id, dev->devtype, fpi_driver_get_data_type(dev->drv), print->driver_id, print->devtype, print->type); @@ -420,6 +431,9 @@ API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev, struct fp_dscv_print *print) { + g_return_val_if_fail(dev, 0); + g_return_val_if_fail(print, 0); + return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0, print->driver_id, print->devtype, 0); } @@ -443,6 +457,9 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev * struct fp_dscv_dev *ddev; int i; + g_return_val_if_fail(devs, NULL); + g_return_val_if_fail(print, NULL); + for (i = 0; (ddev = devs[i]); i++) if (fp_dscv_dev_supports_print_data(ddev, print)) return ddev; @@ -468,6 +485,9 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev * struct fp_dscv_dev *ddev; int i; + g_return_val_if_fail(devs, NULL); + g_return_val_if_fail(print, NULL); + for (i = 0; (ddev = devs[i]); i++) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -488,6 +508,8 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev * */ API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev) { + g_return_val_if_fail(dev, NULL); + return dev->drv; } @@ -502,6 +524,8 @@ API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev) */ API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev) { + g_return_val_if_fail(dev, 0); + return dev->nr_enroll_stages; } @@ -515,6 +539,8 @@ API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev) */ API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev) { + g_return_val_if_fail(dev, 0); + return dev->devtype; } @@ -530,6 +556,9 @@ API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev) API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev, struct fp_print_data *data) { + g_return_val_if_fail(dev, 0); + g_return_val_if_fail(data, 0); + return fpi_print_data_compatible(dev->drv->id, dev->devtype, fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype, data->type); @@ -550,6 +579,9 @@ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev, API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev, struct fp_dscv_print *print) { + g_return_val_if_fail(dev, 0); + g_return_val_if_fail(print, 0); + return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0, print->driver_id, print->devtype, 0); } @@ -564,6 +596,8 @@ API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev, */ API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv) { + g_return_val_if_fail(drv, NULL); + return drv->name; } @@ -577,6 +611,8 @@ API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv) */ API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv) { + g_return_val_if_fail(drv, NULL); + return drv->full_name; } @@ -590,6 +626,8 @@ API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv) */ API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv) { + g_return_val_if_fail(drv, 0); + return drv->id; } @@ -603,6 +641,8 @@ API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv) */ API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv) { + g_return_val_if_fail(drv, FP_SCAN_TYPE_PRESS); + return drv->scan_type; } @@ -621,6 +661,8 @@ API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv) */ API_EXPORTED int fp_driver_supports_imaging(struct fp_driver *drv) { + g_return_val_if_fail(drv, 0); + return drv->capture_start != NULL; } @@ -639,6 +681,8 @@ API_EXPORTED int fp_driver_supports_imaging(struct fp_driver *drv) */ API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev) { + g_return_val_if_fail(dev, 0); + return dev->drv->capture_start != NULL; } @@ -654,6 +698,8 @@ API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev) */ API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev) { + g_return_val_if_fail(dev, 0); + return dev->drv->identify_start != NULL; } @@ -671,6 +717,8 @@ API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev) */ API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev) { + g_return_val_if_fail(dev, -1); + if (!dev->img_dev) { fp_dbg("get image width for non-imaging device"); return -1; @@ -693,6 +741,8 @@ API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev) */ API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev) { + g_return_val_if_fail(dev, -1); + if (!dev->img_dev) { fp_dbg("get image height for non-imaging device"); return -1; diff --git a/libfprint/fpi-core.h b/libfprint/fpi-core.h index a5a0a44d..d183f885 100644 --- a/libfprint/fpi-core.h +++ b/libfprint/fpi-core.h @@ -110,7 +110,7 @@ struct fp_img_driver { /* Device operations */ int (*open)(struct fp_img_dev *dev, unsigned long driver_data); void (*close)(struct fp_img_dev *dev); - int (*activate)(struct fp_img_dev *dev, enum fp_imgdev_state state); + int (*activate)(struct fp_img_dev *dev); int (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state); void (*deactivate)(struct fp_img_dev *dev); }; diff --git a/libfprint/fpi-data.c b/libfprint/fpi-data.c index 0ac0f987..c19142ac 100644 --- a/libfprint/fpi-data.c +++ b/libfprint/fpi-data.c @@ -56,12 +56,15 @@ struct fpi_print_data_item_fp2 { * * This page documents the various operations you can do with a stored print. * Note that by default, "stored prints" are not actually stored anywhere - * except in RAM. For the simple scenarios, libfprint provides a simple API - * for you to save and load the stored prints referring to a single user in - * their home directory. For more advanced users, libfprint provides APIs for - * you to convert print data to a byte string, and to reconstruct stored prints + * except in RAM. Storage needs to be handled by the API user by using the + * fp_print_data_get_data() and fp_print_data_from_data(). This API allows + * to convert print data into byte strings, and to reconstruct stored prints * from such data at a later point. You are welcome to store these byte strings * in any fashion that suits you. + * + * The provided API to store data on disk is deprecated and should not be + * used anymore. This API stored the prints in the current user's home + * directory. */ /* @@ -211,7 +214,7 @@ API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data, item = list_item->data; out_item = (struct fpi_print_data_item_fp2 *)buf; out_item->length = GUINT32_TO_LE(item->length); - /* FIXME: fp_print_data_item->data content is not endianess agnostic */ + /* FIXME: fp_print_data_item->data content is not endianness agnostic */ memcpy(out_item->data, item->data, item->length); buf += sizeof(*out_item); buf += item->length; @@ -233,7 +236,7 @@ static struct fp_print_data *fpi_print_data_from_fp1_data(unsigned char *buf, data = print_data_new(GUINT16_FROM_LE(raw->driver_id), GUINT32_FROM_LE(raw->devtype), raw->data_type); item = fpi_print_data_item_new(print_data_len); - /* FIXME: fp_print_data->data content is not endianess agnostic */ + /* FIXME: fp_print_data->data content is not endianness agnostic */ memcpy(item->data, raw->data, print_data_len); data->prints = g_slist_prepend(data->prints, item); @@ -269,7 +272,7 @@ static struct fp_print_data *fpi_print_data_from_fp2_data(unsigned char *buf, total_data_len -= item_len; item = fpi_print_data_item_new(item_len); - /* FIXME: fp_print_data->data content is not endianess agnostic */ + /* FIXME: fp_print_data->data content is not endianness agnostic */ memcpy(item->data, raw_item->data, item_len); data->prints = g_slist_prepend(data->prints, item); @@ -366,6 +369,10 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger) * directory beneath the current user's home directory. * * Returns: 0 on success, non-zero on error. + * + * Deprecated: Data storage should be handled outside of libfprint. + * See stored prints description + * for more information. */ API_EXPORTED int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger) @@ -478,6 +485,10 @@ static int load_from_file(char *path, struct fp_print_data **data) * obscure error conditions (e.g. corruption). * * Returns: 0 on success, non-zero on error + * + * Deprecated: Data storage should be handled outside of libfprint. + * See stored prints description + * for more information. */ API_EXPORTED int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data) @@ -513,6 +524,10 @@ API_EXPORTED int fp_print_data_load(struct fp_dev *dev, * Removes a stored print from disk previously saved with fp_print_data_save(). * * Returns: 0 on success, negative on error + * + * Deprecated: Data storage should be handled outside of libfprint. + * See stored prints description + * for more information. */ API_EXPORTED int fp_print_data_delete(struct fp_dev *dev, enum fp_finger finger) diff --git a/libfprint/fpi-dev-img.c b/libfprint/fpi-dev-img.c index 93f1f47e..b9d27831 100644 --- a/libfprint/fpi-dev-img.c +++ b/libfprint/fpi-dev-img.c @@ -485,9 +485,15 @@ void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status) */ void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev) { + enum fp_imgdev_action action; + G_DEBUG_HERE(); - switch (imgdev->action) { + action = imgdev->action; + imgdev->action = IMG_ACTION_NONE; + imgdev->action_state = 0; + + switch (action) { case IMG_ACTION_ENROLL: fpi_drvcb_enroll_stopped(FP_DEV(imgdev)); break; @@ -504,9 +510,6 @@ void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev) fp_err("unhandled action %d", imgdev->action); break; } - - imgdev->action = IMG_ACTION_NONE; - imgdev->action_state = 0; } int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev) @@ -533,14 +536,14 @@ int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev) return height; } -static int dev_activate(struct fp_img_dev *imgdev, enum fp_imgdev_state state) +static int dev_activate(struct fp_img_dev *imgdev) { struct fp_driver *drv = FP_DEV(imgdev)->drv; struct fp_img_driver *imgdrv = fpi_driver_to_img_driver(drv); if (!imgdrv->activate) return 0; - return imgdrv->activate(imgdev, state); + return imgdrv->activate(imgdev); } static void dev_deactivate(struct fp_img_dev *imgdev) @@ -562,7 +565,7 @@ static int generic_acquire_start(struct fp_dev *dev, int action) imgdev->action_state = IMG_ACQUIRE_STATE_ACTIVATING; imgdev->enroll_stage = 0; - r = dev_activate(imgdev, IMGDEV_STATE_AWAIT_FINGER_ON); + r = dev_activate(imgdev); if (r < 0) fp_err("activation failed with error %d", r); diff --git a/libfprint/fpi-img.c b/libfprint/fpi-img.c index f5ebea7f..c7f44c24 100644 --- a/libfprint/fpi-img.c +++ b/libfprint/fpi-img.c @@ -405,7 +405,7 @@ int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, } } - /* FIXME: space is wasted if we dont hit the max minutiae count. would + /* FIXME: space is wasted if we don't hit the max minutiae count. would * be good to make this dynamic. */ print = fpi_print_data_new(FP_DEV(imgdev)); item = fpi_print_data_item_new(sizeof(struct xyt_struct)); diff --git a/libfprint/fpi-poll.c b/libfprint/fpi-poll.c index af0c4bee..3f2c898f 100644 --- a/libfprint/fpi-poll.c +++ b/libfprint/fpi-poll.c @@ -91,8 +91,6 @@ struct fpi_timeout { char *name; }; -static gboolean fpi_poll_is_setup(void); - static int timeout_sort_fn(gconstpointer _a, gconstpointer _b) { fpi_timeout *a = (fpi_timeout *) _a; @@ -167,7 +165,6 @@ fpi_timeout *fpi_timeout_add(unsigned int msec, int r; g_return_val_if_fail (dev != NULL, NULL); - g_return_val_if_fail (fpi_poll_is_setup(), NULL); fp_dbg("in %dms", msec); @@ -210,26 +207,6 @@ void fpi_timeout_cancel(fpi_timeout *timeout) fpi_timeout_free(timeout); } -void -fpi_timeout_cancel_for_dev(struct fp_dev *dev) -{ - GSList *l; - - g_return_if_fail (dev != NULL); - - l = active_timers; - while (l) { - struct fpi_timeout *timeout = l->data; - GSList *current = l; - - l = l->next; - if (timeout->dev == dev) { - fpi_timeout_free (timeout); - active_timers = g_slist_delete_link (active_timers, current); - } - } -} - /* get the expiry time and optionally the timeout structure for the next * timeout. returns 0 if there are no expired timers, or 1 if the * timeval/timeout output parameters were populated. if the returned timeval @@ -487,12 +464,6 @@ void fpi_poll_exit(void) libusb_set_pollfd_notifiers(fpi_usb_ctx, NULL, NULL, NULL); } -static gboolean -fpi_poll_is_setup(void) -{ - return (fd_added_cb != NULL && fd_removed_cb != NULL); -} - void fpi_timeout_cancel_all_for_dev(struct fp_dev *dev) { diff --git a/libfprint/fpi-sync.c b/libfprint/fpi-sync.c index e5a64f81..c2dd7927 100644 --- a/libfprint/fpi-sync.c +++ b/libfprint/fpi-sync.c @@ -149,7 +149,7 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data) * or I/O problems. * * The RETRY codes from #fp_enroll_result may be returned from any enroll - * stage. These codes indicate that the scan was not succesful in that the + * stage. These codes indicate that the scan was not successful in that the * user did not position their finger correctly or similar. When a RETRY code * is returned, the enrollment stage is not advanced, so the next call * into this function will retry the current stage again. The current stage may diff --git a/libfprint/fprint.h b/libfprint/fprint.h index b9b09092..4b68e4aa 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -275,11 +275,13 @@ int fp_identify_finger(struct fp_dev *dev, /* Data handling */ int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, - struct fp_print_data **data); + struct fp_print_data **data) LIBFPRINT_DEPRECATED; int fp_print_data_from_dscv_print(struct fp_dscv_print *print, struct fp_print_data **data) LIBFPRINT_DEPRECATED; -int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger); -int fp_print_data_delete(struct fp_dev *dev, enum fp_finger finger); +int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger) + LIBFPRINT_DEPRECATED; +int fp_print_data_delete(struct fp_dev *dev, enum fp_finger finger) + LIBFPRINT_DEPRECATED; void fp_print_data_free(struct fp_print_data *data); size_t fp_print_data_get_data(struct fp_print_data *data, unsigned char **ret); struct fp_print_data *fp_print_data_from_data(unsigned char *buf, diff --git a/libfprint/meson.build b/libfprint/meson.build index abd00054..976c70c8 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -1,40 +1,18 @@ libfprint_sources = [ - 'fp_internal.h', - 'nbis-helpers.h', - 'drivers_api.h', 'fpi-async.c', - 'fpi-async.h', 'fpi-assembling.c', - 'fpi-assembling.h', 'fpi-core.c', - 'fpi-core.h', 'fpi-data.c', - 'fpi-data.h', 'fpi-dev.c', - 'fpi-dev.h', 'fpi-dev-img.c', - 'fpi-dev-img.h', 'fpi-img.c', - 'fpi-img.h', - 'fpi-log.h', 'fpi-ssm.c', - 'fpi-ssm.h', 'fpi-sync.c', - 'fpi-poll.h', 'fpi-poll.c', - 'fpi-usb.h', 'fpi-usb.c', - 'drivers/driver_ids.h', ] nbis_sources = [ - 'nbis/include/bozorth.h', - 'nbis/include/bz_array.h', - 'nbis/include/defs.h', - 'nbis/include/lfs.h', - 'nbis/include/log.h', - 'nbis/include/morph.h', - 'nbis/include/sunrast.h', 'nbis/bozorth3/bozorth3.c', 'nbis/bozorth3/bz_alloc.c', 'nbis/bozorth3/bz_drvrs.c', @@ -76,13 +54,13 @@ drivers_sources = [] drivers_cflags = [] foreach driver: drivers if driver == 'upekts' - drivers_sources += [ 'drivers/upekts.c' ] + drivers_sources += [ 'drivers/upekts.c', 'drivers/upek_proto.c' ] endif if driver == 'upektc' - drivers_sources += [ 'drivers/upektc.c', 'drivers/upektc.h', 'drivers/upek_proto.c', 'drivers/upek_proto.h' ] + drivers_sources += [ 'drivers/upektc.c' ] endif if driver == 'upeksonly' - drivers_sources += [ 'drivers/upeksonly.c', 'drivers/upeksonly.h' ] + drivers_sources += [ 'drivers/upeksonly.c' ] endif if driver == 'uru4000' drivers_sources += [ 'drivers/uru4000.c' ] @@ -92,20 +70,20 @@ foreach driver: drivers aeslib = true endif if driver == 'aes1660' - drivers_sources += [ 'drivers/aes1660.c', 'drivers/aes1660.h' ] + drivers_sources += [ 'drivers/aes1660.c' ] aeslib = true aesx660 = true endif if driver == 'aes2501' - drivers_sources += [ 'drivers/aes2501.c', 'drivers/aes2501.h' ] + drivers_sources += [ 'drivers/aes2501.c' ] aeslib = true endif if driver == 'aes2550' - drivers_sources += [ 'drivers/aes2550.c', 'drivers/aes2550.h' ] + drivers_sources += [ 'drivers/aes2550.c' ] aeslib = true endif if driver == 'aes2660' - drivers_sources += [ 'drivers/aes2660.c', 'drivers/aes2660.h' ] + drivers_sources += [ 'drivers/aes2660.c' ] aeslib = true aesx660 = true endif @@ -119,9 +97,6 @@ foreach driver: drivers aeslib = true aes3k = true endif - if driver == 'fdu2000' - drivers_sources += [ 'drivers/fdu2000.c' ] - endif if driver == 'vcom5s' drivers_sources += [ 'drivers/vcom5s.c' ] endif @@ -129,33 +104,33 @@ foreach driver: drivers drivers_sources += [ 'drivers/vfs101.c' ] endif if driver == 'vfs301' - drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c', 'drivers/vfs301_proto.h', 'drivers/vfs301_proto_fragments.h' ] + drivers_sources += [ 'drivers/vfs301.c', 'drivers/vfs301_proto.c' ] endif if driver == 'vfs5011' - drivers_sources += [ 'drivers/vfs5011.c', 'drivers/vfs5011_proto.h' ] + drivers_sources += [ 'drivers/vfs5011.c' ] endif if driver == 'upektc_img' - drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upektc_img.h', 'drivers/upek_proto.c', 'drivers/upek_proto.h' ] + drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upek_proto.c' ] endif if driver == 'etes603' drivers_sources += [ 'drivers/etes603.c' ] endif if driver == 'vfs0050' - drivers_sources += [ 'drivers/vfs0050.c', 'drivers/vfs0050.h' ] + drivers_sources += [ 'drivers/vfs0050.c' ] endif if driver == 'elan' - drivers_sources += [ 'drivers/elan.c', 'drivers/elan.h' ] + drivers_sources += [ 'drivers/elan.c' ] endif endforeach if aeslib - drivers_sources += [ 'drivers/aeslib.c', 'drivers/aeslib.h' ] + drivers_sources += [ 'drivers/aeslib.c' ] endif if aesx660 - drivers_sources += ['drivers/aesx660.c', 'drivers/aesx660.h' ] + drivers_sources += ['drivers/aesx660.c' ] endif if aes3k - drivers_sources += ['drivers/aes3k.c', 'drivers/aes3k.h' ] + drivers_sources += ['drivers/aes3k.c' ] endif other_sources = [] diff --git a/meson.build b/meson.build index db5008f1..b7f7f315 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('libfprint', [ 'c', 'cpp' ], - version: '0.99.0', + version: '1.0', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized', @@ -27,7 +27,9 @@ common_cflags = cc.get_supported_arguments([ '-Wstrict-prototypes', '-Werror-implicit-function-declaration', '-Wno-pointer-sign', - '-Wshadow' + '-Wshadow', + '-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_50', + '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_50', ]) # maintaining compatibility with the previous libtool versioning @@ -39,7 +41,7 @@ revision = 0 libversion = '@0@.@1@.@2@'.format(soversion, current, revision) # Dependencies -glib_dep = dependency('glib-2.0', version: '>= 2.28') +glib_dep = dependency('glib-2.0', version: '>= 2.50') libusb_dep = dependency('libusb-1.0', version: '>= 0.9.1') mathlib_dep = cc.find_library('m', required: false) diff --git a/meson_options.txt b/meson_options.txt index 3e63304b..f40ebc31 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -17,7 +17,7 @@ option('x11-examples', option('gtk-examples', description: 'Whether to build GTK+ example applications', type: 'boolean', - value: true) + value: false) option('doc', description: 'Whether to build the API documentation', type: 'boolean',