From 59fe0fb699beca75d087ca146cfd413a9bb3da8a Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 15 Mar 2015 16:13:32 +0300 Subject: [PATCH 001/141] nbis: add one more step of false minutia removal Remove minutiae that are located on scan perimeter --- libfprint/nbis/include/lfs.h | 5 + libfprint/nbis/mindtct/globals.c | 4 + libfprint/nbis/mindtct/remove.c | 158 +++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) diff --git a/libfprint/nbis/include/lfs.h b/libfprint/nbis/include/lfs.h index 49aad842..9ff01b22 100644 --- a/libfprint/nbis/include/lfs.h +++ b/libfprint/nbis/include/lfs.h @@ -236,6 +236,8 @@ typedef struct lfsparms{ int pores_steps_bwd; double pores_min_dist2; double pores_max_ratio; + int remove_perimeter_pts; + int min_pp_distance; /* Ridge Counting Controls */ int max_nbrs; @@ -585,6 +587,9 @@ typedef struct lfsparms{ /* contour points to be considered a pore. */ #define PORES_MAX_RATIO 2.25 +/* Points which are closer than this distance to scan perimeter will be removed */ +#define PERIMETER_PTS_DISTANCE 10 + /***** RIDGE COUNTING CONSTANTS *****/ diff --git a/libfprint/nbis/mindtct/globals.c b/libfprint/nbis/mindtct/globals.c index da85aab4..e17c7dc9 100644 --- a/libfprint/nbis/mindtct/globals.c +++ b/libfprint/nbis/mindtct/globals.c @@ -129,6 +129,8 @@ LFSPARMS g_lfsparms = { PORES_STEPS_BWD, PORES_MIN_DIST2, PORES_MAX_RATIO, + FALSE, /* not removing perimeter points by default */ + PERIMETER_PTS_DISTANCE, /* Ridge Counting Controls */ MAX_NBRS, @@ -213,6 +215,8 @@ LFSPARMS g_lfsparms_V2 = { PORES_STEPS_BWD, PORES_MIN_DIST2, PORES_MAX_RATIO, + FALSE, /* not removing perimeter points by default */ + PERIMETER_PTS_DISTANCE, /* Ridge Counting Controls */ MAX_NBRS, diff --git a/libfprint/nbis/mindtct/remove.c b/libfprint/nbis/mindtct/remove.c index 029a0bca..6863ecf3 100644 --- a/libfprint/nbis/mindtct/remove.c +++ b/libfprint/nbis/mindtct/remove.c @@ -1350,6 +1350,159 @@ static int remove_overlaps(MINUTIAE *minutiae, return(0); } +static void mark_minutiae_in_range(MINUTIAE *minutiae, int *to_remove, int x, int y, + const LFSPARMS *lfsparms) +{ + int i, dist; + for (i = 0; i < minutiae->num; i++) { + if (to_remove[i]) + continue; + dist = (int)sqrt((x - minutiae->list[i]->x) * (x - minutiae->list[i]->x) + + (y - minutiae->list[i]->y) * (y - minutiae->list[i]->y)); + if (dist < lfsparms->min_pp_distance) { + to_remove[i] = 1; + } + } +} + +/************************************************************************* +************************************************************************** +#cat: remove_perimeter_pts - Takes a list of true and false minutiae and +#cat: attempts to detect and remove those false minutiae that +#cat: belong to image edge + + Input: + minutiae - list of true and false minutiae + bdata - binary image data (0==while & 1==black) + iw - width (in pixels) of image + ih - height (in pixels) of image + lfsparms - parameters and thresholds for controlling LFS + Output: + minutiae - list of pruned minutiae + Return Code: + Zero - successful completion + Negative - system error +**************************************************************************/ +static int remove_perimeter_pts(MINUTIAE *minutiae, + unsigned char *bdata, const int iw, const int ih, + const LFSPARMS *lfsparms) +{ + int i, j, ret, *to_remove; + int *left, *left_up, *left_down; + int *right, *right_up, *right_down; + int removed = 0; + int left_min, right_max; + + if (!lfsparms->remove_perimeter_pts) + return(0); + + to_remove = calloc(minutiae->num, sizeof(int)); + left = calloc(ih, sizeof(int)); + left_up = calloc(ih, sizeof(int)); + left_down = calloc(ih, sizeof(int)); + right = calloc(ih, sizeof(int)); + right_up = calloc(ih, sizeof(int)); + right_down = calloc(ih, sizeof(int)); + + /* Pass downwards */ + left_min = iw - 1; + right_max = 0; + for (i = 0; i < ih; i++) { + for (j = 0; j < left_min; j++) { + if ((bdata[i * iw + j] != 0)) { + left_min = j; + break; + } + } + if (left_min == (iw - 1)) + left_down[i] = -1; + else + left_down[i] = left_min; + for (j = iw - 1; j >= right_max; j--) { + if ((bdata[i * iw + j] != 0)) { + right_max = j; + break; + } + } + if (right_max == 0) + right_down[i] = -1; + else + right_down[i] = right_max; + } + + /* Pass upwards */ + left_min = iw - 1; + right_max = 0; + for (i = ih - 1; i >= 0; i--) { + for (j = 0; j < left_min; j++) { + if ((bdata[i * iw + j] != 0)) { + left_min = j; + break; + } + } + if (left_min == (iw - 1)) + left_up[i] = -1; + else + left_up[i] = left_min; + for (j = iw - 1; j >= right_max; j--) { + if ((bdata[i * iw + j] != 0)) { + right_max = j; + break; + } + } + if (right_max == 0) + right_up[i] = -1; + else + right_up[i] = right_max; + } + + /* Merge */ + left_min = left_down[ih - 1]; + right_max = right_down[ih - 1]; + for (i = 0; i < ih; i++) { + if (left_down[i] != left_min) + left[i] = left_down[i]; + else + left[i] = left_up[i]; + + if (right_down[i] != right_max) + right[i] = right_down[i]; + else + right[i] = right_up[i]; + } + free(left_up); + free(left_down); + free(right_up); + free(right_down); + + /* Mark minitiae close to the edge */ + for (i = 0; i < ih; i++) { + if (left[i] != -1) + mark_minutiae_in_range(minutiae, to_remove, left[i], i, lfsparms); + if (right[i] != -1) + mark_minutiae_in_range(minutiae, to_remove, right[i], i, lfsparms); + } + + free(left); + free(right); + + for (i = minutiae->num - 1; i >= 0; i--) { + /* If the current minutia index is flagged for removal ... */ + if (to_remove[i]){ + removed ++; + /* Remove the minutia from the minutiae list. */ + if((ret = remove_minutia(i, minutiae))){ + free(to_remove); + return(ret); + } + } + } + + free(to_remove); + + return (0); +} + /************************************************************************* ************************************************************************** #cat: remove_pores_V2 - Attempts to detect and remove minutia points located on @@ -2104,6 +2257,11 @@ int remove_false_minutia_V2(MINUTIAE *minutiae, return(ret); } + /* 11. Remove minutiae on image edge */ + if((ret = remove_perimeter_pts(minutiae, bdata, iw, ih, lfsparms))) { + return (ret); + } + return(0); } From 9bbd9b208a69282a7ede960711839b03b6ea4c8c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 15 Mar 2015 16:17:08 +0300 Subject: [PATCH 002/141] lib: add partial image flag And activate perimeter points removal if this flag is set. --- libfprint/fp_internal.h | 1 + libfprint/img.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index f640f58c..6b95a1a6 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -376,6 +376,7 @@ struct fp_minutiae { #define FP_IMG_H_FLIPPED (1<<1) #define FP_IMG_COLORS_INVERTED (1<<2) #define FP_IMG_BINARIZED_FORM (1<<3) +#define FP_IMG_PARTIAL (1<<4) #define FP_IMG_STANDARDIZATION_FLAGS (FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED \ | FP_IMG_COLORS_INVERTED) diff --git a/libfprint/img.c b/libfprint/img.c index 3c91d93f..f9545dbd 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -283,6 +283,9 @@ int fpi_img_detect_minutiae(struct fp_img *img) return -EINVAL; } + /* Remove perimeter points from partial image */ + g_lfsparms_V2.remove_perimeter_pts = img->flags & FP_IMG_PARTIAL ? TRUE : FALSE; + /* 25.4 mm per inch */ timer = g_timer_new(); r = get_minutiae(&minutiae, &quality_map, &direction_map, From bd0d4258e4b27579ecdfa5e91bd6f228d28796f3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 15 Mar 2015 16:18:50 +0300 Subject: [PATCH 003/141] upektc_img: set partial flag on an image Sensor width seems to be only 128 pixels and that's not enough for scanning whole finger surface. Lower bz3_threshold to 20, since for wrong fingerprint score never goes above 10, but sometimes for right finger score is below 40. --- libfprint/drivers/upektc_img.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 577d3ed0..79cc2d1e 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -302,6 +302,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) BUG_ON(upekdev->image_size != IMAGE_SIZE); fp_dbg("Image size is %d\n", upekdev->image_size); img = fpi_img_new(IMAGE_SIZE); + img->flags = FP_IMG_PARTIAL; memcpy(img->data, upekdev->image_bits, IMAGE_SIZE); fpi_imgdev_image_captured(dev, img); fpi_imgdev_report_finger_status(dev, FALSE); @@ -665,7 +666,7 @@ struct fp_img_driver upektc_img_driver = { .flags = 0, .img_height = IMAGE_HEIGHT, .img_width = IMAGE_WIDTH, - .bz3_threshold = 70, + .bz3_threshold = 20, .open = dev_init, .close = dev_deinit, From 985e8c4577cf6e79c6f99cf0c694f4e732daab27 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 15 Mar 2015 21:21:37 +0300 Subject: [PATCH 004/141] aes1660: set partial flag on an image Sensor width seems to be only 128 pixels and that's not enough for scanning whole finger surface. Lower bz3_threshold to 25, since for wrong finger score never goes above 10, but sometimes for right finger score is below 40. --- libfprint/drivers/aes1660.c | 3 ++- libfprint/drivers/aesx660.c | 1 + libfprint/drivers/aesx660.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index f931ba36..b221561f 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -56,6 +56,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) aesdev->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd; aesdev->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd); aesdev->frame_width = FRAME_WIDTH; + aesdev->extra_img_flags = FP_IMG_PARTIAL; fpi_imgdev_open_complete(dev, 0); return 0; @@ -102,7 +103,7 @@ struct fp_img_driver aes1660_driver = { .flags = 0, .img_height = -1, .img_width = FRAME_WIDTH + FRAME_WIDTH / 2, - .bz3_threshold = 70, + .bz3_threshold = 20, .open = dev_init, .close = dev_deinit, diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index ec28a5bd..433ba335 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -313,6 +313,7 @@ static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer) aesdev->strips = g_slist_reverse(aesdev->strips); img = aes_assemble(aesdev->strips, aesdev->strips_len, aesdev->frame_width, FRAME_HEIGHT, aesdev->frame_width + aesdev->frame_width / 2); + img->flags |= aesdev->extra_img_flags; g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); g_slist_free(aesdev->strips); aesdev->strips = NULL; diff --git a/libfprint/drivers/aesx660.h b/libfprint/drivers/aesx660.h index 0510a43a..044d8099 100644 --- a/libfprint/drivers/aesx660.h +++ b/libfprint/drivers/aesx660.h @@ -61,6 +61,7 @@ struct aesX660_dev { unsigned char *start_imaging_cmd; size_t start_imaging_cmd_len; unsigned int frame_width; + uint16_t extra_img_flags; }; struct aesX660_cmd { From 391373fb0c9e427ef93a71b056a999739297e428 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 19 Mar 2015 19:33:26 +0300 Subject: [PATCH 005/141] upektc_img: Fix copy/paste error Replace upekts_img with upektc_img --- libfprint/drivers/upektc_img.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 79cc2d1e..2fd2d9b2 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define FP_COMPONENT "upekts_img" +#define FP_COMPONENT "upektc_img" #include #include @@ -46,7 +46,7 @@ static void start_deactivation(struct fp_img_dev *dev); #define MAX_RESPONSE_SIZE 2052 #define SHORT_RESPONSE_SIZE 64 -struct upekts_img_dev { +struct upektc_img_dev { unsigned char cmd[MAX_CMD_SIZE]; unsigned char response[MAX_RESPONSE_SIZE]; unsigned char image_bits[IMAGE_SIZE * 2]; @@ -126,7 +126,7 @@ static void upektc_img_submit_req(struct fpi_ssm *ssm, libusb_transfer_cb_fn cb) { struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; struct libusb_transfer *transfer = libusb_alloc_transfer(0); int r; @@ -157,7 +157,7 @@ static void upektc_img_read_data(struct fpi_ssm *ssm, size_t buf_size, size_t bu { struct libusb_transfer *transfer = libusb_alloc_transfer(0); struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; int r; if (!transfer) { @@ -224,7 +224,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; unsigned char *data = upekdev->response; struct fp_img *img; size_t response_size; @@ -326,7 +326,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) static void capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; switch (ssm->cur_state) { case CAPTURE_INIT_CAPTURE: @@ -361,7 +361,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; int err = ssm->error; fp_dbg("Capture completed, %d", err); @@ -377,7 +377,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; struct fpi_ssm *ssm; upekdev->image_size = 0; @@ -422,7 +422,7 @@ static void deactivate_read_data_cb(struct libusb_transfer *transfer) static void deactivate_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; switch (ssm->cur_state) { case DEACTIVATE_DEINIT: @@ -439,7 +439,7 @@ static void deactivate_run_state(struct fpi_ssm *ssm) static void deactivate_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; int err = ssm->error; fp_dbg("Deactivate completed"); @@ -456,7 +456,7 @@ static void deactivate_sm_complete(struct fpi_ssm *ssm) static void start_deactivation(struct fp_img_dev *dev) { - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; struct fpi_ssm *ssm; upekdev->image_size = 0; @@ -521,7 +521,7 @@ static void activate_run_state(struct fpi_ssm *ssm) { struct libusb_transfer *transfer; struct fp_img_dev *dev = ssm->priv; - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; int r; switch (ssm->cur_state) { @@ -595,7 +595,7 @@ static void activate_sm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); ssm->priv = dev; @@ -606,7 +606,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct upekts_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = dev->priv; upekdev->deactivating = TRUE; } @@ -622,7 +622,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) return r; } - dev->priv = g_malloc0(sizeof(struct upekts_img_dev)); + dev->priv = g_malloc0(sizeof(struct upektc_img_dev)); fpi_imgdev_open_complete(dev, 0); return 0; } From 2944a35e74fdf1d91789b5715cce81974d6668a3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 19 Mar 2015 19:27:13 +0300 Subject: [PATCH 006/141] imgdev: Add fpi_imgdev_abort_scan() to abort scan gracefully from within the driver. Smart sensors like Upek TouchChip Coprocessor can provide scan status instead of image, as result we need to report such status as "short scan" or "finger not centered" from within the driver, since it's not a session error. --- libfprint/fp_internal.h | 1 + libfprint/imgdev.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 6b95a1a6..2324b273 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -483,6 +483,7 @@ void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev); void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, gboolean present); void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img); +void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result); void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error); #endif diff --git a/libfprint/imgdev.c b/libfprint/imgdev.c index 3b5d3f32..4d9000a5 100644 --- a/libfprint/imgdev.c +++ b/libfprint/imgdev.c @@ -217,6 +217,13 @@ static void identify_process_img(struct fp_img_dev *imgdev) imgdev->identify_match_offset = match_offset; } +void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result) +{ + imgdev->action_result = result; + imgdev->action_state = IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF; + dev_change_state(imgdev, IMGDEV_STATE_AWAIT_FINGER_OFF); +} + void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img) { struct fp_print_data *print; From a656a4a9f37dcf34cd1047647af7253fae89eb4c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 19 Mar 2015 19:34:08 +0300 Subject: [PATCH 007/141] upektc_img: Handle scan status reported by sensor properly Sensor can report "short scan" or "finger not centered" instead of image, so it's necessary to handle them gracefully. --- libfprint/drivers/upektc_img.c | 47 +++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 2fd2d9b2..31eddff0 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -184,9 +184,11 @@ static void upektc_img_read_data(struct fpi_ssm *ssm, size_t buf_size, size_t bu enum capture_states { CAPTURE_INIT_CAPTURE, CAPTURE_READ_DATA, + CAPTURE_READ_DATA_TERM, CAPTURE_ACK_00_28, CAPTURE_ACK_08, CAPTURE_ACK_FRAME, + CAPTURE_ACK_00_28_TERM, CAPTURE_NUM_STATES, }; @@ -194,11 +196,18 @@ static void capture_reqs_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && - (transfer->length == transfer->actual_length)) { - fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); - } else { + if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) || + (transfer->length != transfer->actual_length)) { fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + switch (ssm->cur_state) { + case CAPTURE_ACK_00_28_TERM: + fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA_TERM); + break; + default: + fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); + break; } } @@ -243,7 +252,13 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) fp_dbg("request completed, len: %.4x", transfer->actual_length); if (transfer->actual_length == 0) { - fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA); + fpi_ssm_jump_to_state(ssm, ssm->cur_state); + return; + } + + if (ssm->cur_state == CAPTURE_READ_DATA_TERM) { + fp_dbg("Terminating SSM\n"); + fpi_ssm_mark_completed(ssm); return; } @@ -277,10 +292,26 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) /* finger is present! */ fpi_ssm_jump_to_state(ssm, CAPTURE_ACK_00_28); break; + case 0x1e: + /* short scan */ + fp_err("short scan, aborting\n"); + fpi_imgdev_abort_scan(dev, FP_VERIFY_RETRY_TOO_SHORT); + fpi_imgdev_report_finger_status(dev, FALSE); + fpi_ssm_jump_to_state(ssm, CAPTURE_ACK_00_28_TERM); + break; + case 0x1d: + /* too much horisontal movement */ + fp_err("too much horisontal movement, aborting\n"); + fpi_imgdev_abort_scan(dev, FP_VERIFY_RETRY_CENTER_FINGER); + fpi_imgdev_report_finger_status(dev, FALSE); + fpi_ssm_jump_to_state(ssm, CAPTURE_ACK_00_28_TERM); + break; default: /* some error happened, cancel scan */ - fp_err("something bad happened, aborting scan :(\n"); - fpi_ssm_mark_aborted(ssm, FP_VERIFY_RETRY_REMOVE_FINGER); + fp_err("something bad happened, stop scan\n"); + fpi_imgdev_abort_scan(dev, FP_VERIFY_RETRY); + fpi_imgdev_report_finger_status(dev, FALSE); + fpi_ssm_jump_to_state(ssm, CAPTURE_ACK_00_28_TERM); break; } break; @@ -335,6 +366,7 @@ static void capture_run_state(struct fpi_ssm *ssm) upekdev->seq++; break; case CAPTURE_READ_DATA: + case CAPTURE_READ_DATA_TERM: if (!upekdev->response_rest) upektc_img_read_data(ssm, SHORT_RESPONSE_SIZE, 0, capture_read_data_cb); else @@ -342,6 +374,7 @@ static void capture_run_state(struct fpi_ssm *ssm) SHORT_RESPONSE_SIZE, capture_read_data_cb); break; case CAPTURE_ACK_00_28: + case CAPTURE_ACK_00_28_TERM: upektc_img_submit_req(ssm, upek2020_ack_00_28, sizeof(upek2020_ack_00_28), upekdev->seq, capture_reqs_cb); upekdev->seq++; From d9567002e458fca4f289d84bb3cb49d9d97585e7 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 1 Apr 2015 13:39:54 +0300 Subject: [PATCH 008/141] imgdev: reset action_result after reporting it Otherwise we end up in reporting the same result on next iteration. --- libfprint/imgdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfprint/imgdev.c b/libfprint/imgdev.c index 4d9000a5..4408c230 100644 --- a/libfprint/imgdev.c +++ b/libfprint/imgdev.c @@ -164,15 +164,18 @@ void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, break; case IMG_ACTION_VERIFY: fpi_drvcb_report_verify_result(imgdev->dev, r, img); + imgdev->action_result = 0; fp_print_data_free(data); break; case IMG_ACTION_IDENTIFY: fpi_drvcb_report_identify_result(imgdev->dev, r, imgdev->identify_match_offset, img); + imgdev->action_result = 0; fp_print_data_free(data); break; case IMG_ACTION_CAPTURE: fpi_drvcb_report_capture_result(imgdev->dev, r, img); + imgdev->action_result = 0; break; default: fp_err("unhandled action %d", imgdev->action); From 9f7e1ecf40ec86bae0088c847ee2453be8a27ad5 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 30 Aug 2015 16:36:58 -0700 Subject: [PATCH 009/141] vfs5011: make '5 scans per enroll' work with this driver Restart scan if core did not ask to terminate it explicitly. --- libfprint/drivers/vfs5011.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 38a9ef9d..67f024fe 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -77,6 +77,8 @@ struct usbexchange_data { int timeout; }; +static void start_scan(struct fp_img_dev *dev); + static void async_send_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; @@ -869,19 +871,22 @@ static void activate_loop_complete(struct fpi_ssm *ssm) if (data->init_sequence.receive_buf != NULL) g_free(data->init_sequence.receive_buf); data->init_sequence.receive_buf = NULL; - data->loop_running = FALSE; submit_image(ssm, data); fpi_imgdev_report_finger_status(dev, FALSE); - fpi_ssm_free(ssm); - if (r) - fpi_imgdev_session_error(dev, r); + data->loop_running = FALSE; - if (data->deactivating) + if (data->deactivating) { fpi_imgdev_deactivate_complete(dev); + } else if (r) { + fpi_imgdev_session_error(dev, r); + } else { + start_scan(dev); + } } + static void open_loop(struct fpi_ssm *ssm) { struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; @@ -928,8 +933,6 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) (unsigned char *)g_malloc0(MAXLINES * VFS5011_IMAGE_WIDTH); dev->priv = data; - dev->dev->nr_enroll_stages = 1; - r = libusb_reset_device(dev->udev); if (r != 0) { fp_err("Failed to reset the device"); @@ -963,21 +966,28 @@ static void dev_close(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 void start_scan(struct fp_img_dev *dev) { struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; struct fpi_ssm *ssm; - fp_dbg("device initialized"); - data->deactivating = FALSE; data->loop_running = TRUE; - fp_dbg("creating ssm"); ssm = fpi_ssm_new(dev->dev, activate_loop, DEV_ACTIVATE_NUM_STATES); ssm->priv = dev; fp_dbg("starting ssm"); fpi_ssm_start(ssm, activate_loop_complete); fp_dbg("ssm done, getting out"); +} + +static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +{ + struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + + fp_dbg("device initialized"); + data->deactivating = FALSE; + + start_scan(dev); return 0; } From 6e8d5cd6a199f83fb5f862a8421f8582608032f5 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 30 Aug 2015 16:38:44 -0700 Subject: [PATCH 010/141] vfs5011: do duplicate line search for 30 lines It seems that on faster devices, the driver can get more duplicate lines. Without this change scan looks too stretched. Suggested by: Thomas Rinsma --- libfprint/drivers/vfs5011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 67f024fe..c6d4586f 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -353,7 +353,7 @@ int vfs5011_rescale_image(unsigned char *image, int input_lines, enum { RESOLUTION = 10, MEDIAN_FILTER_SIZE = 13, - MAX_OFFSET = 10, + MAX_OFFSET = 30, GOOD_OFFSETS_CRITERION = 20, GOOD_OFFSETS_THRESHOLD = 3 }; From 6664f87d8f2650d7471a110b33839c878f97f8b4 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 10:28:49 -0700 Subject: [PATCH 011/141] aes1610: fix memory corruption introduced by a457658f1b --- libfprint/drivers/aes1610.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 957d0f4a..f87a63c2 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -579,11 +579,14 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) } if (sum > 0) { - /* FIXME: would preallocating strip buffers be a decent optimization? */ - stripdata = g_malloc(128 * 4); - memcpy(stripdata, data + 1, 128 * 4); - aesdev->strips = g_slist_prepend(aesdev->strips, stripdata); - aesdev->strips_len++; + /* FIXME: would preallocating strip buffers be a decent optimization? */ + struct aes_stripe *stripe = g_malloc(FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof(struct aes_stripe)); + stripe->delta_x = 0; + stripe->delta_y = 0; + stripdata = stripe->data; + memcpy(stripdata, data + 1, FRAME_WIDTH * (FRAME_HEIGHT / 2)); + aesdev->strips = g_slist_prepend(aesdev->strips, stripe); + aesdev->strips_len++; aesdev->blanks_count = 0; } From e40f7bd1f7aba96de11a5165a15b3b1783181ac3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 31 Aug 2015 21:25:20 -0700 Subject: [PATCH 012/141] lib: move frame assembling routines into a separate file and make them usable by non-aes drivers Frame assembling routines are not aes-specific, so move them into a separate file and add an accessor for peeking a pixel. --- libfprint/Makefile.am | 4 + libfprint/aeslib.c | 261 +-------------------------------- libfprint/aeslib.h | 17 +-- libfprint/assembling.c | 277 ++++++++++++++++++++++++++++++++++++ libfprint/assembling.h | 50 +++++++ libfprint/drivers/aes1610.c | 25 ++-- libfprint/drivers/aes1660.c | 14 +- libfprint/drivers/aes2501.c | 29 ++-- libfprint/drivers/aes2550.c | 17 ++- libfprint/drivers/aes2660.c | 13 +- libfprint/drivers/aesx660.c | 12 +- libfprint/drivers/aesx660.h | 5 +- 12 files changed, 422 insertions(+), 302 deletions(-) create mode 100644 libfprint/assembling.c create mode 100644 libfprint/assembling.h diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index b86d0f8e..66856659 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -48,6 +48,8 @@ EXTRA_DIST = \ drivers/aes3k.h \ drivers/driver_ids.h \ aeslib.c aeslib.h \ + assembling.c \ + assembling.h \ pixman.c \ 60-fprint-autosuspend.rules @@ -210,6 +212,8 @@ libfprint_la_SOURCES = \ imgdev.c \ poll.c \ sync.c \ + assembling.c \ + assembling.h \ $(DRIVER_SRC) \ $(OTHER_SRC) \ $(NBIS_SRC) diff --git a/libfprint/aeslib.c b/libfprint/aeslib.c index 8c0381a4..978454d8 100644 --- a/libfprint/aeslib.c +++ b/libfprint/aeslib.c @@ -26,6 +26,7 @@ #include #include "fp_internal.h" +#include "assembling.h" #include "aeslib.h" #define MAX_REGWRITES_PER_REQUEST 16 @@ -158,268 +159,16 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs, continue_write_regv(wdata); } -static inline unsigned char aes_get_pixel(struct aes_stripe *frame, +unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx, + struct fpi_frame *frame, unsigned int x, - unsigned int y, - unsigned int frame_width, - unsigned int frame_height) + unsigned int y) { unsigned char ret; - ret = frame->data[x * (frame_height >> 1) + (y >> 1)]; + ret = frame->data[x * (ctx->frame_height >> 1) + (y >> 1)]; ret = y % 2 ? ret >> 4 : ret & 0xf; ret *= 17; return ret; } - -static unsigned int calc_error(struct aes_stripe *first_frame, - struct aes_stripe *second_frame, - int dx, - int dy, - unsigned int frame_width, - unsigned int frame_height) -{ - unsigned int width, height; - unsigned int x1, y1, x2, y2, err, i, j; - - width = frame_width - (dx > 0 ? dx : -dx); - height = frame_height - dy; - - y1 = 0; - y2 = dy; - i = 0; - err = 0; - do { - x1 = dx < 0 ? 0 : dx; - x2 = dx < 0 ? -dx : 0; - j = 0; - - do { - unsigned char v1, v2; - - - v1 = aes_get_pixel(first_frame, x1, y1, frame_width, frame_height); - v2 = aes_get_pixel(second_frame, x2, y2, frame_width, frame_height); - err += v1 > v2 ? v1 - v2 : v2 - v1; - j++; - x1++; - x2++; - - } while (j < width); - i++; - y1++; - y2++; - } while (i < height); - - /* Normalize error */ - err *= (frame_height * frame_width); - err /= (height * width); - - if (err == 0) - return INT_MAX; - - return err; -} - -/* This function is rather CPU-intensive. It's better to use hardware - * to detect movement direction when possible. - */ -static void find_overlap(struct aes_stripe *first_frame, - struct aes_stripe *second_frame, - unsigned int *min_error, - unsigned int frame_width, - unsigned int frame_height) -{ - int dx, dy; - unsigned int err; - *min_error = INT_MAX; - - /* Seeking in horizontal and vertical dimensions, - * for horizontal dimension we'll check only 8 pixels - * in both directions. For vertical direction diff is - * rarely less than 2, so start with it. - */ - for (dy = 2; dy < frame_height; dy++) { - for (dx = -8; dx < 8; dx++) { - err = calc_error(first_frame, second_frame, - dx, dy, frame_width, frame_height); - if (err < *min_error) { - *min_error = err; - second_frame->delta_x = -dx; - second_frame->delta_y = dy; - } - } - } -} - -unsigned int aes_calc_delta(GSList *stripes, size_t num_stripes, - unsigned int frame_width, unsigned int frame_height, - gboolean reverse) -{ - GSList *list_entry = stripes; - GTimer *timer; - int frame = 1; - int height = 0; - struct aes_stripe *prev_stripe = list_entry->data; - unsigned int min_error; - - list_entry = g_slist_next(list_entry); - - timer = g_timer_new(); - do { - struct aes_stripe *cur_stripe = list_entry->data; - - if (reverse) { - find_overlap(prev_stripe, cur_stripe, &min_error, - frame_width, frame_height); - prev_stripe->delta_y = -prev_stripe->delta_y; - prev_stripe->delta_x = -prev_stripe->delta_x; - } - else - find_overlap(cur_stripe, prev_stripe, &min_error, - frame_width, frame_height); - - frame++; - height += prev_stripe->delta_y; - prev_stripe = cur_stripe; - list_entry = g_slist_next(list_entry); - - } while (frame < num_stripes); - - if (height < 0) - height = -height; - height += frame_height; - g_timer_stop(timer); - fp_dbg("calc delta completed in %f secs", g_timer_elapsed(timer, NULL)); - g_timer_destroy(timer); - - return height; -} - -static inline void aes_blit_stripe(struct fp_img *img, - struct aes_stripe *stripe, - int x, int y, unsigned int frame_width, - unsigned int frame_height) -{ - unsigned int ix, iy; - unsigned int fx, fy; - unsigned int width, height; - - /* Find intersection */ - if (x < 0) { - width = frame_width + x; - ix = 0; - fx = -x; - } else { - ix = x; - fx = 0; - width = frame_width; - } - if ((ix + width) > img->width) - width = img->width - ix; - - if (y < 0) { - iy = 0; - fy = -y; - height = frame_height + y; - } else { - iy = y; - fy = 0; - height = frame_height; - } - - if (fx > frame_width) - return; - - if (fy > frame_height) - return; - - if (ix > img->width) - return; - - if (iy > img->height) - return; - - if ((iy + height) > img->height) - height = img->height - iy; - - for (; fy < height; fy++, iy++) { - if (x < 0) { - ix = 0; - fx = -x; - } else { - ix = x; - fx = 0; - } - for (; fx < width; fx++, ix++) { - img->data[ix + (iy * img->width)] = aes_get_pixel(stripe, fx, fy, frame_width, frame_height); - } - } -} - -struct fp_img *aes_assemble(GSList *stripes, size_t stripes_len, - unsigned int frame_width, unsigned int frame_height, unsigned int img_width) -{ - GSList *stripe; - struct fp_img *img; - int height = 0; - int i, y, x; - gboolean reverse = FALSE; - struct aes_stripe *aes_stripe; - - BUG_ON(stripes_len == 0); - BUG_ON(img_width < frame_width); - - /* Calculate height */ - i = 0; - stripe = stripes; - - /* No offset for 1st image */ - aes_stripe = stripe->data; - aes_stripe->delta_x = 0; - aes_stripe->delta_y = 0; - do { - aes_stripe = stripe->data; - - height += aes_stripe->delta_y; - i++; - stripe = g_slist_next(stripe); - } while (i < stripes_len); - - fp_dbg("height is %d", height); - - if (height < 0) { - reverse = TRUE; - height = -height; - } - - /* For last frame */ - height += frame_height; - - /* Create buffer big enough for max image */ - img = fpi_img_new(img_width * height); - img->flags = FP_IMG_COLORS_INVERTED; - img->width = img_width; - img->height = height; - - /* Assemble stripes */ - i = 0; - stripe = stripes; - y = reverse ? (height - frame_height) : 0; - x = (img_width - frame_width) / 2; - - do { - aes_stripe = stripe->data; - - y += aes_stripe->delta_y; - x += aes_stripe->delta_x; - - aes_blit_stripe(img, aes_stripe, x, y, frame_width, frame_height); - - stripe = g_slist_next(stripe); - i++; - } while (i < stripes_len); - - return img; -} diff --git a/libfprint/aeslib.h b/libfprint/aeslib.h index 7721d111..2dd6cea0 100644 --- a/libfprint/aeslib.h +++ b/libfprint/aeslib.h @@ -27,11 +27,8 @@ struct aes_regwrite { unsigned char value; }; -struct aes_stripe { - int delta_x; - int delta_y; - unsigned char data[0]; -}; +struct fpi_frame; +struct fpi_frame_asmbl_ctx; typedef void (*aes_write_regv_cb)(struct fp_img_dev *dev, int result, void *user_data); @@ -39,12 +36,10 @@ typedef void (*aes_write_regv_cb)(struct fp_img_dev *dev, int result, void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs, unsigned int num_regs, aes_write_regv_cb callback, void *user_data); -unsigned int aes_calc_delta(GSList *stripes, size_t stripes_len, - unsigned int frame_width, unsigned int frame_height, - gboolean reverse); - -struct fp_img *aes_assemble(GSList *stripes, size_t stripes_len, - unsigned int frame_width, unsigned int frame_height, unsigned int img_width); +unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx, + struct fpi_frame *frame, + unsigned int x, + unsigned int y); #endif diff --git a/libfprint/assembling.c b/libfprint/assembling.c new file mode 100644 index 00000000..dd8d2127 --- /dev/null +++ b/libfprint/assembling.c @@ -0,0 +1,277 @@ +/* + * Image assembling routines + * Copyright (C) 2007-2008 Daniel Drake + * Copyright (C) 2015 Vasily Khoruzhick + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define FP_COMPONENT "assembling" + +#include +#include + +#include +#include + +#include "fp_internal.h" +#include "assembling.h" + +static unsigned int calc_error(struct fpi_frame_asmbl_ctx *ctx, + struct fpi_frame *first_frame, + struct fpi_frame *second_frame, + int dx, + int dy) +{ + unsigned int width, height; + unsigned int x1, y1, x2, y2, err, i, j; + + width = ctx->frame_width - (dx > 0 ? dx : -dx); + height = ctx->frame_height - dy; + + y1 = 0; + y2 = dy; + i = 0; + err = 0; + do { + x1 = dx < 0 ? 0 : dx; + x2 = dx < 0 ? -dx : 0; + j = 0; + + do { + unsigned char v1, v2; + + + v1 = ctx->get_pixel(ctx, first_frame, x1, y1); + v2 = ctx->get_pixel(ctx, second_frame, x2, y2); + err += v1 > v2 ? v1 - v2 : v2 - v1; + j++; + x1++; + x2++; + + } while (j < width); + i++; + y1++; + y2++; + } while (i < height); + + /* Normalize error */ + err *= (ctx->frame_height * ctx->frame_width); + err /= (height * width); + + if (err == 0) + return INT_MAX; + + return err; +} + +/* This function is rather CPU-intensive. It's better to use hardware + * to detect movement direction when possible. + */ +static void find_overlap(struct fpi_frame_asmbl_ctx *ctx, + struct fpi_frame *first_frame, + struct fpi_frame *second_frame, + unsigned int *min_error) +{ + int dx, dy; + unsigned int err; + *min_error = INT_MAX; + + /* Seeking in horizontal and vertical dimensions, + * for horizontal dimension we'll check only 8 pixels + * in both directions. For vertical direction diff is + * rarely less than 2, so start with it. + */ + for (dy = 2; dy < ctx->frame_height; dy++) { + for (dx = -8; dx < 8; dx++) { + err = calc_error(ctx, first_frame, second_frame, + dx, dy); + if (err < *min_error) { + *min_error = err; + second_frame->delta_x = -dx; + second_frame->delta_y = dy; + } + } + } +} + +unsigned int fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, + GSList *stripes, size_t num_stripes, + gboolean reverse) +{ + GSList *list_entry = stripes; + GTimer *timer; + int frame = 1; + int height = 0; + struct fpi_frame *prev_stripe = list_entry->data; + unsigned int min_error; + + list_entry = g_slist_next(list_entry); + + timer = g_timer_new(); + do { + struct fpi_frame *cur_stripe = list_entry->data; + + if (reverse) { + find_overlap(ctx, prev_stripe, cur_stripe, &min_error); + prev_stripe->delta_y = -prev_stripe->delta_y; + prev_stripe->delta_x = -prev_stripe->delta_x; + } + else + find_overlap(ctx, cur_stripe, prev_stripe, &min_error); + + frame++; + height += prev_stripe->delta_y; + prev_stripe = cur_stripe; + list_entry = g_slist_next(list_entry); + + } while (frame < num_stripes); + + if (height < 0) + height = -height; + height += ctx->frame_height; + g_timer_stop(timer); + fp_dbg("calc delta completed in %f secs", g_timer_elapsed(timer, NULL)); + g_timer_destroy(timer); + + return height; +} + +static inline void aes_blit_stripe(struct fpi_frame_asmbl_ctx *ctx, + struct fp_img *img, + struct fpi_frame *stripe, + int x, int y) +{ + unsigned int ix, iy; + unsigned int fx, fy; + unsigned int width, height; + + /* Find intersection */ + if (x < 0) { + width = ctx->frame_width + x; + ix = 0; + fx = -x; + } else { + ix = x; + fx = 0; + width = ctx->frame_width; + } + if ((ix + width) > img->width) + width = img->width - ix; + + if (y < 0) { + iy = 0; + fy = -y; + height = ctx->frame_height + y; + } else { + iy = y; + fy = 0; + height = ctx->frame_height; + } + + if (fx > ctx->frame_width) + return; + + if (fy > ctx->frame_height) + return; + + if (ix > img->width) + return; + + if (iy > img->height) + return; + + if ((iy + height) > img->height) + height = img->height - iy; + + for (; fy < height; fy++, iy++) { + if (x < 0) { + ix = 0; + fx = -x; + } else { + ix = x; + fx = 0; + } + for (; fx < width; fx++, ix++) { + img->data[ix + (iy * img->width)] = ctx->get_pixel(ctx, stripe, fx, fy); + } + } +} + +struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, + GSList *stripes, size_t stripes_len) +{ + GSList *stripe; + struct fp_img *img; + int height = 0; + int i, y, x; + gboolean reverse = FALSE; + struct fpi_frame *fpi_frame; + + BUG_ON(stripes_len == 0); + BUG_ON(ctx->image_width < ctx->frame_width); + + /* Calculate height */ + i = 0; + stripe = stripes; + + /* No offset for 1st image */ + fpi_frame = stripe->data; + fpi_frame->delta_x = 0; + fpi_frame->delta_y = 0; + do { + fpi_frame = stripe->data; + + height += fpi_frame->delta_y; + i++; + stripe = g_slist_next(stripe); + } while (i < stripes_len); + + fp_dbg("height is %d", height); + + if (height < 0) { + reverse = TRUE; + height = -height; + } + + /* For last frame */ + height += ctx->frame_height; + + /* Create buffer big enough for max image */ + img = fpi_img_new(ctx->image_width * height); + img->flags = FP_IMG_COLORS_INVERTED; + img->width = ctx->image_width; + img->height = height; + + /* Assemble stripes */ + i = 0; + stripe = stripes; + y = reverse ? (height - ctx->frame_height) : 0; + x = (ctx->image_width - ctx->frame_width) / 2; + + do { + fpi_frame = stripe->data; + + y += fpi_frame->delta_y; + x += fpi_frame->delta_x; + + aes_blit_stripe(ctx, img, fpi_frame, x, y); + + stripe = g_slist_next(stripe); + i++; + } while (i < stripes_len); + + return img; +} diff --git a/libfprint/assembling.h b/libfprint/assembling.h new file mode 100644 index 00000000..1d1905d3 --- /dev/null +++ b/libfprint/assembling.h @@ -0,0 +1,50 @@ +/* + * Image assembling routines + * Shared functions between libfprint Authentec drivers + * Copyright (C) 2007 Daniel Drake + * Copyright (C) 2015 Vasily Khoruzhick + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __ASSEMBLING_H__ +#define __ASSEMBLING_H__ + +#include + +struct fpi_frame { + int delta_x; + int delta_y; + unsigned char data[0]; +}; + +struct fpi_frame_asmbl_ctx { + unsigned frame_width; + unsigned frame_height; + unsigned image_width; + unsigned char (*get_pixel)(struct fpi_frame_asmbl_ctx *ctx, + struct fpi_frame *frame, + unsigned x, + unsigned y); +}; + +unsigned int fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, + GSList *stripes, size_t stripes_len, + gboolean reverse); + +struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, + GSList *stripes, size_t stripes_len); + +#endif diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index f87a63c2..d8aaeaa8 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -30,6 +30,7 @@ #include +#include #include #include @@ -66,6 +67,7 @@ static int adjust_gain(unsigned char *buffer, int status); #define FRAME_WIDTH 128 #define FRAME_HEIGHT 8 #define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) +#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) /* maximum number of frames to read during a scan */ /* FIXME reduce substantially */ #define MAX_FRAMES 350 @@ -80,6 +82,13 @@ struct aes1610_dev { uint8_t blanks_count; }; +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = FRAME_WIDTH, + .frame_height = FRAME_HEIGHT, + .image_width = IMAGE_WIDTH, + .get_pixel = aes_get_pixel, +}; + typedef void (*aes1610_read_regs_cb)(struct fp_img_dev *dev, int status, unsigned char *regs, void *user_data); @@ -580,7 +589,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) if (sum > 0) { /* FIXME: would preallocating strip buffers be a decent optimization? */ - struct aes_stripe *stripe = g_malloc(FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof(struct aes_stripe)); + struct fpi_frame *stripe = g_malloc(FRAME_WIDTH * (FRAME_HEIGHT / 2) + sizeof(struct fpi_frame)); stripe->delta_x = 0; stripe->delta_y = 0; stripdata = stripe->data; @@ -618,18 +627,14 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) /* send stop capture bits */ aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop), stub_capture_stop_cb, NULL); aesdev->strips = g_slist_reverse(aesdev->strips); - height = aes_calc_delta(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FALSE); - rev_height = aes_calc_delta(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, TRUE); + height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, FALSE); + rev_height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, TRUE); fp_dbg("heights: %d rev: %d", height, rev_height); if (rev_height < height) { fp_dbg("Reversed direction"); - height = aes_calc_delta(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FALSE); + height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, FALSE); } - img = aes_assemble(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH + FRAME_WIDTH / 2); + img = fpi_assemble_frames(&assembling_ctx, aesdev->strips, aesdev->strips_len); g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; @@ -843,7 +848,7 @@ struct fp_img_driver aes1610_driver = { }, .flags = 0, .img_height = -1, - .img_width = FRAME_WIDTH + FRAME_WIDTH / 2, + .img_width = IMAGE_WIDTH, .bz3_threshold = 50, diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index b221561f..8e63fe38 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -28,12 +28,22 @@ #include +#include +#include + #include "aesx660.h" #include "aes1660.h" #include "driver_ids.h" #define FRAME_WIDTH 128 -#define SCALE_FACTOR 2 +#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) + +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = FRAME_WIDTH, + .frame_height = AESX660_FRAME_HEIGHT, + .image_width = IMAGE_WIDTH, + .get_pixel = aes_get_pixel, +}; static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { @@ -55,7 +65,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) aesdev->init_seqs_len[1] = array_n_elements(aes1660_init_2); aesdev->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd; aesdev->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd); - aesdev->frame_width = FRAME_WIDTH; + aesdev->assembling_ctx = &assembling_ctx; aesdev->extra_img_flags = FP_IMG_PARTIAL; fpi_imgdev_open_complete(dev, 0); diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 264e2dcf..426bd9ed 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -28,6 +28,7 @@ #include +#include #include #include @@ -58,6 +59,7 @@ static void complete_deactivation(struct fp_img_dev *dev); #define FRAME_WIDTH 192 #define FRAME_HEIGHT 16 #define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) +#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) /* maximum number of frames to read during a scan */ /* FIXME reduce substantially */ #define MAX_FRAMES 150 @@ -72,6 +74,13 @@ struct aes2501_dev { int no_finger_cnt; }; +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = FRAME_WIDTH, + .frame_height = FRAME_HEIGHT, + .image_width = IMAGE_WIDTH, + .get_pixel = aes_get_pixel, +}; + typedef void (*aes2501_read_regs_cb)(struct fp_img_dev *dev, int status, unsigned char *regs, void *user_data); @@ -484,18 +493,18 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) unsigned int height, rev_height; aesdev->strips = g_slist_reverse(aesdev->strips); - height = aes_calc_delta(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FALSE); - rev_height = aes_calc_delta(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, TRUE); + height = fpi_do_movement_estimation(&assembling_ctx, + aesdev->strips, aesdev->strips_len, FALSE); + rev_height = fpi_do_movement_estimation(&assembling_ctx, + aesdev->strips, aesdev->strips_len, TRUE); fp_dbg("heights: %d rev: %d", height, rev_height); if (rev_height < height) { fp_dbg("Reversed direction"); - height = aes_calc_delta(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FALSE); + height = fpi_do_movement_estimation(&assembling_ctx, + aesdev->strips, aesdev->strips_len, FALSE); } - img = aes_assemble(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH + FRAME_WIDTH / 2); + img = fpi_assemble_frames(&assembling_ctx, + aesdev->strips, aesdev->strips_len); g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; @@ -509,7 +518,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) } else { /* obtain next strip */ /* FIXME: would preallocating strip buffers be a decent optimization? */ - struct aes_stripe *stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct aes_stripe)); + struct fpi_frame *stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); stripe->delta_x = 0; stripe->delta_y = 0; stripdata = stripe->data; @@ -881,7 +890,7 @@ struct fp_img_driver aes2501_driver = { }, .flags = 0, .img_height = -1, - .img_width = FRAME_WIDTH + FRAME_WIDTH / 2, + .img_width = IMAGE_WIDTH, .open = dev_init, .close = dev_deinit, diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 29e59d17..822dbcd8 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -28,6 +28,7 @@ #include +#include #include #include @@ -56,6 +57,7 @@ static void complete_deactivation(struct fp_img_dev *dev); #define FRAME_WIDTH 192 #define FRAME_HEIGHT 8 #define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT) +#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) struct aes2550_dev { GSList *strips; @@ -64,6 +66,13 @@ struct aes2550_dev { int heartbeat_cnt; }; +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = FRAME_WIDTH, + .frame_height = FRAME_HEIGHT, + .image_width = IMAGE_WIDTH, + .get_pixel = aes_get_pixel, +}; + /****** FINGER PRESENCE DETECTION ******/ static unsigned char finger_det_reqs[] = { @@ -204,7 +213,7 @@ static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data) unsigned char *stripdata; struct fp_img_dev *dev = ssm->priv; struct aes2550_dev *aesdev = dev->priv; - struct aes_stripe *stripe; + struct fpi_frame *stripe; int len; if (data[0] != AES2550_EDATA_MAGIC) { @@ -215,7 +224,7 @@ static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data) if (len != (AES2550_STRIP_SIZE - 3)) { fp_dbg("Bogus frame len: %.4x\n", len); } - stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct aes_stripe)); /* 4 bits per pixel */ + stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bits per pixel */ stripe->delta_x = (int8_t)data[6]; stripe->delta_y = -(int8_t)data[7]; stripdata = stripe->data; @@ -253,8 +262,8 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) struct fp_img *img; aesdev->strips = g_slist_reverse(aesdev->strips); - img = aes_assemble(aesdev->strips, aesdev->strips_len, - FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH + FRAME_WIDTH / 2); + img = fpi_assemble_frames(&assembling_ctx, + aesdev->strips, aesdev->strips_len); g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index d7b6cefc..2edb765b 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -28,11 +28,22 @@ #include +#include +#include + #include "aesx660.h" #include "aes2660.h" #include "driver_ids.h" #define FRAME_WIDTH 192 +#define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) + +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = FRAME_WIDTH, + .frame_height = AESX660_FRAME_HEIGHT, + .image_width = IMAGE_WIDTH, + .get_pixel = aes_get_pixel, +}; static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { @@ -55,7 +66,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) aesdev->init_seqs_len[1] = array_n_elements(aes2660_init_2); aesdev->start_imaging_cmd = (unsigned char *)aes2660_start_imaging_cmd; aesdev->start_imaging_cmd_len = sizeof(aes2660_start_imaging_cmd); - aesdev->frame_width = FRAME_WIDTH; + aesdev->assembling_ctx = &assembling_ctx; fpi_imgdev_open_complete(dev, 0); return 0; diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 433ba335..278fe810 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -30,6 +30,7 @@ #include +#include #include #include @@ -41,7 +42,7 @@ static void complete_deactivation(struct fp_img_dev *dev); #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) #define BULK_TIMEOUT 4000 -#define FRAME_HEIGHT 8 +#define FRAME_HEIGHT AESX660_FRAME_HEIGHT #define min(a, b) (((a) < (b)) ? (a) : (b)) @@ -273,12 +274,12 @@ enum capture_states { /* Returns number of processed bytes */ static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) { - struct aes_stripe *stripe; + struct fpi_frame *stripe; unsigned char *stripdata; struct fp_img_dev *dev = ssm->priv; struct aesX660_dev *aesdev = dev->priv; - stripe = g_malloc(aesdev->frame_width * FRAME_HEIGHT / 2 + sizeof(struct aes_stripe)); /* 4 bpp */ + stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */ stripdata = stripe->data; fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET], @@ -289,7 +290,7 @@ static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) fp_dbg("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y); if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) { - memcpy(stripdata, data + AESX660_IMAGE_OFFSET, aesdev->frame_width * FRAME_HEIGHT / 2); + memcpy(stripdata, data + AESX660_IMAGE_OFFSET, aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2); aesdev->strips = g_slist_prepend(aesdev->strips, stripe); aesdev->strips_len++; @@ -311,8 +312,7 @@ static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer) struct fp_img *img; aesdev->strips = g_slist_reverse(aesdev->strips); - img = aes_assemble(aesdev->strips, aesdev->strips_len, - aesdev->frame_width, FRAME_HEIGHT, aesdev->frame_width + aesdev->frame_width / 2); + img = fpi_assemble_frames(aesdev->assembling_ctx, aesdev->strips, aesdev->strips_len); img->flags |= aesdev->extra_img_flags; g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL); g_slist_free(aesdev->strips); diff --git a/libfprint/drivers/aesx660.h b/libfprint/drivers/aesx660.h index 044d8099..2106ca2d 100644 --- a/libfprint/drivers/aesx660.h +++ b/libfprint/drivers/aesx660.h @@ -41,6 +41,8 @@ #define AESX660_IMAGE_OFFSET 43 #define AESX660_BULK_TRANSFER_SIZE 4096 +#define AESX660_FRAME_HEIGHT 8 + struct aesX660_dev { GSList *strips; size_t strips_len; @@ -55,12 +57,11 @@ struct aesX660_dev { size_t buffer_max; /* Device-specific stuff */ - int h_scale_factor; struct aesX660_cmd *init_seqs[2]; size_t init_seqs_len[2]; unsigned char *start_imaging_cmd; size_t start_imaging_cmd_len; - unsigned int frame_width; + struct fpi_frame_asmbl_ctx *assembling_ctx; uint16_t extra_img_flags; }; From aab3daa28b4b45a94f7142eadfef76343c1b13d3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 10:15:35 -0700 Subject: [PATCH 013/141] upeksonly: move regwrite sequences into a header --- libfprint/Makefile.am | 2 +- libfprint/drivers/upeksonly.c | 99 +------------------------- libfprint/drivers/upeksonly.h | 126 ++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 99 deletions(-) create mode 100644 libfprint/drivers/upeksonly.h diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 66856659..ea6e6784 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -5,7 +5,7 @@ MOSTLYCLEANFILES = $(udev_rules_DATA) UPEKE2_SRC = drivers/upeke2.c UPEKTS_SRC = drivers/upekts.c UPEKTC_SRC = drivers/upektc.c drivers/upektc.h -UPEKSONLY_SRC = drivers/upeksonly.c +UPEKSONLY_SRC = drivers/upeksonly.c drivers/upeksonly.h URU4000_SRC = drivers/uru4000.c AES1610_SRC = drivers/aes1610.c AES1660_SRC = drivers/aes1660.c drivers/aes1660.h diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 84f864b4..8f0c0c26 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -30,6 +30,7 @@ #include +#include "upeksonly.h" #include "driver_ids.h" #define CTRL_TIMEOUT 1000 @@ -96,11 +97,6 @@ struct sonly_dev { }; }; -struct sonly_regwrite { - uint8_t reg; - uint8_t value; -}; - /***** IMAGE PROCESSING *****/ static void free_img_transfers(struct sonly_dev *sdev) @@ -663,51 +659,6 @@ static void sm_await_intr(struct fpi_ssm *ssm) /***** AWAIT FINGER *****/ -static const struct sonly_regwrite awfsm_2016_writev_1[] = { - { 0x0a, 0x00 }, { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x3b }, - { 0x00, 0x67 }, { 0x00, 0x67 }, -}; - -static const struct sonly_regwrite awfsm_1000_writev_1[] = { - /* Initialize sensor settings */ - { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x37 }, { 0x00, 0x5f }, - { 0x01, 0x6e }, { 0x01, 0xee }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, - { 0x0e, 0x0e }, { 0x0f, 0x0d }, - - { 0x13, 0x05 }, { 0x13, 0x45 }, - - /* Initialize finger detection registers (not enabling yet) */ - { 0x30, 0xe0 }, { 0x15, 0x26 }, - - { 0x12, 0x01 }, { 0x20, 0x01 }, { 0x07, 0x10 }, - { 0x10, 0x00 }, { 0x11, 0xbf }, -}; - -static const struct sonly_regwrite awfsm_2016_writev_2[] = { - { 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e }, - { 0x0f, 0x0d }, { 0x0b, 0x00 }, -}; - -static const struct sonly_regwrite awfsm_1000_writev_2[] = { - /* Enable finger detection */ - { 0x30, 0xe1 }, { 0x15, 0x06 }, { 0x15, 0x86 }, -}; - -static const struct sonly_regwrite awfsm_2016_writev_3[] = { - { 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 }, - { 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 }, -}; - -static const struct sonly_regwrite awfsm_2016_writev_4[] = { - { 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf }, - { 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 },\ - { 0x05, 0x00 }, { 0x0b, 0x00 }, - - /* enter finger detection mode */ - { 0x15, 0x20 }, { 0x30, 0xe1 }, { 0x15, 0x24 }, { 0x15, 0x04 }, - { 0x15, 0x84 }, -}; - enum awfsm_2016_states { AWFSM_2016_WRITEV_1, AWFSM_2016_READ_01, @@ -789,16 +740,6 @@ static void awfsm_1000_run_state(struct fpi_ssm *ssm) /***** CAPTURE MODE *****/ -static const struct sonly_regwrite capsm_2016_writev[] = { - /* enter capture mode */ - { 0x09, 0x28 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, { 0x04, 0x00 }, - { 0x05, 0x00 }, -}; - -static const struct sonly_regwrite capsm_1000_writev[] = { - { 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */ -}; - enum capsm_2016_states { CAPSM_2016_INIT, CAPSM_2016_WRITE_15, @@ -903,18 +844,6 @@ static void capsm_1000_run_state(struct fpi_ssm *ssm) /***** DEINITIALIZATION *****/ -static const struct sonly_regwrite deinitsm_2016_writev[] = { - /* reset + enter low power mode */ - { 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 }, -}; - -static const struct sonly_regwrite deinitsm_1000_writev[] = { - { 0x15, 0x26 }, { 0x30, 0xe0 }, /* Disable finger detection */ - - { 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */ -}; - - enum deinitsm_2016_states { DEINITSM_2016_WRITEV, DEINITSM_2016_NUM_STATES, @@ -945,32 +874,6 @@ static void deinitsm_1000_run_state(struct fpi_ssm *ssm) /***** INITIALIZATION *****/ -static const struct sonly_regwrite initsm_2016_writev_1[] = { - { 0x49, 0x00 }, - - /* BSAPI writes different values to register 0x3e each time. I initially - * thought this was some kind of clever authentication, but just blasting - * these sniffed values each time seems to work. */ - { 0x3e, 0x83 }, { 0x3e, 0x4f }, { 0x3e, 0x0f }, { 0x3e, 0xbf }, - { 0x3e, 0x45 }, { 0x3e, 0x35 }, { 0x3e, 0x1c }, { 0x3e, 0xae }, - - { 0x44, 0x01 }, { 0x43, 0x06 }, { 0x43, 0x05 }, { 0x43, 0x04 }, - { 0x44, 0x00 }, { 0x0b, 0x00 }, -}; - -static const struct sonly_regwrite initsm_1000_writev_1[] = { - { 0x49, 0x00 }, /* Encryption disabled */ - - /* Setting encryption key. Doesn't need to be random since we don't use any - * encryption. */ - { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, - { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, - - { 0x04, 0x00 }, { 0x05, 0x00 }, - - { 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */ -}; - enum initsm_2016_states { INITSM_2016_WRITEV_1, INITSM_2016_READ_09, diff --git a/libfprint/drivers/upeksonly.h b/libfprint/drivers/upeksonly.h new file mode 100644 index 00000000..ac00da2d --- /dev/null +++ b/libfprint/drivers/upeksonly.h @@ -0,0 +1,126 @@ +/* + * UPEK TouchStrip Sensor-Only driver for libfprint + * Copyright (C) 2008 Daniel Drake + * + * TCS4C (USB ID 147e:1000) support: + * Copyright (C) 2010 Hugo Grostabussiat + * + * 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 + */ + +struct sonly_regwrite { + uint8_t reg; + uint8_t value; +}; + +/***** AWAIT FINGER *****/ + +static const struct sonly_regwrite awfsm_2016_writev_1[] = { + { 0x0a, 0x00 }, { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x3b }, + { 0x00, 0x67 }, { 0x00, 0x67 }, +}; + +static const struct sonly_regwrite awfsm_1000_writev_1[] = { + /* Initialize sensor settings */ + { 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x37 }, { 0x00, 0x5f }, + { 0x01, 0x6e }, { 0x01, 0xee }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, + { 0x0e, 0x0e }, { 0x0f, 0x0d }, + + { 0x13, 0x05 }, { 0x13, 0x45 }, + + /* Initialize finger detection registers (not enabling yet) */ + { 0x30, 0xe0 }, { 0x15, 0x26 }, + + { 0x12, 0x01 }, { 0x20, 0x01 }, { 0x07, 0x10 }, + { 0x10, 0x00 }, { 0x11, 0xbf }, +}; + +static const struct sonly_regwrite awfsm_2016_writev_2[] = { + { 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e }, + { 0x0f, 0x0d }, { 0x0b, 0x00 }, +}; + +static const struct sonly_regwrite awfsm_1000_writev_2[] = { + /* Enable finger detection */ + { 0x30, 0xe1 }, { 0x15, 0x06 }, { 0x15, 0x86 }, +}; + +static const struct sonly_regwrite awfsm_2016_writev_3[] = { + { 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 }, + { 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 }, +}; + +static const struct sonly_regwrite awfsm_2016_writev_4[] = { + { 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf }, + { 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 },\ + { 0x05, 0x00 }, { 0x0b, 0x00 }, + + /* enter finger detection mode */ + { 0x15, 0x20 }, { 0x30, 0xe1 }, { 0x15, 0x24 }, { 0x15, 0x04 }, + { 0x15, 0x84 }, +}; + +/***** CAPTURE MODE *****/ + +static const struct sonly_regwrite capsm_2016_writev[] = { + /* enter capture mode */ + { 0x09, 0x28 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, { 0x04, 0x00 }, + { 0x05, 0x00 }, +}; + +static const struct sonly_regwrite capsm_1000_writev[] = { + { 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */ +}; + +/***** DEINITIALIZATION *****/ + +static const struct sonly_regwrite deinitsm_2016_writev[] = { + /* reset + enter low power mode */ + { 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 }, +}; + +static const struct sonly_regwrite deinitsm_1000_writev[] = { + { 0x15, 0x26 }, { 0x30, 0xe0 }, /* Disable finger detection */ + + { 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */ +}; + +/***** INITIALIZATION *****/ + +static const struct sonly_regwrite initsm_2016_writev_1[] = { + { 0x49, 0x00 }, + + /* BSAPI writes different values to register 0x3e each time. I initially + * thought this was some kind of clever authentication, but just blasting + * these sniffed values each time seems to work. */ + { 0x3e, 0x83 }, { 0x3e, 0x4f }, { 0x3e, 0x0f }, { 0x3e, 0xbf }, + { 0x3e, 0x45 }, { 0x3e, 0x35 }, { 0x3e, 0x1c }, { 0x3e, 0xae }, + + { 0x44, 0x01 }, { 0x43, 0x06 }, { 0x43, 0x05 }, { 0x43, 0x04 }, + { 0x44, 0x00 }, { 0x0b, 0x00 }, +}; + +static const struct sonly_regwrite initsm_1000_writev_1[] = { + { 0x49, 0x00 }, /* Encryption disabled */ + + /* Setting encryption key. Doesn't need to be random since we don't use any + * encryption. */ + { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, + { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, + + { 0x04, 0x00 }, { 0x05, 0x00 }, + + { 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */ +}; From 6fc5293e8330e65ed21c0e43a18b3be061933e74 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 10:20:55 -0700 Subject: [PATCH 014/141] upeksonly: add support for 147e:1001 device --- libfprint/drivers/upeksonly.c | 302 ++++++++++++++++++++++++++++------ libfprint/drivers/upeksonly.h | 197 +++++++++++++++++++++- 2 files changed, 447 insertions(+), 52 deletions(-) diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 8f0c0c26..569b4aba 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -5,6 +5,9 @@ * TCS4C (USB ID 147e:1000) support: * Copyright (C) 2010 Hugo Grostabussiat * + * TCRD5B (USB ID 147e:1001) support: + * Copyright (C) 2014 Vasily Khoruzhick + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -34,14 +37,14 @@ #include "driver_ids.h" #define CTRL_TIMEOUT 1000 -#define IMG_WIDTH 288 #define NUM_BULK_TRANSFERS 24 -#define MAX_ROWS 700 +#define MAX_ROWS 1024 #define MIN_ROWS 64 enum { - UPEKSONLY_2016, - UPEKSONLY_1000, + UPEKSONLY_2016, + UPEKSONLY_1000, + UPEKSONLY_1001, }; struct img_transfer_data { @@ -67,12 +70,19 @@ enum sonly_kill_transfers_action { EXEC_CALLBACK, }; +enum sonly_fs { + AWAIT_FINGER, + FINGER_DETECTED, + FINGER_REMOVED, +}; + struct sonly_dev { gboolean capturing; gboolean deactivating; uint8_t read_reg_result; int dev_model; + int img_width; struct fpi_ssm *loopsm; struct libusb_transfer *img_transfer[NUM_BULK_TRANSFERS]; @@ -86,8 +96,11 @@ struct sonly_dev { int wraparounds; int num_blank; - int finger_removed; + int num_nonblank; + enum sonly_fs finger_state; int last_seqnum; + int diff_thresh; + int total_thresh; enum sonly_kill_transfers_action killing_transfers; int kill_status_code; @@ -158,13 +171,13 @@ static void cancel_img_transfers(struct fp_img_dev *dev) static gboolean is_capturing(struct sonly_dev *sdev) { - return sdev->num_rows < MAX_ROWS && !sdev->finger_removed; + return sdev->num_rows < MAX_ROWS && (sdev->finger_state != FINGER_REMOVED); } static void handoff_img(struct fp_img_dev *dev) { struct sonly_dev *sdev = dev->priv; - size_t size = IMG_WIDTH * sdev->num_rows; + size_t size = sdev->img_width * sdev->num_rows; struct fp_img *img = fpi_img_new(size); GSList *elem = sdev->rows; size_t offset = 0; @@ -181,10 +194,10 @@ static void handoff_img(struct fp_img_dev *dev) * It feels a lot smarter to correct here than mess with it at * read time*/ do { - memcpy(img->data + offset, elem->data + 2, IMG_WIDTH - 2); - memcpy(img->data + offset + IMG_WIDTH - 2, elem->data, 2); + memcpy(img->data + offset, elem->data + 2, sdev->img_width - 2); + memcpy(img->data + offset + sdev->img_width - 2, elem->data, 2); g_free(elem->data); - offset += IMG_WIDTH; + offset += sdev->img_width; } while ((elem = g_slist_next(elem)) != NULL); g_slist_free(sdev->rows); @@ -198,14 +211,14 @@ static void handoff_img(struct fp_img_dev *dev) cancel_img_transfers(dev); } -static void compute_rows(unsigned char *a, unsigned char *b, int *diff, +static void compute_rows(struct sonly_dev *sdev, unsigned char *a, unsigned char *b, int *diff, int *total) { int i; int _total = 0; int _diff = 0; - for (i = 0; i < IMG_WIDTH; i++) { + for (i = 0; i < sdev->img_width; i++) { if (a[i] > b[i]) _diff += a[i] - b[i]; else @@ -226,9 +239,34 @@ static void row_complete(struct fp_img_dev *dev) int diff; int total; - compute_rows(lastrow, sdev->rowbuf, &diff, &total); + compute_rows(sdev, lastrow, sdev->rowbuf, &diff, &total); - if (total < 52000) { + switch (sdev->finger_state) { + case AWAIT_FINGER: + if (sdev->deactivating) { + sdev->killing_transfers = ITERATE_SSM; + sdev->kill_ssm = sdev->loopsm; + cancel_img_transfers(dev); + } + fp_dbg("total: %d", total); + if (total < sdev->total_thresh) { + sdev->num_nonblank++; + } else { + sdev->num_nonblank = 0; + } + + if (sdev->num_nonblank > 32) { + sdev->finger_state = FINGER_DETECTED; + fpi_imgdev_report_finger_status(dev, TRUE); + } + break; + case FINGER_DETECTED: + case FINGER_REMOVED: + default: + break; + } + + if (total < sdev->total_thresh) { sdev->num_blank = 0; } else { sdev->num_blank++; @@ -239,20 +277,35 @@ static void row_complete(struct fp_img_dev *dev) * actual scan. Happens most commonly if scan is started * from before the first joint resulting in a gap after the inital touch. */ - if ((sdev->num_blank > 500) + if ((sdev->num_blank > 32) && ((sdev->num_rows > MIN_ROWS) || (sdev->num_blank > 5000))) { - sdev->finger_removed = 1; + sdev->finger_state = FINGER_REMOVED; fp_dbg("detected finger removal. Blank rows: %d, Full rows: %d", sdev->num_blank, sdev->num_rows); handoff_img(dev); return; } } - if (diff < 3000) + fp_dbg("diff is %d", diff); + if (diff < sdev->diff_thresh) { return; + } } - sdev->rows = g_slist_prepend(sdev->rows, sdev->rowbuf); - sdev->num_rows++; + switch (sdev->finger_state) { + case AWAIT_FINGER: + if (!sdev->num_rows) { + sdev->rows = g_slist_prepend(sdev->rows, sdev->rowbuf); + sdev->num_rows++; + } else { + return; + } + break; + case FINGER_DETECTED: + case FINGER_REMOVED: + sdev->rows = g_slist_prepend(sdev->rows, sdev->rowbuf); + sdev->num_rows++; + break; + } sdev->rowbuf = NULL; if (sdev->num_rows >= MAX_ROWS) { @@ -268,7 +321,7 @@ static void add_to_rowbuf(struct fp_img_dev *dev, unsigned char *data, int size) memcpy(sdev->rowbuf + sdev->rowbuf_offset, data, size); sdev->rowbuf_offset += size; - if (sdev->rowbuf_offset >= IMG_WIDTH) + if (sdev->rowbuf_offset >= sdev->img_width) row_complete(dev); } @@ -276,7 +329,7 @@ static void add_to_rowbuf(struct fp_img_dev *dev, unsigned char *data, int size) static void start_new_row(struct sonly_dev *sdev, unsigned char *data, int size) { if (!sdev->rowbuf) - sdev->rowbuf = g_malloc(IMG_WIDTH); + sdev->rowbuf = g_malloc(sdev->img_width); memcpy(sdev->rowbuf, data, size); sdev->rowbuf_offset = size; } @@ -290,7 +343,7 @@ static int rowbuf_remaining(struct sonly_dev *sdev) if (sdev->rowbuf_offset == -1) return -1; - r = IMG_WIDTH - sdev->rowbuf_offset; + r = sdev->img_width - sdev->rowbuf_offset; if (r > 62) r = 62; return r; @@ -322,7 +375,7 @@ static void handle_packet(struct fp_img_dev *dev, unsigned char *data) /* If possible take the replacement data from last row */ if (sdev->num_rows > 1) { - int row_left = IMG_WIDTH - sdev->rowbuf_offset; + int row_left = sdev->img_width - sdev->rowbuf_offset; unsigned char *last_row = g_slist_nth_data (sdev->rows, 0); if (row_left >= 62) { @@ -341,12 +394,12 @@ static void handle_packet(struct fp_img_dev *dev, unsigned char *data) if (for_rowbuf < 62) { start_new_row(sdev, dummy_data + for_rowbuf, 62 - for_rowbuf); } - } else if (abs_base_addr % IMG_WIDTH == 0) { + } else if (abs_base_addr % sdev->img_width == 0) { start_new_row(sdev, dummy_data, 62); } else { /* does the data in the packet reside on a row boundary? * if so capture it */ - next_row_addr = ((abs_base_addr / IMG_WIDTH) + 1) * IMG_WIDTH; + next_row_addr = ((abs_base_addr / sdev->img_width) + 1) * sdev->img_width; diff = next_row_addr - abs_base_addr; if (diff < 62) start_new_row(sdev, dummy_data + diff, 62 - diff); @@ -377,14 +430,14 @@ static void handle_packet(struct fp_img_dev *dev, unsigned char *data) } /* does the packet START on a boundary? if so we want it in full */ - if (abs_base_addr % IMG_WIDTH == 0) { + if (abs_base_addr % sdev->img_width == 0) { start_new_row(sdev, data, 62); return; } /* does the data in the packet reside on a row boundary? * if so capture it */ - next_row_addr = ((abs_base_addr / IMG_WIDTH) + 1) * IMG_WIDTH; + next_row_addr = ((abs_base_addr / sdev->img_width) + 1) * sdev->img_width; diff = next_row_addr - abs_base_addr; if (diff < 62) start_new_row(sdev, data + diff, 62 - diff); @@ -614,6 +667,7 @@ static void sm_await_intr_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = ssm->priv; + struct sonly_dev *sdev = dev->priv; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { g_free(transfer->buffer); @@ -626,6 +680,7 @@ static void sm_await_intr_cb(struct libusb_transfer *transfer) transfer->buffer[2], transfer->buffer[3]); g_free(transfer->buffer); + sdev->finger_state = FINGER_DETECTED; fpi_imgdev_report_finger_status(dev, TRUE); fpi_ssm_next_state(ssm); } @@ -756,6 +811,17 @@ enum capsm_1000_states { CAPSM_1000_NUM_STATES, }; +enum capsm_1001_states { + CAPSM_1001_INIT, + CAPSM_1001_FIRE_BULK, + CAPSM_1001_WRITEV_1, + CAPSM_1001_WRITEV_2, + CAPSM_1001_WRITEV_3, + CAPSM_1001_WRITEV_4, + CAPSM_1001_WRITEV_5, + CAPSM_1001_NUM_STATES, +}; + static void capsm_fire_bulk(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; @@ -797,7 +863,8 @@ static void capsm_2016_run_state(struct fpi_ssm *ssm) sdev->num_rows = 0; sdev->wraparounds = -1; sdev->num_blank = 0; - sdev->finger_removed = 0; + sdev->num_nonblank = 0; + sdev->finger_state = FINGER_DETECTED; sdev->last_seqnum = 16383; sdev->killing_transfers = 0; fpi_ssm_next_state(ssm); @@ -828,7 +895,8 @@ static void capsm_1000_run_state(struct fpi_ssm *ssm) sdev->num_rows = 0; sdev->wraparounds = -1; sdev->num_blank = 0; - sdev->finger_removed = 0; + sdev->num_nonblank = 0; + sdev->finger_state = FINGER_DETECTED; sdev->last_seqnum = 16383; sdev->killing_transfers = 0; fpi_ssm_next_state(ssm); @@ -842,6 +910,44 @@ static void capsm_1000_run_state(struct fpi_ssm *ssm) } } +static void capsm_1001_run_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct sonly_dev *sdev = dev->priv; + + switch (ssm->cur_state) { + case CAPSM_1001_INIT: + sdev->rowbuf_offset = -1; + sdev->num_rows = 0; + sdev->wraparounds = -1; + sdev->num_blank = 0; + sdev->num_nonblank = 0; + sdev->finger_state = AWAIT_FINGER; + sdev->last_seqnum = 16383; + sdev->killing_transfers = 0; + fpi_ssm_next_state(ssm); + break; + case CAPSM_1001_FIRE_BULK: ; + capsm_fire_bulk (ssm); + break; + case CAPSM_1001_WRITEV_1: + sm_write_regs(ssm, capsm_1001_writev_1, G_N_ELEMENTS(capsm_1001_writev_1)); + break; + case CAPSM_1001_WRITEV_2: + sm_write_regs(ssm, capsm_1001_writev_2, G_N_ELEMENTS(capsm_1001_writev_2)); + break; + case CAPSM_1001_WRITEV_3: + sm_write_regs(ssm, capsm_1001_writev_3, G_N_ELEMENTS(capsm_1001_writev_3)); + break; + case CAPSM_1001_WRITEV_4: + sm_write_regs(ssm, capsm_1001_writev_4, G_N_ELEMENTS(capsm_1001_writev_4)); + break; + case CAPSM_1001_WRITEV_5: + sm_write_regs(ssm, capsm_1001_writev_5, G_N_ELEMENTS(capsm_1001_writev_5)); + break; + } +} + /***** DEINITIALIZATION *****/ enum deinitsm_2016_states { @@ -854,6 +960,11 @@ enum deinitsm_1000_states { DEINITSM_1000_NUM_STATES, }; +enum deinitsm_1001_states { + DEINITSM_1001_WRITEV, + DEINITSM_1001_NUM_STATES, +}; + static void deinitsm_2016_run_state(struct fpi_ssm *ssm) { switch (ssm->cur_state) { @@ -872,6 +983,15 @@ static void deinitsm_1000_run_state(struct fpi_ssm *ssm) } } +static void deinitsm_1001_run_state(struct fpi_ssm *ssm) +{ + switch (ssm->cur_state) { + case DEINITSM_1001_WRITEV: + sm_write_regs(ssm, deinitsm_1001_writev, G_N_ELEMENTS(deinitsm_1001_writev)); + break; + } +} + /***** INITIALIZATION *****/ enum initsm_2016_states { @@ -890,6 +1010,15 @@ enum initsm_1000_states { INITSM_1000_NUM_STATES, }; +enum initsm_1001_states { + INITSM_1001_WRITEV_1, + INITSM_1001_WRITEV_2, + INITSM_1001_WRITEV_3, + INITSM_1001_WRITEV_4, + INITSM_1001_WRITEV_5, + INITSM_1001_NUM_STATES, +}; + static void initsm_2016_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; @@ -929,6 +1058,27 @@ static void initsm_1000_run_state(struct fpi_ssm *ssm) } } +static void initsm_1001_run_state(struct fpi_ssm *ssm) +{ + switch (ssm->cur_state) { + case INITSM_1001_WRITEV_1: + sm_write_regs(ssm, initsm_1001_writev_1, G_N_ELEMENTS(initsm_1001_writev_1)); + break; + case INITSM_1001_WRITEV_2: + sm_write_regs(ssm, initsm_1001_writev_2, G_N_ELEMENTS(initsm_1001_writev_2)); + break; + case INITSM_1001_WRITEV_3: + sm_write_regs(ssm, initsm_1001_writev_3, G_N_ELEMENTS(initsm_1001_writev_3)); + break; + case INITSM_1001_WRITEV_4: + sm_write_regs(ssm, initsm_1001_writev_4, G_N_ELEMENTS(initsm_1001_writev_4)); + break; + case INITSM_1001_WRITEV_5: + sm_write_regs(ssm, initsm_1001_writev_5, G_N_ELEMENTS(initsm_1001_writev_5)); + break; + } +} + /***** CAPTURE LOOP *****/ enum loopsm_states { @@ -948,26 +1098,44 @@ static void loopsm_run_state(struct fpi_ssm *ssm) switch (ssm->cur_state) { case LOOPSM_RUN_AWFSM: ; - if (sdev->deactivating) { - fpi_ssm_mark_completed(ssm); - } else { - struct fpi_ssm *awfsm = NULL; - switch (sdev->dev_model) { - case UPEKSONLY_2016: - awfsm = fpi_ssm_new(dev->dev, awfsm_2016_run_state, - AWFSM_2016_NUM_STATES); - break; - case UPEKSONLY_1000: - awfsm = fpi_ssm_new(dev->dev, awfsm_1000_run_state, - AWFSM_1000_NUM_STATES); - break; + switch (sdev->dev_model) { + case UPEKSONLY_1001: + if (sdev->deactivating) { + fpi_ssm_mark_completed(ssm); + } else { + fpi_ssm_next_state(ssm); } - awfsm->priv = dev; - fpi_ssm_start_subsm(ssm, awfsm); + break; + default: + if (sdev->deactivating) { + fpi_ssm_mark_completed(ssm); + } else { + struct fpi_ssm *awfsm = NULL; + switch (sdev->dev_model) { + case UPEKSONLY_2016: + awfsm = fpi_ssm_new(dev->dev, awfsm_2016_run_state, + AWFSM_2016_NUM_STATES); + break; + case UPEKSONLY_1000: + awfsm = fpi_ssm_new(dev->dev, awfsm_1000_run_state, + AWFSM_1000_NUM_STATES); + break; + } + awfsm->priv = dev; + fpi_ssm_start_subsm(ssm, awfsm); + } + break; } break; case LOOPSM_AWAIT_FINGER: - sm_await_intr(ssm); + switch (sdev->dev_model) { + case UPEKSONLY_1001: + fpi_ssm_next_state(ssm); + break; + default: + sm_await_intr(ssm); + break; + } break; case LOOPSM_RUN_CAPSM: ; struct fpi_ssm *capsm = NULL; @@ -980,13 +1148,15 @@ static void loopsm_run_state(struct fpi_ssm *ssm) capsm = fpi_ssm_new(dev->dev, capsm_1000_run_state, CAPSM_1000_NUM_STATES); break; + case UPEKSONLY_1001: + capsm = fpi_ssm_new(dev->dev, capsm_1001_run_state, + CAPSM_1001_NUM_STATES); + break; } capsm->priv = dev; fpi_ssm_start_subsm(ssm, capsm); break; case LOOPSM_CAPTURE: - /* bulk URBs already flying, so just wait for image completion - * to push us into next state */ break; case LOOPSM_RUN_DEINITSM: ; struct fpi_ssm *deinitsm = NULL; @@ -999,6 +1169,10 @@ static void loopsm_run_state(struct fpi_ssm *ssm) deinitsm = fpi_ssm_new(dev->dev, deinitsm_1000_run_state, DEINITSM_1000_NUM_STATES); break; + case UPEKSONLY_1001: + deinitsm = fpi_ssm_new(dev->dev, deinitsm_1001_run_state, + DEINITSM_1001_NUM_STATES); + break; } sdev->capturing = FALSE; deinitsm->priv = dev; @@ -1115,6 +1289,9 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) case UPEKSONLY_1000: ssm = fpi_ssm_new(dev->dev, initsm_1000_run_state, INITSM_1000_NUM_STATES); break; + case UPEKSONLY_1001: + ssm = fpi_ssm_new(dev->dev, initsm_1001_run_state, INITSM_1001_NUM_STATES); + break; } ssm->priv = dev; fpi_ssm_start(ssm, initsm_complete); @@ -1124,6 +1301,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { int r; + struct sonly_dev *sdev; r = libusb_set_configuration(dev->udev, 1); if (r < 0) { @@ -1137,8 +1315,28 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) return r; } - dev->priv = g_malloc0(sizeof(struct sonly_dev)); - ((struct sonly_dev*)dev->priv)->dev_model = (int)driver_data; + sdev = dev->priv = g_malloc0(sizeof(struct sonly_dev)); + sdev->dev_model = (int)driver_data; + switch (driver_data) { + case UPEKSONLY_1000: + sdev->img_width = IMG_WIDTH_1000; + upeksonly_driver.img_width = IMG_WIDTH_1000; + sdev->diff_thresh = 3000; + sdev->total_thresh = 52000; + break; + case UPEKSONLY_1001: + sdev->img_width = IMG_WIDTH_1001; + upeksonly_driver.img_width = IMG_WIDTH_1001; + sdev->diff_thresh = 1300; + sdev->total_thresh = 40000; + break; + case UPEKSONLY_2016: + sdev->img_width = IMG_WIDTH_2016; + upeksonly_driver.img_width = IMG_WIDTH_2016; + sdev->diff_thresh = 3000; + sdev->total_thresh = 52000; + break; + } fpi_imgdev_open_complete(dev, 0); return 0; } @@ -1161,12 +1359,16 @@ static int dev_discover(struct libusb_device_descriptor *dsc, uint32_t *devtype) return 1; } + if (dsc->idProduct == 0x1001) + return 1; + return 0; } static const struct usb_id id_table[] = { { .vendor = 0x147e, .product = 0x2016, .driver_data = UPEKSONLY_2016 }, { .vendor = 0x147e, .product = 0x1000, .driver_data = UPEKSONLY_1000 }, + { .vendor = 0x147e, .product = 0x1001, .driver_data = UPEKSONLY_1001 }, { 0, 0, 0, }, }; @@ -1180,7 +1382,7 @@ struct fp_img_driver upeksonly_driver = { .discover = dev_discover, }, .flags = 0, - .img_width = IMG_WIDTH, + .img_width = -1, .img_height = -1, .open = dev_init, diff --git a/libfprint/drivers/upeksonly.h b/libfprint/drivers/upeksonly.h index ac00da2d..4a3f72ba 100644 --- a/libfprint/drivers/upeksonly.h +++ b/libfprint/drivers/upeksonly.h @@ -5,6 +5,9 @@ * TCS4C (USB ID 147e:1000) support: * Copyright (C) 2010 Hugo Grostabussiat * + * TCRD5B (USB ID 147e:1001) support: + * Copyright (C) 2014 Vasily Khoruzhick + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -20,6 +23,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define IMG_WIDTH_2016 288 +#define IMG_WIDTH_1000 288 +#define IMG_WIDTH_1001 216 + struct sonly_regwrite { uint8_t reg; uint8_t value; @@ -66,7 +73,7 @@ static const struct sonly_regwrite awfsm_2016_writev_4[] = { { 0x08, 0x00 }, { 0x10, 0x00 }, { 0x12, 0x01 }, { 0x11, 0xbf }, { 0x12, 0x01 }, { 0x07, 0x10 }, { 0x07, 0x10 }, { 0x04, 0x00 },\ { 0x05, 0x00 }, { 0x0b, 0x00 }, - + /* enter finger detection mode */ { 0x15, 0x20 }, { 0x30, 0xe1 }, { 0x15, 0x24 }, { 0x15, 0x04 }, { 0x15, 0x84 }, @@ -84,6 +91,57 @@ static const struct sonly_regwrite capsm_1000_writev[] = { { 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */ }; +static const struct sonly_regwrite capsm_1001_writev_1[] = { + { 0x1a, 0x02 }, + { 0x4a, 0x9d }, + { 0x4e, 0x05 }, +}; + + +static const struct sonly_regwrite capsm_1001_writev_2[] = { + { 0x4d, 0xc0 }, { 0x4e, 0x09 }, +}; + +static const struct sonly_regwrite capsm_1001_writev_3[] = { + { 0x4a, 0x9c }, + { 0x1a, 0x00 }, + { 0x0b, 0x00 }, + { 0x04, 0x00 }, + { 0x05, 0x00 }, + { 0x1a, 0x02 }, + { 0x4a, 0x9d }, + { 0x4d, 0x40 }, { 0x4e, 0x09 }, +}; + +static const struct sonly_regwrite capsm_1001_writev_4[] = { + { 0x4a, 0x9c }, + { 0x1a, 0x00 }, + { 0x1a, 0x02 }, + { 0x4a, 0x9d }, + { 0x4e, 0x08 }, +}; + + +static const struct sonly_regwrite capsm_1001_writev_5[] = { + { 0x4a, 0x9c }, + { 0x1a, 0x00 }, + { 0x1a, 0x02 }, + { 0x00, 0x5f }, { 0x01, 0xee }, + { 0x03, 0x2c }, + { 0x07, 0x00 }, { 0x08, 0x00 }, { 0x09, 0x29 }, { 0x0a, 0x00 }, { 0x0b, 0x00 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e }, + { 0x0f, 0x0d }, { 0x10, 0x00 }, { 0x11, 0x8f }, { 0x12, 0x01 }, { 0x13, 0x45 }, + { 0x15, 0x26 }, + { 0x1e, 0x02 }, + { 0x20, 0x01 }, + { 0x25, 0x8f }, + { 0x27, 0x23 }, + { 0x30, 0xe0 }, + { 0x07, 0x10 }, + { 0x09, 0x21 }, + { 0x13, 0x75 }, + { 0x0b, 0x80 }, +}; + /***** DEINITIALIZATION *****/ static const struct sonly_regwrite deinitsm_2016_writev[] = { @@ -97,11 +155,18 @@ static const struct sonly_regwrite deinitsm_1000_writev[] = { { 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */ }; +static const struct sonly_regwrite deinitsm_1001_writev[] = { + { 0x0b, 0x00 }, + { 0x13, 0x45 }, + { 0x09, 0x29 }, + { 0x1a, 0x00 }, +}; + /***** INITIALIZATION *****/ static const struct sonly_regwrite initsm_2016_writev_1[] = { { 0x49, 0x00 }, - + /* BSAPI writes different values to register 0x3e each time. I initially * thought this was some kind of clever authentication, but just blasting * these sniffed values each time seems to work. */ @@ -124,3 +189,131 @@ static const struct sonly_regwrite initsm_1000_writev_1[] = { { 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */ }; + +static const struct sonly_regwrite initsm_1001_writev_1[] = { + { 0x4a, 0x9d }, + { 0x4f, 0x06 }, + { 0x4f, 0x05 }, + { 0x4f, 0x04 }, + { 0x4a, 0x9c }, + { 0x3e, 0xa6 }, + { 0x3e, 0x01 }, + { 0x3e, 0x68 }, + { 0x3e, 0xfd }, + { 0x3e, 0x72 }, + { 0x3e, 0xef }, + { 0x3e, 0x5d }, + { 0x3e, 0xc5 }, + { 0x1a, 0x02 }, + { 0x4a, 0x9d }, + { 0x4c, 0x1f }, { 0x4d, 0xb8 }, { 0x4e, 0x00 }, +}; + + +static const struct sonly_regwrite initsm_1001_writev_2[] = { + { 0x4c, 0x03 }, { 0x4d, 0xb8 }, { 0x4e, 0x00 }, +}; + +static const struct sonly_regwrite initsm_1001_writev_3[] = { + { 0x4a, 0x9c }, + { 0x1a, 0x00 }, + { 0x1a, 0x02 }, + { 0x4a, 0x9d }, + { 0x4c, 0xff }, { 0x4d, 0xc0 }, { 0x4e, 0x00 }, +}; + + +static const struct sonly_regwrite initsm_1001_writev_4[] = { + { 0x4a, 0x9c }, + { 0x1a, 0x00 }, + { 0x09, 0x27 }, + { 0x1a, 0x02 }, + { 0x49, 0x01 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x0a }, + { 0x47, 0x00 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x0a }, + { 0x47, 0x00 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x0a }, + { 0x47, 0x00 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x02 }, + { 0x47, 0x0a }, + { 0x47, 0x00 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x47, 0x04 }, + { 0x49, 0x00 }, + { 0x3e, 0x90 }, + { 0x3e, 0xbd }, + { 0x3e, 0xbf }, + { 0x3e, 0x48 }, + { 0x3e, 0x2a }, + { 0x3e, 0xe3 }, + { 0x3e, 0xd2 }, + { 0x3e, 0x58 }, + { 0x09, 0x2f }, + { 0x1a, 0x00 }, + { 0x1a, 0x02 }, + { 0x4a, 0x9d }, + { 0x4d, 0x40 }, { 0x4e, 0x03 }, +}; + +static const struct sonly_regwrite initsm_1001_writev_5[] = { + { 0x4a, 0x9c }, + { 0x1a, 0x00 }, +}; From b51fa446e38e621c1965998e1e404574599dc728 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 5 Sep 2015 09:38:10 -0700 Subject: [PATCH 015/141] lib: move line assembling routines out of vfs5011 into common code --- libfprint/assembling.c | 132 +++++++++++++++++++++++++++ libfprint/assembling.h | 16 ++++ libfprint/drivers/vfs5011.c | 173 ++++++++---------------------------- 3 files changed, 183 insertions(+), 138 deletions(-) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index dd8d2127..87711bd0 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -1,6 +1,7 @@ /* * Image assembling routines * Copyright (C) 2007-2008 Daniel Drake + * Copyright (C) 2013 Arseniy Lartsev * Copyright (C) 2015 Vasily Khoruzhick * * This library is free software; you can redistribute it and/or @@ -275,3 +276,134 @@ struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, return img; } + +static int cmpint(const void *p1, const void *p2, gpointer data) +{ + int a = *((int *)p1); + int b = *((int *)p2); + if (a < b) + return -1; + else if (a == b) + return 0; + else + return 1; +} + +static void median_filter(int *data, int size, int filtersize) +{ + int i; + int *result = (int *)g_malloc0(size*sizeof(int)); + int *sortbuf = (int *)g_malloc0(filtersize*sizeof(int)); + for (i = 0; i < size; i++) { + int i1 = i - (filtersize-1)/2; + int i2 = i + (filtersize-1)/2; + if (i1 < 0) + i1 = 0; + if (i2 >= size) + i2 = size-1; + g_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]; + } + memmove(data, result, size*sizeof(int)); + g_free(result); + g_free(sortbuf); +} + +static void interpolate_lines(struct fpi_line_asmbl_ctx *ctx, + GSList *line1, float y1, GSList *line2, + float y2, unsigned char *output, float yi, int size) +{ + int i; + unsigned char p1, p2; + + if (!line1 || !line2) + return; + + for (i = 0; i < size; i++) { + p1 = ctx->get_pixel(ctx, line1, i); + p2 = ctx->get_pixel(ctx, line2, i); + output[i] = (float)p1 + + (yi - y1)/(y2 - y1)*(p2 - p1); + } +} + +static int min(int a, int b) {return (a < b) ? a : b; } + +/* Rescale image to account for variable swiping speed */ +struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx, + GSList *lines, size_t lines_len) +{ + /* Number of output lines per distance between two scanners */ + int i; + GSList *row1, *row2; + float y = 0.0; + int line_ind = 0; + int *offsets = (int *)g_malloc0((lines_len / 2) * sizeof(int)); + unsigned char *output = g_malloc0(ctx->line_width * ctx->max_height); + struct fp_img *img; + + fp_dbg("%llu", g_get_real_time()); + + row1 = lines; + for (i = 0; (i < lines_len - 1) && row1; i += 2) { + int bestmatch = i; + int bestdiff = 0; + int j, firstrow, lastrow; + + firstrow = i + 1; + lastrow = min(i + ctx->max_search_offset, lines_len - 1); + + row2 = g_slist_next(row1); + for (j = firstrow; j <= lastrow; j++) { + int diff = ctx->get_deviation(ctx, + row1, + row2); + if ((j == firstrow) || (diff < bestdiff)) { + bestdiff = diff; + bestmatch = j; + } + row2 = g_slist_next(row2); + } + offsets[i / 2] = bestmatch - i; + fp_dbg("%d", offsets[i / 2]); + row1 = g_slist_next(row1); + if (row1) + row1 = g_slist_next(row1); + } + + median_filter(offsets, (lines_len / 2) - 1, ctx->median_filter_size); + + fp_dbg("offsets_filtered: %llu", g_get_real_time()); + for (i = 0; i <= (lines_len / 2) - 1; i++) + fp_dbg("%d", offsets[i]); + row1 = lines; + for (i = 0; i < lines_len - 1; i++, row1 = g_slist_next(row1)) { + int offset = offsets[i/2]; + if (offset > 0) { + float ynext = y + (float)ctx->resolution / offset; + while (line_ind < ynext) { + if (line_ind > ctx->max_height - 1) + goto out; + interpolate_lines(ctx, + row1, y, + g_slist_next(row1), + ynext, + output + line_ind * ctx->line_width, + line_ind, + ctx->line_width); + line_ind++; + } + y = ynext; + } + } +out: + img = fpi_img_new(ctx->line_width * line_ind); + 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); + g_free(offsets); + g_free(output); + return img; +} diff --git a/libfprint/assembling.h b/libfprint/assembling.h index 1d1905d3..4525006e 100644 --- a/libfprint/assembling.h +++ b/libfprint/assembling.h @@ -47,4 +47,20 @@ unsigned int fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, GSList *stripes, size_t stripes_len); +struct fpi_line_asmbl_ctx { + unsigned line_width; + unsigned max_height; + unsigned resolution; + unsigned median_filter_size; + unsigned max_search_offset; + int (*get_deviation)(struct fpi_line_asmbl_ctx *ctx, + GSList *line1, GSList *line2); + unsigned char (*get_pixel)(struct fpi_line_asmbl_ctx *ctx, + GSList *line, + unsigned x); +}; + +struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx, + GSList *lines, size_t lines_len); + #endif diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index c6d4586f..1878df79 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "driver_ids.h" #include "vfs5011_proto.h" @@ -285,9 +286,15 @@ static int get_diff_norm(unsigned char *buf1, unsigned char *buf2, int size) } /* Calculade squared standand deviation of sum of two lines */ -static int get_deviation2(unsigned char *buf1, unsigned char *buf2, int size) +static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1, GSList *row2) { + unsigned char *buf1, *buf2; int res = 0, mean = 0, i; + const int size = 64; + + buf1 = row1->data + 56; + buf2 = row2->data + 168; + for (i = 0; i < size; i++) mean += (int)buf1[i] + (int)buf2[i]; @@ -301,121 +308,13 @@ static int get_deviation2(unsigned char *buf1, unsigned char *buf2, int size) return res / size; } -static int cmpint(const void *p1, const void *p2, gpointer data) +static unsigned char vfs5011_get_pixel(struct fpi_line_asmbl_ctx *ctx, + GSList *row, + unsigned x) { - int a = *((int *)p1); - int b = *((int *)p2); - if (a < b) - return -1; - else if (a == b) - return 0; - else - return 1; -} + unsigned char *data = row->data + 8; -static void median_filter(int *data, int size, int filtersize) -{ - int i; - int *result = (int *)g_malloc0(size*sizeof(int)); - int *sortbuf = (int *)g_malloc0(filtersize*sizeof(int)); - for (i = 0; i < size; i++) { - int i1 = i - (filtersize-1)/2; - int i2 = i + (filtersize-1)/2; - if (i1 < 0) - i1 = 0; - if (i2 >= size) - i2 = size-1; - g_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]; - } - memmove(data, result, size*sizeof(int)); - g_free(result); - g_free(sortbuf); -} - -void interpolate_lines(unsigned char *line1, float y1, unsigned char *line2, - float y2, unsigned char *output, float yi, int size) -{ - int i; - for (i = 0; i < size; i++) - output[i] = (float)line1[i] - + (yi-y1)/(y2-y1)*(line2[i]-line1[i]); -} - -int min(int a, int b) {return (a < b) ? a : b; } - -/* Rescale image to account for variable swiping speed */ -int vfs5011_rescale_image(unsigned char *image, int input_lines, - unsigned char *output, int max_output_lines) -{ - /* Number of output lines per distance between two scanners */ - enum { - RESOLUTION = 10, - MEDIAN_FILTER_SIZE = 13, - MAX_OFFSET = 30, - GOOD_OFFSETS_CRITERION = 20, - GOOD_OFFSETS_THRESHOLD = 3 - }; - int i; - float y = 0.0; - int line_ind = 0; - int *offsets = (int *)g_malloc0(input_lines * sizeof(int)); -#ifdef ENABLE_DEBUG_LOGGING - gint64 start_time = g_get_real_time(); -#endif - - for (i = 0; i < input_lines-1; i += 2) { - int bestmatch = i; - int bestdiff = 0; - int j; - - int firstrow, lastrow; - firstrow = i+1; - lastrow = min(i + MAX_OFFSET, input_lines-1); - - for (j = firstrow; j <= lastrow; j++) { - int diff = get_deviation2( - image + i*VFS5011_LINE_SIZE + 56, - image + j*VFS5011_LINE_SIZE + 168, - 64); - if ((j == firstrow) || (diff < bestdiff)) { - bestdiff = diff; - bestmatch = j; - } - } - offsets[i/2] = bestmatch - i; - fp_dbg("offsets: %llu - %d", start_time, offsets[i/2]); - } - - median_filter(offsets, input_lines-1, MEDIAN_FILTER_SIZE); - - fp_dbg("offsets_filtered: %llu", g_get_real_time()); - for (i = 0; i <= input_lines/2-1; i++) - fp_dbg("%d", offsets[i]); - for (i = 0; i < input_lines-1; i++) { - int offset = offsets[i/2]; - if (offset > 0) { - float ynext = y + (float)RESOLUTION / offset; - while (line_ind < ynext) { - if (line_ind > max_output_lines-1) { - g_free(offsets); - return line_ind; - } - interpolate_lines( - image + i*VFS5011_LINE_SIZE + 8, y, - image + (i+1)*VFS5011_LINE_SIZE + 8, - ynext, - output + line_ind*VFS5011_IMAGE_WIDTH, - line_ind, - VFS5011_IMAGE_WIDTH); - line_ind++; - } - y = ynext; - } - } - g_free(offsets); - return line_ind; + return data[x]; } /* ====================== main stuff ======================= */ @@ -426,12 +325,22 @@ enum { MAX_CAPTURE_LINES = 100000, }; +static struct fpi_line_asmbl_ctx assembling_ctx = { + .line_width = VFS5011_IMAGE_WIDTH, + .max_height = MAXLINES, + .resolution = 10, + .median_filter_size = 25, + .max_search_offset = 30, + .get_deviation = vfs5011_get_deviation2, + .get_pixel = vfs5011_get_pixel, +}; + struct vfs5011_data { unsigned char *total_buffer; unsigned char *capture_buffer; - unsigned char *image_buffer; + unsigned char *row_buffer; unsigned char *lastline; - unsigned char *rescale_buffer; + GSList *rows; int lines_captured, lines_recorded, empty_lines; int max_lines_captured, max_lines_recorded; int lines_total, lines_total_allocated; @@ -511,10 +420,9 @@ static int process_chunk(struct vfs5011_data *data, int transferred) data->lastline + 8, linebuf + 8, VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) { - data->lastline = data->image_buffer - + data->lines_recorded - * VFS5011_LINE_SIZE; - memmove(data->lastline, linebuf, VFS5011_LINE_SIZE); + data->lastline = g_malloc(VFS5011_LINE_SIZE); + data->rows = g_slist_prepend(data->rows, data->lastline); + g_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", @@ -529,20 +437,14 @@ static int process_chunk(struct vfs5011_data *data, int transferred) void submit_image(struct fpi_ssm *ssm, struct vfs5011_data *data) { struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; - int height = vfs5011_rescale_image(data->image_buffer, - data->lines_recorded, - data->rescale_buffer, MAXLINES); - struct fp_img *img = fpi_img_new(VFS5011_IMAGE_WIDTH * height); + struct fp_img *img; - if (img == NULL) { - fp_err("Failed to create image"); - fpi_ssm_mark_aborted(ssm, -1); - } + data->rows = g_slist_reverse(data->rows); - img->flags = FP_IMG_V_FLIPPED; - img->width = VFS5011_IMAGE_WIDTH; - img->height = height; - memmove(img->data, data->rescale_buffer, VFS5011_IMAGE_WIDTH * height); + img = fpi_assemble_lines(&assembling_ctx, data->rows, data->lines_recorded); + + g_slist_free_full(data->rows, g_free); + data->rows = NULL; fp_dbg("Image captured, commiting"); @@ -927,10 +829,6 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) data = (struct vfs5011_data *)g_malloc0(sizeof(*data)); data->capture_buffer = (unsigned char *)g_malloc0(CAPTURE_LINES * VFS5011_LINE_SIZE); - data->image_buffer = - (unsigned char *)g_malloc0(MAXLINES * VFS5011_LINE_SIZE); - data->rescale_buffer = - (unsigned char *)g_malloc0(MAXLINES * VFS5011_IMAGE_WIDTH); dev->priv = data; r = libusb_reset_device(dev->udev); @@ -959,8 +857,7 @@ static void dev_close(struct fp_img_dev *dev) struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; if (data != NULL) { g_free(data->capture_buffer); - g_free(data->image_buffer); - g_free(data->rescale_buffer); + g_slist_free_full(data->rows, g_free); g_free(data); } fpi_imgdev_close_complete(dev); From 3746b2ad5c91e649488916179b44460609bab805 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 1 Sep 2015 08:39:38 -0700 Subject: [PATCH 016/141] upeksonly: use line assembling routines to account variable swiping speed --- libfprint/drivers/upeksonly.c | 89 +++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 569b4aba..22ada5e2 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -33,12 +33,14 @@ #include +#include + #include "upeksonly.h" #include "driver_ids.h" #define CTRL_TIMEOUT 1000 #define NUM_BULK_TRANSFERS 24 -#define MAX_ROWS 1024 +#define MAX_ROWS 2048 #define MIN_ROWS 64 enum { @@ -110,6 +112,59 @@ struct sonly_dev { }; }; + +/* Calculade squared standand deviation of sum of two lines */ +static int upeksonly_get_deviation2(struct fpi_line_asmbl_ctx *ctx, + GSList *line1, GSList *line2) +{ + unsigned char *buf1 = line1->data, *buf2 = line2->data; + int res = 0, mean = 0, i; + for (i = 0; i < ctx->line_width; i+= 2) + mean += (int)buf1[i + 1] + (int)buf2[i]; + + mean /= (ctx->line_width / 2); + + for (i = 0; i < ctx->line_width; i+= 2) { + int dev = (int)buf1[i + 1] + (int)buf2[i] - mean; + res += dev*dev; + } + + return res / (ctx->line_width / 2); +} + + +static unsigned char upeksonly_get_pixel(struct fpi_line_asmbl_ctx *ctx, + GSList *row, + unsigned x) +{ + unsigned char *buf; + unsigned offset; + + /* The scans from this device are rolled right by two colums */ + if (x < ctx->line_width - 2) + offset = x + 2; + else if ((x > ctx->line_width - 2) && (x < ctx->line_width)) + offset = x - (ctx->line_width - 2); + else + return 0; + /* Each 2nd pixel is shifted 2 pixels down */ + if ((!(x & 1)) && g_slist_next(row) && g_slist_next(g_slist_next(row))) + buf = g_slist_next(g_slist_next(row))->data; + else + buf = row->data; + + return buf[offset]; +} + +static struct fpi_line_asmbl_ctx assembling_ctx = { + .max_height = 1024, + .resolution = 8, + .median_filter_size = 25, + .max_search_offset = 30, + .get_deviation = upeksonly_get_deviation2, + .get_pixel = upeksonly_get_pixel, +}; + /***** IMAGE PROCESSING *****/ static void free_img_transfers(struct sonly_dev *sdev) @@ -177,30 +232,21 @@ static gboolean is_capturing(struct sonly_dev *sdev) static void handoff_img(struct fp_img_dev *dev) { struct sonly_dev *sdev = dev->priv; - size_t size = sdev->img_width * sdev->num_rows; - struct fp_img *img = fpi_img_new(size); + struct fp_img *img; + GSList *elem = sdev->rows; - size_t offset = 0; if (!elem) { fp_err("no rows?"); return; } + sdev->rows = g_slist_reverse(sdev->rows); + fp_dbg("%d rows", sdev->num_rows); - img->height = sdev->num_rows; + img = fpi_assemble_lines(&assembling_ctx, sdev->rows, sdev->num_rows); - /* The scans from this device are rolled right by two colums - * It feels a lot smarter to correct here than mess with it at - * read time*/ - do { - memcpy(img->data + offset, elem->data + 2, sdev->img_width - 2); - memcpy(img->data + offset + sdev->img_width - 2, elem->data, 2); - g_free(elem->data); - offset += sdev->img_width; - } while ((elem = g_slist_next(elem)) != NULL); - - g_slist_free(sdev->rows); + g_slist_free_full(sdev->rows, g_free); sdev->rows = NULL; fpi_imgdev_image_captured(dev, img); @@ -258,6 +304,8 @@ static void row_complete(struct fp_img_dev *dev) if (sdev->num_nonblank > 32) { sdev->finger_state = FINGER_DETECTED; fpi_imgdev_report_finger_status(dev, TRUE); + } else { + return; } break; case FINGER_DETECTED: @@ -1321,19 +1369,22 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) case UPEKSONLY_1000: sdev->img_width = IMG_WIDTH_1000; upeksonly_driver.img_width = IMG_WIDTH_1000; - sdev->diff_thresh = 3000; + assembling_ctx.line_width = IMG_WIDTH_1000; + sdev->diff_thresh = 1200; sdev->total_thresh = 52000; break; case UPEKSONLY_1001: sdev->img_width = IMG_WIDTH_1001; upeksonly_driver.img_width = IMG_WIDTH_1001; - sdev->diff_thresh = 1300; + assembling_ctx.line_width = IMG_WIDTH_1001; + sdev->diff_thresh = 400; sdev->total_thresh = 40000; break; case UPEKSONLY_2016: sdev->img_width = IMG_WIDTH_2016; upeksonly_driver.img_width = IMG_WIDTH_2016; - sdev->diff_thresh = 3000; + assembling_ctx.line_width = IMG_WIDTH_2016; + sdev->diff_thresh = 1200; sdev->total_thresh = 52000; break; } From c2a11c5918684a842c34418fd7630f26492790d2 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 12:23:33 -0700 Subject: [PATCH 017/141] aes1610: set partial flag on an image Set partial flag to remove false minutiae at the perimeter of a scan --- libfprint/drivers/aes1610.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index d8aaeaa8..b4de1a2e 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -635,6 +635,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, FALSE); } img = fpi_assemble_frames(&assembling_ctx, aesdev->strips, aesdev->strips_len); + img->flags |= FP_IMG_PARTIAL; g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; From 83f29dad9f42f4cae53c4d130ca792d25e6468c3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 12:24:21 -0700 Subject: [PATCH 018/141] aes2501: set partial flag on an image Set partial flag to remove false minutiae at the perimeter of a scan --- libfprint/drivers/aes2501.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 426bd9ed..87297409 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -505,6 +505,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) } img = fpi_assemble_frames(&assembling_ctx, aesdev->strips, aesdev->strips_len); + img->flags |= FP_IMG_PARTIAL; g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; From c9cdbaf8803be8c9ca33029419f006deb55d7e88 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 12:24:48 -0700 Subject: [PATCH 019/141] aes2550: set partial flag on an image Set partial flag to remove false minutiae at the perimeter of a scan --- libfprint/drivers/aes2550.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 822dbcd8..965bdb07 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -264,6 +264,7 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) aesdev->strips = g_slist_reverse(aesdev->strips); img = fpi_assemble_frames(&assembling_ctx, aesdev->strips, aesdev->strips_len); + img->flags |= FP_IMG_PARTIAL; g_slist_free_full(aesdev->strips, g_free); aesdev->strips = NULL; aesdev->strips_len = 0; From 0f0a4b2da6704505471aa2797fac7c41de21a862 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 12:25:05 -0700 Subject: [PATCH 020/141] aes2660: set partial flag on an image Set partial flag to remove false minutiae at the perimeter of a scan --- libfprint/drivers/aes2660.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index 2edb765b..7cae59c9 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -67,6 +67,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) aesdev->start_imaging_cmd = (unsigned char *)aes2660_start_imaging_cmd; aesdev->start_imaging_cmd_len = sizeof(aes2660_start_imaging_cmd); aesdev->assembling_ctx = &assembling_ctx; + aesdev->extra_img_flags = FP_IMG_PARTIAL; fpi_imgdev_open_complete(dev, 0); return 0; From f7d00a828dd0af5db75a80415758c848d48d11f8 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 19 Sep 2015 15:27:19 -0700 Subject: [PATCH 021/141] lib: use normalized error to make decision about movement direction Height is not a good determinant in movement direction, normalized error is much better. Should fix aes1610 and aes2501 driver issues. --- libfprint/assembling.c | 29 +++++++++++++++++++++-------- libfprint/assembling.h | 5 ++--- libfprint/drivers/aes1610.c | 9 +-------- libfprint/drivers/aes2501.c | 13 ++----------- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index 87711bd0..cde4eaf8 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -88,7 +88,7 @@ static void find_overlap(struct fpi_frame_asmbl_ctx *ctx, { int dx, dy; unsigned int err; - *min_error = INT_MAX; + *min_error = 255 * ctx->frame_height * ctx->frame_width; /* Seeking in horizontal and vertical dimensions, * for horizontal dimension we'll check only 8 pixels @@ -108,16 +108,20 @@ static void find_overlap(struct fpi_frame_asmbl_ctx *ctx, } } -unsigned int fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, +static unsigned int do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, GSList *stripes, size_t num_stripes, gboolean reverse) { GSList *list_entry = stripes; GTimer *timer; int frame = 1; - int height = 0; struct fpi_frame *prev_stripe = list_entry->data; unsigned int min_error; + /* Max error is width * height * 255, for AES2501 which has the largest + * sensor its 192*16*255 = 783360. So for 32bit value it's ~5482 frame before + * we might get int overflow. Use 64bit value here to prevent integer overflow + */ + unsigned long long total_error = 0; list_entry = g_slist_next(list_entry); @@ -132,22 +136,31 @@ unsigned int fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, } else find_overlap(ctx, cur_stripe, prev_stripe, &min_error); + total_error += min_error; frame++; - height += prev_stripe->delta_y; prev_stripe = cur_stripe; list_entry = g_slist_next(list_entry); } while (frame < num_stripes); - if (height < 0) - height = -height; - height += ctx->frame_height; g_timer_stop(timer); fp_dbg("calc delta completed in %f secs", g_timer_elapsed(timer, NULL)); g_timer_destroy(timer); - return height; + return total_error / num_stripes; +} + +void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, + GSList *stripes, size_t num_stripes) +{ + int err, rev_err; + err = do_movement_estimation(ctx, stripes, num_stripes, FALSE); + rev_err = do_movement_estimation(ctx, stripes, num_stripes, TRUE); + fp_dbg("errors: %d rev: %d", err, rev_err); + if (err < rev_err) { + do_movement_estimation(ctx, stripes, num_stripes, FALSE); + } } static inline void aes_blit_stripe(struct fpi_frame_asmbl_ctx *ctx, diff --git a/libfprint/assembling.h b/libfprint/assembling.h index 4525006e..3bcab2f7 100644 --- a/libfprint/assembling.h +++ b/libfprint/assembling.h @@ -40,9 +40,8 @@ struct fpi_frame_asmbl_ctx { unsigned y); }; -unsigned int fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, - GSList *stripes, size_t stripes_len, - gboolean reverse); +void fpi_do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, + GSList *stripes, size_t stripes_len); struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, GSList *stripes, size_t stripes_len); diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index b4de1a2e..afd0dbb8 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -621,19 +621,12 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) /* stop capturing if MAX_FRAMES is reached */ if (aesdev->blanks_count > 10 || g_slist_length(aesdev->strips) >= MAX_FRAMES) { struct fp_img *img; - unsigned int height, rev_height; fp_dbg("sending stop capture.... blanks=%d frames=%d", aesdev->blanks_count, g_slist_length(aesdev->strips)); /* send stop capture bits */ aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop), stub_capture_stop_cb, NULL); aesdev->strips = g_slist_reverse(aesdev->strips); - height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, FALSE); - rev_height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, TRUE); - fp_dbg("heights: %d rev: %d", height, rev_height); - if (rev_height < height) { - fp_dbg("Reversed direction"); - height = fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len, FALSE); - } + fpi_do_movement_estimation(&assembling_ctx, aesdev->strips, aesdev->strips_len); img = fpi_assemble_frames(&assembling_ctx, aesdev->strips, aesdev->strips_len); img->flags |= FP_IMG_PARTIAL; g_slist_free_full(aesdev->strips, g_free); diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 87297409..6c852a51 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -490,19 +490,10 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) aesdev->no_finger_cnt++; if (aesdev->no_finger_cnt == 3) { struct fp_img *img; - unsigned int height, rev_height; aesdev->strips = g_slist_reverse(aesdev->strips); - height = fpi_do_movement_estimation(&assembling_ctx, - aesdev->strips, aesdev->strips_len, FALSE); - rev_height = fpi_do_movement_estimation(&assembling_ctx, - aesdev->strips, aesdev->strips_len, TRUE); - fp_dbg("heights: %d rev: %d", height, rev_height); - if (rev_height < height) { - fp_dbg("Reversed direction"); - height = fpi_do_movement_estimation(&assembling_ctx, - aesdev->strips, aesdev->strips_len, FALSE); - } + fpi_do_movement_estimation(&assembling_ctx, + aesdev->strips, aesdev->strips_len); img = fpi_assemble_frames(&assembling_ctx, aesdev->strips, aesdev->strips_len); img->flags |= FP_IMG_PARTIAL; From 9437c98d54c33a5a752f4ffd28a761b7cbf32141 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 22 Sep 2015 19:49:58 -0700 Subject: [PATCH 022/141] lib: frame assembling: flip image for non-reverse direction It was here for aes2501 and aes1610 before moving assembling routines into common code. --- libfprint/assembling.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index cde4eaf8..1052f99d 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -266,6 +266,7 @@ struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, /* Create buffer big enough for max image */ img = fpi_img_new(ctx->image_width * height); img->flags = FP_IMG_COLORS_INVERTED; + img->flags |= reverse ? 0 : FP_IMG_H_FLIPPED | FP_IMG_V_FLIPPED; img->width = ctx->image_width; img->height = height; From 67d29f79368aab9604b23e1744907bfdbe9ec44c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 29 Sep 2015 17:08:51 -0700 Subject: [PATCH 023/141] aes1610: improve gain settings --- libfprint/drivers/aes1610.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index afd0dbb8..fc234d2d 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -413,7 +413,7 @@ static unsigned char list_BE_values[10] = { /* * The different possible values for 0xBD register */ static unsigned char list_BD_values[10] = { - 0x48, 0x4B, 0x4F, 0x52, 0x57, 0x59, 0x5B + 0x28, 0x2b, 0x30, 0x3b, 0x45, 0x49, 0x4B }; /* @@ -434,25 +434,25 @@ static int adjust_gain(unsigned char *buffer, int status) strip_scan_reqs[0].value = 0x6B; strip_scan_reqs[1].value = 0x06; strip_scan_reqs[2].value = 0x35; - strip_scan_reqs[3].value = 0x5B; + strip_scan_reqs[3].value = 0x4B; } else if (buffer[1] > 0x55) { strip_scan_reqs[0].value = 0x63; strip_scan_reqs[1].value = 0x15; strip_scan_reqs[2].value = 0x35; - strip_scan_reqs[3].value = 0x4F; + strip_scan_reqs[3].value = 0x3b; } else if (buffer[1] > 0x40 || buffer[16] > 0x19) { strip_scan_reqs[0].value = 0x43; strip_scan_reqs[1].value = 0x13; strip_scan_reqs[2].value = 0x35; - strip_scan_reqs[3].value = 0x4B; + strip_scan_reqs[3].value = 0x30; } else { // minimum gain needed strip_scan_reqs[0].value = 0x23; strip_scan_reqs[1].value = 0x07; strip_scan_reqs[2].value = 0x35; - strip_scan_reqs[3].value = 0x48; + strip_scan_reqs[3].value = 0x28; } // Now copy this values in capture_reqs From ffef6c2bcc87a40767b23891ec1e53a4d459e9c1 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 29 Sep 2015 17:10:42 -0700 Subject: [PATCH 024/141] vfs5011: add proper dev_deactivate() support Driver is not able to cancel imaging process without this change --- libfprint/drivers/vfs5011.c | 56 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 1878df79..a2267b23 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -347,6 +347,7 @@ struct vfs5011_data { gboolean loop_running; gboolean deactivating; struct usbexchange_data init_sequence; + struct libusb_transfer *flying_transfer; }; enum { @@ -468,10 +469,15 @@ static void chunk_capture_callback(struct libusb_transfer *transfer) else fpi_ssm_jump_to_state(ssm, DEV_ACTIVATE_READ_DATA); } else { - fp_err("Failed to capture data"); - fpi_ssm_mark_aborted(ssm, -1); + if (!data->deactivating) { + fp_err("Failed to capture data"); + fpi_ssm_mark_aborted(ssm, -1); + } else { + fpi_ssm_mark_completed(ssm); + } } libusb_free_transfer(transfer); + data->flying_transfer = NULL; } static int capture_chunk_async(struct vfs5011_data *data, @@ -486,12 +492,12 @@ static int capture_chunk_async(struct vfs5011_data *data, STOP_CHECK_LINES = 50 }; - struct libusb_transfer *transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, handle, VFS5011_IN_ENDPOINT_DATA, + data->flying_transfer = libusb_alloc_transfer(0); + libusb_fill_bulk_transfer(data->flying_transfer, handle, VFS5011_IN_ENDPOINT_DATA, data->capture_buffer, nline * VFS5011_LINE_SIZE, chunk_capture_callback, ssm, timeout); - return libusb_submit_transfer(transfer); + return libusb_submit_transfer(data->flying_transfer); } static void async_sleep_cb(void *data) @@ -700,6 +706,12 @@ static void activate_loop(struct fpi_ssm *ssm) fp_dbg("main_loop: state %d", ssm->cur_state); + if (data->deactivating) { + fp_dbg("deactivating, marking completed"); + fpi_ssm_mark_completed(ssm); + return; + } + switch (ssm->cur_state) { case DEV_ACTIVATE_REQUEST_FPRINT: data->init_sequence.stepcount = @@ -723,17 +735,12 @@ static void activate_loop(struct fpi_ssm *ssm) break; case DEV_ACTIVATE_READ_DATA: - if (data->deactivating) { - fp_dbg("deactivating, marking completed"); - fpi_ssm_mark_completed(ssm); - } else { - r = capture_chunk_async(data, dev->udev, CAPTURE_LINES, - READ_TIMEOUT, ssm); - if (r != 0) { - fp_err("Failed to capture data"); - fpi_imgdev_session_error(dev, r); - fpi_ssm_mark_aborted(ssm, r); - } + r = capture_chunk_async(data, dev->udev, CAPTURE_LINES, + READ_TIMEOUT, ssm); + if (r != 0) { + fp_err("Failed to capture data"); + fpi_imgdev_session_error(dev, r); + fpi_ssm_mark_aborted(ssm, r); } break; @@ -773,8 +780,11 @@ static void activate_loop_complete(struct fpi_ssm *ssm) if (data->init_sequence.receive_buf != NULL) g_free(data->init_sequence.receive_buf); data->init_sequence.receive_buf = NULL; - submit_image(ssm, data); - fpi_imgdev_report_finger_status(dev, FALSE); + /* We don't want to submit image if we're in deactivating process */ + if (!data->deactivating) { + submit_image(ssm, data); + fpi_imgdev_report_finger_status(dev, FALSE); + } fpi_ssm_free(ssm); data->loop_running = FALSE; @@ -891,10 +901,16 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { + int r; struct vfs5011_data *data = dev->priv; - if (data->loop_running) + if (data->loop_running) { data->deactivating = TRUE; - else + if (data->flying_transfer) { + r = libusb_cancel_transfer(data->flying_transfer); + if (r < 0) + fp_dbg("cancel failed error %d", r); + } + } else fpi_imgdev_deactivate_complete(dev); } From fc1781e317f66eb5f9dd10afb765d721f8116f2f Mon Sep 17 00:00:00 2001 From: Volkau Siarhei Date: Sat, 1 Nov 2014 15:46:52 +0300 Subject: [PATCH 025/141] vfs101: fix broken enrolling by prev commit to vfs101.c --- libfprint/drivers/vfs101.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 84624eb2..062bc426 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -653,7 +653,7 @@ static int action_completed(struct fp_img_dev *dev) struct vfs101_dev *vdev = dev->priv; if ((dev->action == IMG_ACTION_ENROLL) && - (vdev->enroll_stage < 1)) + (vdev->enroll_stage < dev->dev->nr_enroll_stages)) /* Enroll not completed, return false */ return FALSE; From 61fa57b05dccda8ed855f66e650564e5da9acb1a Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 14 Oct 2015 10:45:15 -0700 Subject: [PATCH 026/141] aes1610: decrease bz3_threshold to 20 --- libfprint/drivers/aes1610.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index fc234d2d..56617530 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -844,7 +844,7 @@ struct fp_img_driver aes1610_driver = { .img_height = -1, .img_width = IMAGE_WIDTH, - .bz3_threshold = 50, + .bz3_threshold = 20, .open = dev_init, .close = dev_deinit, From d71018bd8f478baea65cc48c59074abb66813b90 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 24 Nov 2015 15:22:46 -0800 Subject: [PATCH 027/141] vfs5011: add USB IDs of device found in some Toshiba laptops --- libfprint/drivers/vfs5011.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index a2267b23..efa3df23 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -915,6 +915,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 = 0x0017 /* Validity device from Lenovo T440 laptops */ }, { .vendor = 0x138a, .product = 0x0018 /* one more Validity device */ }, From 487dae0d2fa5a7a1951581f17b55fa1f411e73e6 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 12 Apr 2016 16:10:53 +0200 Subject: [PATCH 028/141] Work-around kernel's lack of USB PM The device is already supported by the vfs5011 driver and non- blacklisted, so will show up in the udev rules, but for ease of backporting to older versions, add it to the whitelist anyway. https://bugzilla.redhat.com/show_bug.cgi?id=1173367 --- libfprint/fprint-list-udev-rules.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c index a17e6e11..b8fbd4c9 100644 --- a/libfprint/fprint-list-udev-rules.c +++ b/libfprint/fprint-list-udev-rules.c @@ -25,6 +25,8 @@ static const struct usb_id whitelist_id_table[] = { { .vendor = 0x08ff, .product = 0x2810 }, + /* https://bugzilla.redhat.com/show_bug.cgi?id=1173367 */ + { .vendor = 0x138a, .product = 0x0017 }, { 0, 0, 0, }, }; From 9570c36fd42bff6246de50ace398a457b9495b46 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 19 Jul 2016 11:18:31 +0200 Subject: [PATCH 029/141] build: Fix running autogen.sh out-of-tree --- autogen.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index e4366b30..4bc9d7d8 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,10 +1,18 @@ #!/bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +pushd $srcdir + libtoolize --copy --force || exit 1 aclocal || exit 1 autoheader || exit 1 autoconf || exit 1 automake -a -c || exit 1 +popd + if test -z "$NOCONFIGURE"; then - exec ./configure --enable-maintainer-mode --enable-examples-build \ + $srcdir/configure --enable-maintainer-mode --enable-examples-build \ --enable-x11-examples-build --enable-debug-log $* fi From 12f6dae8cd81f363e02849acea40c69a8764f487 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 3 Nov 2016 14:05:11 +0100 Subject: [PATCH 030/141] build: Fix 9570c36 on Debian Debian's ash doesn't implement pushd/popd. --- autogen.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/autogen.sh b/autogen.sh index 4bc9d7d8..cd72a669 100755 --- a/autogen.sh +++ b/autogen.sh @@ -3,14 +3,16 @@ srcdir=`dirname $0` test -z "$srcdir" && srcdir=. -pushd $srcdir +olddir="`pwd`" + +cd "$srcdir" libtoolize --copy --force || exit 1 aclocal || exit 1 autoheader || exit 1 autoconf || exit 1 automake -a -c || exit 1 -popd +cd "$olddir" if test -z "$NOCONFIGURE"; then $srcdir/configure --enable-maintainer-mode --enable-examples-build \ From a0bbbd7d32150ab6ed25f466cce05169fbbbaead Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sat, 5 Nov 2016 00:10:17 +0100 Subject: [PATCH 031/141] drivers: Print USB error when libusb_claim_interface() fails https://bugs.freedesktop.org/show_bug.cgi?id=98594 --- libfprint/drivers/aes1610.c | 2 +- libfprint/drivers/aes1660.c | 2 +- libfprint/drivers/aes2501.c | 2 +- libfprint/drivers/aes2550.c | 2 +- libfprint/drivers/aes2660.c | 2 +- libfprint/drivers/aes3500.c | 2 +- libfprint/drivers/aes4000.c | 2 +- libfprint/drivers/etes603.c | 3 +-- libfprint/drivers/fdu2000.c | 6 ++++-- libfprint/drivers/upeke2.c | 4 +++- libfprint/drivers/upeksonly.c | 2 +- libfprint/drivers/upektc.c | 2 +- libfprint/drivers/upektc_img.c | 2 +- libfprint/drivers/upekts.c | 4 +++- libfprint/drivers/uru4000.c | 2 +- libfprint/drivers/vcom5s.c | 2 +- libfprint/drivers/vfs101.c | 2 +- libfprint/drivers/vfs301.c | 2 +- libfprint/drivers/vfs5011.c | 2 +- 19 files changed, 26 insertions(+), 21 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 56617530..50bc4834 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -811,7 +811,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index 8e63fe38..32bea4eb 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -53,7 +53,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 6c852a51..f6e3edf4 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -850,7 +850,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 965bdb07..387967ee 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -622,7 +622,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index 7cae59c9..efe9670a 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -53,7 +53,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c index 6f4d6b07..05c204a3 100644 --- a/libfprint/drivers/aes3500.c +++ b/libfprint/drivers/aes3500.c @@ -131,7 +131,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev)); diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index b8496514..f1a9d061 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -128,7 +128,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev)); diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index aae0f0f4..44cacbcb 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -1465,8 +1465,7 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) ret = libusb_claim_interface(idev->udev, 0); if (ret != LIBUSB_SUCCESS) { - fp_err("libusb_claim_interface failed on interface 0 " - "(err=%d)", ret); + fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(r)); return ret; } diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c index ebd71031..e14b860e 100644 --- a/libfprint/drivers/fdu2000.c +++ b/libfprint/drivers/fdu2000.c @@ -264,8 +264,10 @@ gint dev_init(struct fp_img_dev *dev, unsigned long driver_data) //if ( (r = usb_set_configuration(dev->udev, 1)) < 0 ) // goto out; - if ( (r = libusb_claim_interface(dev->udev, 0)) < 0 ) - goto out; + if ( (r = libusb_claim_interface(dev->udev, 0)) < 0 ) { + fp_err("could not claim interface 0: %s", libusb_error_name(r)); + return r; + } //if ( (r = usb_set_altinterface(dev->udev, 1)) < 0 ) // goto out; diff --git a/libfprint/drivers/upeke2.c b/libfprint/drivers/upeke2.c index f6852058..3f05e809 100644 --- a/libfprint/drivers/upeke2.c +++ b/libfprint/drivers/upeke2.c @@ -864,8 +864,10 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data) int r; r = libusb_claim_interface(dev->udev, 0); - if (r < 0) + if (r < 0) { + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; + } upekdev = g_malloc(sizeof(*upekdev)); upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */ diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 22ada5e2..5048a5c7 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -1359,7 +1359,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 271cffb7..f3d9b8ab 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -441,7 +441,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 31eddff0..18e271b6 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -651,7 +651,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index c191a2dd..b2971276 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -875,8 +875,10 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data) int r; r = libusb_claim_interface(dev->udev, 0); - if (r < 0) + if (r < 0) { + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; + } upekdev = g_malloc(sizeof(*upekdev)); upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */ diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index ccaa87f8..462b86ac 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -1285,7 +1285,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, iface_desc->bInterfaceNumber); if (r < 0) { - fp_err("interface claim failed"); + fp_err("interface claim failed: %s", libusb_error_name(r)); goto out; } diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 4b442b23..1f127a8c 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -348,7 +348,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); if (r == 0) fpi_imgdev_open_complete(dev, 0); diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 062bc426..3ee13e3b 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -1504,7 +1504,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) if (r < 0) { /* Interface not claimed, return error */ - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 04db05ec..833c05b0 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -240,7 +240,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r < 0) { /* Interface not claimed, return error */ - fp_err("could not claim interface 0"); + fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index efa3df23..fa1dcabc 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -849,7 +849,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) r = libusb_claim_interface(dev->udev, 0); if (r != 0) { - fp_err("Failed to claim interface"); + fp_err("Failed to claim interface: %s", libusb_error_name(r)); return r; } From 8454a25ecfc27c5d96867a9fda012d0a73ffeddb Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sat, 5 Nov 2016 00:11:30 +0100 Subject: [PATCH 032/141] aes3500: Fix possible crash if USB init fails The code was indented, but only the first call was actually in the conditional, which meant that initialisation carried on as normal on top of a failed USB device. Exit early and remove the conditional to fix this. --- libfprint/drivers/aes3500.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c index 05c204a3..f229a1ac 100644 --- a/libfprint/drivers/aes3500.c +++ b/libfprint/drivers/aes3500.c @@ -130,23 +130,24 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) struct aes3k_dev *aesdev; r = libusb_claim_interface(dev->udev, 0); - if (r < 0) + if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); + return r; + } aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev)); if (!aesdev) return -ENOMEM; - if (r == 0) - aesdev->data_buflen = DATA_BUFLEN; - aesdev->frame_width = FRAME_WIDTH; - aesdev->frame_size = FRAME_SIZE; - aesdev->frame_number = FRAME_NUMBER; - aesdev->enlarge_factor = ENLARGE_FACTOR; - aesdev->init_reqs = init_reqs; - aesdev->init_reqs_len = G_N_ELEMENTS(init_reqs); - fpi_imgdev_open_complete(dev, 0); + aesdev->data_buflen = DATA_BUFLEN; + aesdev->frame_width = FRAME_WIDTH; + aesdev->frame_size = FRAME_SIZE; + aesdev->frame_number = FRAME_NUMBER; + aesdev->enlarge_factor = ENLARGE_FACTOR; + aesdev->init_reqs = init_reqs; + aesdev->init_reqs_len = G_N_ELEMENTS(init_reqs); + fpi_imgdev_open_complete(dev, 0); return r; } From 76269decdd405a0ae919a24c1ba3061c44bf80b2 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sat, 5 Nov 2016 00:12:46 +0100 Subject: [PATCH 033/141] aes4000: Fix possible crash if USB init fails The code was indented, but only the first call was actually in the conditional, which meant that initialisation carried on as normal on top of a failed USB device. Exit early and remove the conditional to fix this. https://bugzilla.gnome.org/show_bug.cgi?id=98594 --- libfprint/drivers/aes4000.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index f1a9d061..d4f90b79 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -127,23 +127,24 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) struct aes3k_dev *aesdev; r = libusb_claim_interface(dev->udev, 0); - if (r < 0) + if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); + return r; + } aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev)); if (!aesdev) return -ENOMEM; - if (r == 0) - aesdev->data_buflen = DATA_BUFLEN; - aesdev->frame_width = FRAME_WIDTH; - aesdev->frame_size = FRAME_SIZE; - aesdev->frame_number = FRAME_NUMBER; - aesdev->enlarge_factor = ENLARGE_FACTOR; - aesdev->init_reqs = init_reqs; - aesdev->init_reqs_len = G_N_ELEMENTS(init_reqs); - fpi_imgdev_open_complete(dev, 0); + aesdev->data_buflen = DATA_BUFLEN; + aesdev->frame_width = FRAME_WIDTH; + aesdev->frame_size = FRAME_SIZE; + aesdev->frame_number = FRAME_NUMBER; + aesdev->enlarge_factor = ENLARGE_FACTOR; + aesdev->init_reqs = init_reqs; + aesdev->init_reqs_len = G_N_ELEMENTS(init_reqs); + fpi_imgdev_open_complete(dev, 0); return r; } From 49a46668ad2f45d26d3b6d6168ada620c54290ab Mon Sep 17 00:00:00 2001 From: Konstantin Semenov Date: Tue, 19 Jan 2016 14:26:29 +0300 Subject: [PATCH 034/141] lib: Add VFS0050 driver New driver for 138a:0050 device https://bugs.freedesktop.org/show_bug.cgi?id=91616 --- configure.ac | 13 +- libfprint/Makefile.am | 6 + libfprint/core.c | 3 + libfprint/drivers/driver_ids.h | 1 + libfprint/drivers/vfs0050.c | 791 +++++++++++++++++++++++++++++++++ libfprint/drivers/vfs0050.h | 382 ++++++++++++++++ libfprint/fp_internal.h | 3 + 7 files changed, 1198 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/vfs0050.c create mode 100644 libfprint/drivers/vfs0050.h diff --git a/configure.ac b/configure.ac index 707f5875..58ea9e93 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) 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" +all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes3500 aes4000 vfs101 vfs301 vfs5011 upektc_img etes603 vfs0050" require_imaging='no' require_aeslib='no' @@ -48,6 +48,7 @@ enable_vfs301='no' enable_vfs5011='no' enable_upektc_img='no' enable_etes603='no' +enable_vfs0050='no' AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [List of drivers to enable])], @@ -150,6 +151,10 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do AC_DEFINE([ENABLE_ETES603], [], [Build EgisTec ES603 driver]) enable_etes603="yes" ;; + vfs0050) + AC_DEFINE([ENABLE_VFS0050], [], [Build Validity VFS0050 driver]) + enable_vfs0050="yes" + ;; esac done @@ -175,6 +180,7 @@ AM_CONDITIONAL([ENABLE_VFS301], [test "$enable_vfs301" = "yes"]) AM_CONDITIONAL([ENABLE_VFS5011], [test "$enable_vfs5011" = "yes"]) 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"]) PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) @@ -396,6 +402,11 @@ if test x$enable_etes603 != xno ; then else AC_MSG_NOTICE([ etes603 driver disabled]) fi +if test x$enable_vfs0050 != xno ; then + AC_MSG_NOTICE([** vfs0050 driver enabled]) +else + AC_MSG_NOTICE([ vfs0050 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 ea6e6784..a7fb162d 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -21,6 +21,7 @@ VFS301_SRC = drivers/vfs301.c drivers/vfs301_proto.c drivers/vfs301_proto.h dri VFS5011_SRC = drivers/vfs5011.c drivers/vfs5011_proto.h UPEKTC_IMG_SRC = drivers/upektc_img.c drivers/upektc_img.h ETES603_SRC = drivers/etes603.c +VFS0050_SRC = drivers/vfs0050.c drivers/vfs0050.h EXTRA_DIST = \ $(UPEKE2_SRC) \ @@ -42,6 +43,7 @@ EXTRA_DIST = \ $(VFS5011_SRC) \ $(UPEKTC_IMG_SRC) \ $(ETES603_SRC) \ + $(VFS0050_SRC) \ drivers/aesx660.c \ drivers/aesx660.h \ drivers/aes3k.c \ @@ -184,6 +186,10 @@ if ENABLE_ETES603 DRIVER_SRC += $(ETES603_SRC) endif +if ENABLE_VFS0050 +DRIVER_SRC += $(VFS0050_SRC) +endif + if REQUIRE_PIXMAN OTHER_SRC += pixman.c libfprint_la_CFLAGS += $(IMAGING_CFLAGS) diff --git a/libfprint/core.c b/libfprint/core.c index 2ae76497..8b6fe438 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -398,6 +398,9 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_ETES603 &etes603_driver, #endif +#ifdef ENABLE_VFS0050 + &vfs0050_driver, +#endif /*#ifdef ENABLE_FDU2000 &fdu2000_driver, #endif diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h index 4d8414c7..8143d01e 100644 --- a/libfprint/drivers/driver_ids.h +++ b/libfprint/drivers/driver_ids.h @@ -40,6 +40,7 @@ enum { UPEKTC_IMG_ID = 17, ETES603_ID = 18, VFS5011_ID = 19, + VFS0050_ID = 20, }; #endif diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c new file mode 100644 index 00000000..31d793cd --- /dev/null +++ b/libfprint/drivers/vfs0050.c @@ -0,0 +1,791 @@ +/* + * Validity VFS0050 driver for libfprint + * Copyright (C) 2015-2016 Konstantin Semenov + * + * 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 "vfs0050" + +#include +#include +#include +#include +#include "driver_ids.h" + +#include "vfs0050.h" + +/* USB functions */ + +/* Callback for async_write */ +static void async_write_callback(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *idev = ssm->priv; + + int transferred = transfer->actual_length, error = + transfer->status, len = transfer->length; + + if (error != 0) { + fp_err("USB write transfer: %s", libusb_error_name(error)); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + if (transferred != len) { + fp_err("Written only %d of %d bytes", transferred, len); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + fpi_ssm_next_state(ssm); +} + +/* Send data to EP1, the only out endpoint */ +static void async_write(struct fpi_ssm *ssm, void *data, int len) +{ + struct fp_img_dev *idev = ssm->priv; + struct libusb_device_handle *udev = idev->udev; + struct vfs_dev_t *vdev = idev->priv; + + vdev->transfer = libusb_alloc_transfer(0); + vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; + libusb_fill_bulk_transfer(vdev->transfer, udev, 0x01, data, len, + async_write_callback, ssm, VFS_USB_TIMEOUT); + libusb_submit_transfer(vdev->transfer); +} + +/* Callback for async_read */ +static void async_read_callback(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *idev = ssm->priv; + + int transferred = transfer->actual_length, error = + transfer->status, len = transfer->length; + int ep = transfer->endpoint; + + if (error != 0) { + fp_err("USB read transfer on endpoint %d: %s", ep - 0x80, + libusb_error_name(error)); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + if (transferred != len) { + fp_err("Received %d instead of %d bytes", transferred, len); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + fpi_ssm_next_state(ssm); +} + +/* Receive data from the given ep and compare with expected */ +static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len) +{ + struct fp_img_dev *idev = ssm->priv; + struct libusb_device_handle *udev = idev->udev; + struct vfs_dev_t *vdev = idev->priv; + + ep |= LIBUSB_ENDPOINT_IN; + + vdev->transfer = libusb_alloc_transfer(0); + vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; + + /* 0x83 is the only interrupt endpoint */ + if (ep == EP3_IN) + libusb_fill_interrupt_transfer(vdev->transfer, udev, ep, data, + len, async_read_callback, ssm, + VFS_USB_TIMEOUT); + else + libusb_fill_bulk_transfer(vdev->transfer, udev, ep, data, len, + async_read_callback, ssm, + VFS_USB_TIMEOUT); + libusb_submit_transfer(vdev->transfer); +} + +/* Callback for async_read */ +static void async_abort_callback(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *idev = ssm->priv; + + int transferred = transfer->actual_length, error = transfer->status; + int ep = transfer->endpoint; + + /* In normal case endpoint is empty */ + if (error == LIBUSB_TRANSFER_TIMED_OUT) { + fpi_ssm_next_state(ssm); + return; + } + + if (error != 0) { + fp_err("USB write transfer: %s", libusb_error_name(error)); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + /* Don't stop process, only print warning */ + if (transferred > 0) + fp_warn("Endpoint %d had extra %d bytes", ep - 0x80, + transferred); + + fpi_ssm_jump_to_state(ssm, ssm->cur_state); +} + +/* Receive data from the given ep and compare with expected */ +static void async_abort(struct fpi_ssm *ssm, int ep) +{ + struct fp_img_dev *idev = ssm->priv; + struct libusb_device_handle *udev = idev->udev; + struct vfs_dev_t *vdev = idev->priv; + + int len = VFS_USB_BUFFER_SIZE; + unsigned char *data = g_malloc(VFS_USB_BUFFER_SIZE); + + ep |= LIBUSB_ENDPOINT_IN; + + vdev->transfer = libusb_alloc_transfer(0); + vdev->transfer->flags |= + LIBUSB_TRANSFER_FREE_TRANSFER | LIBUSB_TRANSFER_FREE_BUFFER; + + /* 0x83 is the only interrupt endpoint */ + if (ep == EP3_IN) + libusb_fill_interrupt_transfer(vdev->transfer, udev, ep, data, + len, async_abort_callback, ssm, + VFS_USB_ABORT_TIMEOUT); + else + libusb_fill_bulk_transfer(vdev->transfer, udev, ep, data, len, + async_abort_callback, ssm, + VFS_USB_ABORT_TIMEOUT); + libusb_submit_transfer(vdev->transfer); +} + +/* Image processing functions */ + +/* Pixel getter for fpi_assemble_lines */ +static unsigned char vfs0050_get_pixel(struct fpi_line_asmbl_ctx *ctx, + GSList * line, unsigned int x) +{ + return ((struct vfs_line *)line->data)->data[x]; +} + +/* Deviation getter for fpi_assemble_lines */ +static int vfs0050_get_difference(struct fpi_line_asmbl_ctx *ctx, + GSList * line_list_1, GSList * line_list_2) +{ + struct vfs_line *line1 = line_list_1->data; + struct vfs_line *line2 = line_list_2->data; + const int shift = (VFS_IMAGE_WIDTH - VFS_NEXT_LINE_WIDTH) / 2 - 1; + int res = 0; + for (int i = 0; i < VFS_NEXT_LINE_WIDTH; ++i) { + int x = + (int)line1->next_line_part[i] - (int)line2->data[shift + i]; + res += x * x; + } + return res; +} + +#define VFS_NOISE_THRESHOLD 40 + +/* Checks whether line is noise or not using hardware parameters */ +static char is_noise(struct vfs_line *line) +{ + int val1 = line->noise_hash_1; + int val2 = line->noise_hash_2; + if (val1 > VFS_NOISE_THRESHOLD + && val1 < 256 - VFS_NOISE_THRESHOLD + && val2 > VFS_NOISE_THRESHOLD && val2 < 256 - VFS_NOISE_THRESHOLD) + return 1; + return 0; +} + +/* Parameters for fpi_assemble_lines */ +static struct fpi_line_asmbl_ctx assembling_ctx = { + .line_width = VFS_IMAGE_WIDTH, + .max_height = VFS_MAX_HEIGHT, + .resolution = 10, + .median_filter_size = 25, + .max_search_offset = 100, + .get_deviation = vfs0050_get_difference, + .get_pixel = vfs0050_get_pixel, +}; + +/* Processes image before submitting */ +static struct fp_img *prepare_image(struct vfs_dev_t *vdev) +{ + int height = vdev->bytes / VFS_LINE_SIZE; + + /* Noise cleaning. IMHO, it works pretty well + I've not detected cases when it doesn't work or cuts a part of the finger + Noise arises at the end of scan when some water remains on the scanner */ + while (height > 0) { + if (!is_noise(vdev->lines_buffer + height - 1)) + break; + --height; + } + if (height > VFS_MAX_HEIGHT) + height = VFS_MAX_HEIGHT; + + /* If image is not good enough */ + if (height < VFS_IMAGE_WIDTH) + return NULL; + + /* Building GSList */ + GSList *lines = NULL; + for (int i = height - 1; i >= 0; --i) + lines = g_slist_prepend(lines, vdev->lines_buffer + i); + + /* Perform line assembling */ + struct fp_img *img = fpi_assemble_lines(&assembling_ctx, lines, height); + + g_slist_free(lines); + return img; +} + +/* Processes and submits image after fingerprint received */ +static void submit_image(struct fp_img_dev *idev) +{ + struct vfs_dev_t *vdev = idev->priv; + + /* We were not asked to submit image actually */ + if (!vdev->active) + return; + + struct fp_img *img = prepare_image(vdev); + + if (!img) + fpi_imgdev_abort_scan(idev, FP_VERIFY_RETRY_TOO_SHORT); + else + fpi_imgdev_image_captured(idev, img); + + /* Finger not on the scanner */ + fpi_imgdev_report_finger_status(idev, 0); +} + +/* Proto functions */ + +/* SSM loop for clear_ep2 */ +static void clear_ep2_ssm(struct fpi_ssm *ssm) +{ + struct fp_img_dev *idev = ssm->priv; + + short result; + char command04 = 0x04; + + switch (ssm->cur_state) { + case SUBSM1_COMMAND_04: + async_write(ssm, &command04, sizeof(command04)); + break; + + case SUBSM1_RETURN_CODE: + async_read(ssm, 1, &result, sizeof(result)); + break; + + case SUBSM1_ABORT_2: + async_abort(ssm, 2); + break; + + default: + fp_err("Unknown SUBSM1 state"); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + } +} + +/* Send command to clear EP2 */ +static void clear_ep2(struct fpi_ssm *ssm) +{ + struct fp_img_dev *idev = ssm->priv; + + struct fpi_ssm *subsm = + fpi_ssm_new(idev->dev, clear_ep2_ssm, SUBSM1_STATES); + subsm->priv = idev; + fpi_ssm_start_subsm(ssm, subsm); +} + +static void send_control_packet_ssm(struct fpi_ssm *ssm) +{ + struct fp_img_dev *idev = ssm->priv; + struct vfs_dev_t *vdev = idev->priv; + + short result; + unsigned char *commit_result = NULL; + + switch (ssm->cur_state) { + case SUBSM2_SEND_CONTROL: + async_write(ssm, vdev->control_packet, VFS_CONTROL_PACKET_SIZE); + break; + + case SUBSM2_RETURN_CODE: + async_read(ssm, 1, &result, sizeof(result)); + break; + + case SUBSM2_SEND_COMMIT: + /* next_receive_* packets could be sent only in pair */ + if (vdev->control_packet == next_receive_1) { + vdev->control_packet = next_receive_2; + fpi_ssm_jump_to_state(ssm, SUBSM2_SEND_CONTROL); + break; + } + /* commit_out in Windows differs in each commit, but I send the same each time */ + async_write(ssm, commit_out, sizeof(commit_out)); + break; + + case SUBSM2_COMMIT_RESPONSE: + commit_result = g_malloc(VFS_COMMIT_RESPONSE_SIZE); + async_read(ssm, 1, commit_result, VFS_COMMIT_RESPONSE_SIZE); + break; + + case SUBSM2_READ_EMPTY_INTERRUPT: + /* I don't know how to check result, it could be different */ + g_free(commit_result); + + async_read(ssm, 3, vdev->interrupt, VFS_INTERRUPT_SIZE); + break; + + case SUBSM2_ABORT_3: + /* Check that interrupt is empty */ + if (memcmp + (vdev->interrupt, empty_interrupt, VFS_INTERRUPT_SIZE)) { + fp_err("Unknown SUBSM2 state"); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + break; + } + async_abort(ssm, 3); + break; + + case SUBSM2_CLEAR_EP2: + /* After turn_on Windows doesn't clear EP2 */ + if (vdev->control_packet != turn_on) + clear_ep2(ssm); + else + fpi_ssm_next_state(ssm); + break; + + default: + fp_err("Unknown SUBSM2 state"); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + } +} + +/* Send device state control packet */ +static void send_control_packet(struct fpi_ssm *ssm) +{ + struct fp_img_dev *idev = ssm->priv; + + struct fpi_ssm *subsm = + fpi_ssm_new(idev->dev, send_control_packet_ssm, SUBSM2_STATES); + subsm->priv = idev; + fpi_ssm_start_subsm(ssm, subsm); +} + +/* Clears all fprint data */ +static void clear_data(struct vfs_dev_t *vdev) +{ + g_free(vdev->lines_buffer); + vdev->lines_buffer = NULL; + vdev->memory = vdev->bytes = 0; +} + +/* After receiving interrupt from EP3 */ +static void interrupt_callback(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *idev = ssm->priv; + struct vfs_dev_t *vdev = idev->priv; + + char *interrupt = vdev->interrupt; + int error = transfer->status, transferred = transfer->actual_length; + + vdev->wait_interrupt = 0; + + /* When we have cancelled transfer, error is ok actually */ + if (!vdev->active && error == LIBUSB_TRANSFER_CANCELLED) + return; + + if (error != 0) { + fp_err("USB read interrupt transfer: %s", + libusb_error_name(error)); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + /* Interrupt size is VFS_INTERRUPT_SIZE bytes in all known cases */ + if (transferred != VFS_INTERRUPT_SIZE) { + fp_err("Unknown interrupt size %d", transferred); + /* Abort ssm */ + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + /* Standard interrupts */ + if (memcmp(interrupt, interrupt1, VFS_INTERRUPT_SIZE) == 0 || + memcmp(interrupt, interrupt2, VFS_INTERRUPT_SIZE) == 0 || + memcmp(interrupt, interrupt3, VFS_INTERRUPT_SIZE) == 0) { + /* Go to the next ssm stage */ + fpi_ssm_next_state(ssm); + return; + } + + /* When finger is on the scanner before turn_on */ + if (interrupt[0] == 0x01) { + fp_warn("Finger is already on the scanner"); + + /* Go to the next ssm stage */ + fpi_ssm_next_state(ssm); + return; + } + + /* Unknown interrupt; abort the session */ + fp_err("Unknown interrupt '%02x:%02x:%02x:%02x:%02x'!", + interrupt[0] & 0xff, interrupt[1] & 0xff, interrupt[2] & 0xff, + interrupt[3] & 0xff, interrupt[4] & 0xff); + + /* Abort ssm */ + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); +} + +static void receive_callback(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *idev = ssm->priv; + struct vfs_dev_t *vdev = idev->priv; + + int transferred = transfer->actual_length, error = transfer->status; + + if (error != 0 && error != LIBUSB_TRANSFER_TIMED_OUT) { + fp_err("USB read transfer: %s", libusb_error_name(error)); + + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + return; + } + + /* Check if fingerprint data is over */ + if (transferred == 0) { + fpi_ssm_next_state(ssm); + } else { + vdev->bytes += transferred; + + /* We need more data */ + fpi_ssm_jump_to_state(ssm, ssm->cur_state); + } +} + +/* Stub to keep SSM alive when waiting an interrupt */ +static void wait_interrupt(void *data) +{ + struct fpi_ssm *ssm = data; + struct fp_img_dev *idev = ssm->priv; + struct vfs_dev_t *vdev = idev->priv; + + /* Keep sleeping while this flag is on */ + if (vdev->wait_interrupt) + fpi_ssm_jump_to_state(ssm, ssm->cur_state); +} + +/* SSM stub to prepare device to another scan after orange light was on */ +static void another_scan(void *data) +{ + struct fpi_ssm *ssm = data; + fpi_ssm_jump_to_state(ssm, SSM_TURN_ON); +} + +/* Another SSM stub to continue after waiting for probable vdev->active changes */ +static void scan_completed(void *data) +{ + struct fpi_ssm *ssm = data; + fpi_ssm_next_state(ssm); +} + +/* Main SSM loop */ +static void activate_ssm(struct fpi_ssm *ssm) +{ + struct fp_img_dev *idev = ssm->priv; + struct libusb_device_handle *udev = idev->udev; + struct vfs_dev_t *vdev = idev->priv; + + switch (ssm->cur_state) { + case SSM_INITIAL_ABORT_1: + async_abort(ssm, 1); + break; + + case SSM_INITIAL_ABORT_2: + async_abort(ssm, 2); + break; + + case SSM_INITIAL_ABORT_3: + async_abort(ssm, 3); + break; + + case SSM_CLEAR_EP2: + clear_ep2(ssm); + break; + + case SSM_TURN_OFF: + /* Set control_packet argument */ + vdev->control_packet = turn_off; + + send_control_packet(ssm); + break; + + case SSM_TURN_ON: + if (!vdev->active) { + /* The only correct exit */ + fpi_ssm_mark_completed(ssm); + + if (vdev->need_report) { + fpi_imgdev_deactivate_complete(idev); + vdev->need_report = 0; + } + break; + } + /* Set control_packet argument */ + vdev->control_packet = turn_on; + + send_control_packet(ssm); + break; + + case SSM_ASK_INTERRUPT: + /* Activated, light must be blinking now */ + + /* If we first time here, report that activate completed */ + if (vdev->need_report) { + fpi_imgdev_activate_complete(idev, 0); + vdev->need_report = 0; + } + + /* Asyncronously enquire an interrupt */ + vdev->transfer = libusb_alloc_transfer(0); + vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; + libusb_fill_interrupt_transfer(vdev->transfer, udev, 0x83, + vdev->interrupt, + VFS_INTERRUPT_SIZE, + interrupt_callback, ssm, 0); + libusb_submit_transfer(vdev->transfer); + + /* This flag could be turned off only in callback function */ + vdev->wait_interrupt = 1; + + /* I've put it here to be sure that data is cleared */ + clear_data(vdev); + + fpi_ssm_next_state(ssm); + break; + + case SSM_WAIT_INTERRUPT: + /* Check if user had interrupted the process */ + if (!vdev->active) { + libusb_cancel_transfer(vdev->transfer); + fpi_ssm_jump_to_state(ssm, SSM_CLEAR_EP2); + break; + } + + if (vdev->wait_interrupt) + fpi_timeout_add(VFS_SSM_TIMEOUT, wait_interrupt, ssm); + break; + + case SSM_RECEIVE_FINGER: + if (vdev->memory == 0) { + /* Initialize fingerprint buffer */ + g_free(vdev->lines_buffer); + vdev->memory = VFS_USB_BUFFER_SIZE; + vdev->lines_buffer = g_malloc(vdev->memory); + vdev->bytes = 0; + + /* Finger is on the scanner */ + fpi_imgdev_report_finger_status(idev, 1); + } + + /* Increase buffer size while it's insufficient */ + while (vdev->bytes + VFS_USB_BUFFER_SIZE > vdev->memory) { + vdev->memory <<= 1; + vdev->lines_buffer = + (struct vfs_line *)g_realloc(vdev->lines_buffer, + vdev->memory); + } + + /* Receive chunk of data */ + vdev->transfer = libusb_alloc_transfer(0); + vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; + libusb_fill_bulk_transfer(vdev->transfer, udev, 0x82, + (void *)vdev->lines_buffer + + vdev->bytes, VFS_USB_BUFFER_SIZE, + receive_callback, ssm, + VFS_USB_TIMEOUT); + libusb_submit_transfer(vdev->transfer); + break; + + case SSM_SUBMIT_IMAGE: + submit_image(idev); + clear_data(vdev); + + /* Wait for probable vdev->active changing */ + fpi_timeout_add(VFS_SSM_TIMEOUT, scan_completed, ssm); + break; + + case SSM_NEXT_RECEIVE: + if (!vdev->active) { + /* It's the last scan */ + fpi_ssm_jump_to_state(ssm, SSM_CLEAR_EP2); + break; + } + + /* Set control_packet argument */ + vdev->control_packet = next_receive_1; + + send_control_packet(ssm); + break; + + case SSM_WAIT_ANOTHER_SCAN: + /* Orange light is on now */ + fpi_timeout_add(VFS_SSM_ORANGE_TIMEOUT, another_scan, ssm); + break; + + default: + fp_err("Unknown state"); + fpi_imgdev_session_error(idev, -EIO); + fpi_ssm_mark_aborted(ssm, -EIO); + } +} + +/* Driver functions */ + +/* Callback for dev_activate ssm */ +static void dev_activate_callback(struct fpi_ssm *ssm) +{ + struct fp_img_dev *idev = ssm->priv; + struct vfs_dev_t *vdev = idev->priv; + + vdev->ssm_active = 0; + + fpi_ssm_free(ssm); +} + +/* Activate device */ +static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) +{ + struct vfs_dev_t *vdev = idev->priv; + + /* Initialize flags */ + vdev->active = 1; + vdev->need_report = 1; + vdev->ssm_active = 1; + + struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, activate_ssm, SSM_STATES); + ssm->priv = idev; + fpi_ssm_start(ssm, dev_activate_callback); + return 0; +} + +/* Deactivate device */ +static void dev_deactivate(struct fp_img_dev *idev) +{ + struct vfs_dev_t *vdev = idev->priv; + + if (!vdev->ssm_active) { + fpi_imgdev_deactivate_complete(idev); + return; + } + + /* Initialize flags */ + vdev->active = 0; + vdev->need_report = 1; +} + +/* Callback for dev_open ssm */ +static void dev_open_callback(struct fpi_ssm *ssm) +{ + /* Notify open complete */ + fpi_imgdev_open_complete((struct fp_img_dev *)ssm->priv, 0); + fpi_ssm_free(ssm); +} + +/* Open device */ +static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) +{ + /* Claim usb interface */ + int error = libusb_claim_interface(idev->udev, 0); + if (error < 0) { + /* Interface not claimed, return error */ + fp_err("could not claim interface 0"); + return error; + } + + /* Initialize private structure */ + struct vfs_dev_t *vdev = g_malloc0(sizeof(struct vfs_dev_t)); + idev->priv = vdev; + + /* Clearing previous device state */ + struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, activate_ssm, SSM_STATES); + ssm->priv = idev; + fpi_ssm_start(ssm, dev_open_callback); + return 0; +} + +/* Close device */ +static void dev_close(struct fp_img_dev *idev) +{ + /* Release private structure */ + g_free(idev->priv); + + /* Release usb interface */ + libusb_release_interface(idev->udev, 0); + + /* Notify close complete */ + fpi_imgdev_close_complete(idev); +} + +/* Usb id table of device */ +static const struct usb_id id_table[] = { + {.vendor = 0x138a,.product = 0x0050}, + {0, 0, 0,}, +}; + +/* Device driver definition */ +struct fp_img_driver vfs0050_driver = { + /* Driver specification */ + .driver = { + .id = VFS0050_ID, + .name = FP_COMPONENT, + .full_name = "Validity VFS0050", + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + + /* Image specification */ + .flags = 0, + .img_width = VFS_IMAGE_WIDTH, + .img_height = -1, + .bz3_threshold = 24, + + /* Routine specification */ + .open = dev_open, + .close = dev_close, + .activate = dev_activate, + .deactivate = dev_deactivate, +}; diff --git a/libfprint/drivers/vfs0050.h b/libfprint/drivers/vfs0050.h new file mode 100644 index 00000000..81407ddb --- /dev/null +++ b/libfprint/drivers/vfs0050.h @@ -0,0 +1,382 @@ +/* + * Validity VFS0050 driver for libfprint + * Copyright (C) 2015-2016 Konstantin Semenov + * + * 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 + */ + +/* Timeout for all send/recv operations, except interrupt waiting and abort */ +#define VFS_USB_TIMEOUT 100 +/* Timeout for usb abort */ +#define VFS_USB_ABORT_TIMEOUT 20 +/* Default timeout for SSM timers */ +#define VFS_SSM_TIMEOUT 100 +/* Timeout for orange light */ +#define VFS_SSM_ORANGE_TIMEOUT 400 +/* Buffer size for abort and fprint receiving */ +#define VFS_USB_BUFFER_SIZE 65536 + +/* Line size from scanner including metainformation: line number, narrow stripe from the center, etc */ +#define VFS_LINE_SIZE 148 +/* Width of narrow stripe from the center */ +#define VFS_NEXT_LINE_WIDTH 32 +/* Image width from scanner */ +#define VFS_IMAGE_WIDTH 100 +/* Maximum image height after assembling */ +#define VFS_MAX_HEIGHT 3000 + +/* Size of control packets: turn_on, turn_off, next_receive_* */ +#define VFS_CONTROL_PACKET_SIZE 125 +/* Size of result of commit */ +#define VFS_COMMIT_RESPONSE_SIZE 1106 +/* Size of interrupt from EP3 */ +#define VFS_INTERRUPT_SIZE 5 +/* EP3 endpoint */ +#define EP3_IN 0x83 + +/* Fingerprint horizontal line */ +struct vfs_line { + /* It must be always 0x01 */ + unsigned char _0x01; + /* It must be always 0xfe */ + unsigned char _0xfe; + + /* line number starting from some number in Little-Endian */ + unsigned short id; + + /* Some hashes which are useful to detect noise */ + unsigned char noise_hash_1; + unsigned char noise_hash_2; + + /* The first byte of _somedata is always 0x00, the second is strange useless cyclic line number */ + unsigned short _somedata; + + /* Fingerprint image */ + unsigned char data[VFS_IMAGE_WIDTH]; + + /* Narrow fingerprint part from the center used for variable speed lines assembling */ + unsigned char next_line_part[VFS_NEXT_LINE_WIDTH]; + + /* scan_data is 0xfb except some rare cases, it's skipped */ + unsigned char scan_data[8]; +} __attribute__ ((__packed__)); + +/* The main driver structure */ +struct vfs_dev_t { + /* One if we were asked to read fingerprint, zero otherwise */ + char active; + + /* Control packet parameter for send_control_packet */ + unsigned char *control_packet; + + /* For dev_deactivate to check whether ssm still running or not */ + char ssm_active; + + /* Current async transfer */ + struct libusb_transfer *transfer; + + /* Should we call fpi_imgdev_activate_complete or fpi_imgdev_deactivate_complete */ + char need_report; + + /* Should we wait more for interrupt */ + char wait_interrupt; + + /* Received fingerprint raw lines */ + struct vfs_line *lines_buffer; + + /* Current number of received bytes and current memory used by data */ + int bytes, memory; + + /* USB buffer for fingerprint */ + char *usb_buffer; + + /* Received interrupt data */ + unsigned char interrupt[8]; +}; + +/* SSM states for clear_ep2 */ +enum SUBSM1 { + SUBSM1_COMMAND_04, + SUBSM1_RETURN_CODE, + SUBSM1_ABORT_2, + + SUBSM1_STATES, +}; + +/* SSM states for control */ +enum SUBSM2 { + SUBSM2_SEND_CONTROL, + SUBSM2_RETURN_CODE, /* If next_receive, send another control packet */ + + SUBSM2_SEND_COMMIT, + SUBSM2_COMMIT_RESPONSE, + SUBSM2_READ_EMPTY_INTERRUPT, + SUBSM2_ABORT_3, + SUBSM2_CLEAR_EP2, + + SUBSM2_STATES, +}; + +/* SSM states for activate_ssm */ +enum SSM_STATE { + SSM_INITIAL_ABORT_1, + SSM_INITIAL_ABORT_2, + SSM_INITIAL_ABORT_3, + SSM_CLEAR_EP2, + SSM_TURN_OFF, + + /* Here the device is turned off; if not active, complete ssm */ + SSM_TURN_ON, + + SSM_ASK_INTERRUPT, + SSM_WAIT_INTERRUPT, + + SSM_RECEIVE_FINGER, + SSM_SUBMIT_IMAGE, + + /* If not active, jump to CLEAR_EP2 */ + SSM_NEXT_RECEIVE, + SSM_WAIT_ANOTHER_SCAN, + /* Jump to TURN_ON */ + + SSM_STATES +}; + +/* Blocks of data from USB sniffer */ + +/* Turns on the light */ +static unsigned char turn_on[] = { + 0x39, 0x20, 0xBF, 0x02, 0x00, 0xF4, 0x01, 0x00, 0x00, 0x01, 0xD1, 0x00, + 0x20, 0xD1, 0xD1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF4, 0x01, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF4, 0x01, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, +}; + +/* Power off */ +static unsigned char turn_off[] = { + 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, +}; + +/* Turns on orange light */ +static unsigned char next_receive_1[] = { + 0x39, 0xB8, 0x0B, 0x00, 0x00, 0xB8, 0x0B, 0x00, 0x00, 0x01, 0xD1, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xB8, 0x0B, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, +}; + +/* Packet directly after next_receive_1 */ +static unsigned char next_receive_2[] = { + 0x39, 0xE8, 0x03, 0x00, 0x00, 0xE8, 0x03, 0x00, 0x00, 0x01, 0xD1, 0x00, + 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE8, 0x03, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, +}; + +/* Commit message */ +static unsigned char commit_out[] = { + 0x02, 0x94, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x2C, 0x03, 0x00, + 0x30, 0x1B, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x20, 0x03, 0x00, 0x30, 0x3D, 0x10, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x18, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x24, 0x03, 0x00, + 0x30, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x28, 0x03, 0x00, + 0x30, 0x08, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x30, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x38, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x3C, 0x03, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x44, 0x03, 0x00, + 0x30, 0x14, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x48, 0x03, 0x00, 0x30, 0x01, 0x04, 0x02, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x4C, 0x03, 0x00, 0x30, 0x01, 0x0C, 0x02, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x54, 0x03, 0x00, + 0x30, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x5C, 0x03, 0x00, + 0x30, 0x90, 0x01, 0x02, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x60, 0x03, 0x00, 0x30, 0x2C, 0x01, 0x19, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x64, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x6C, 0x03, 0x00, + 0x30, 0x1E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x70, 0x03, 0x00, + 0x30, 0x21, 0x80, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x78, 0x03, 0x00, 0x30, 0x09, 0x00, 0x02, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x7C, 0x03, 0x00, 0x30, 0x0B, 0x00, 0x19, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x80, 0x03, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x84, 0x03, 0x00, + 0x30, 0x3A, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x88, 0x03, 0x00, 0x30, 0x14, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x8C, 0x03, 0x00, 0x30, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x90, 0x03, 0x00, + 0x30, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x94, 0x03, 0x00, + 0x30, 0x08, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x98, 0x03, 0x00, 0x30, 0x00, 0x00, 0xA1, + 0x01, 0x20, 0x00, 0x08, + 0x00, 0x9C, 0x03, 0x00, 0x30, 0x00, 0x00, 0xA1, 0x01, 0x20, 0x00, 0x08, + 0x00, 0xA8, 0x03, 0x00, + 0x30, 0x64, 0x01, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0xAC, 0x03, 0x00, + 0x30, 0x64, 0x01, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0xB0, 0x03, 0x00, 0x30, 0x00, 0x01, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0xB4, 0x03, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0xB8, 0x03, 0x00, + 0x30, 0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0xBC, 0x03, 0x00, + 0x30, 0x05, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0xC0, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x84, 0x03, 0x00, 0x30, 0x3B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x08, 0x07, 0x00, + 0x30, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x0C, 0x07, 0x00, + 0x30, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x14, 0x07, 0x00, 0x30, 0x20, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x1C, 0x07, 0x00, 0x30, 0x1A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x70, 0x0D, 0x00, + 0x30, 0x01, 0x00, 0x00, 0x00, 0x25, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x90, 0x00, 0x00, 0x00, 0x2B, 0xFF, 0x2B, 0xFF, 0x2B, + 0xED, 0x00, 0x00, 0x2B, + 0xFB, 0x00, 0x00, 0x2B, 0xC5, 0x00, 0x00, 0x2B, 0x05, 0x80, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xD3, 0x2E, 0xC0, 0x2C, 0x3B, 0x08, 0xF0, 0x3B, 0x09, 0x24, + 0xBB, 0x3B, 0x0B, 0x24, + 0xAA, 0x3B, 0x1F, 0xF8, 0x00, 0x3B, 0x3F, 0xF0, 0x00, 0x3B, 0x35, 0xC0, + 0x00, 0x38, 0x80, 0x2C, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0x80, 0x2C, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xC0, + 0x3A, 0x80, 0x2C, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3B, 0x0A, 0x80, + 0x2E, 0x83, 0x24, 0xDB, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x2C, 0x31, 0x83, 0x2C, 0x70, + 0x00, 0x00, 0x00, 0x00, + 0xCB, 0x33, 0x1B, 0x83, 0x2C, 0x70, 0x00, 0x00, 0x00, 0x00, 0xCB, 0x31, + 0x83, 0x2C, 0x70, 0x00, + 0x00, 0x00, 0x00, 0xCB, 0x00, 0x33, 0x1E, 0x83, 0x2E, 0x25, 0xFF, 0xC4, + 0x00, 0x2F, 0x06, 0x84, + 0x2E, 0x00, 0x00, 0x10, 0x20, 0x29, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x23, 0x00, 0x00, + 0x00, 0x21, 0x00, 0x10, 0x00, 0x48, 0x03, 0x00, 0x30, 0xFF, 0xF0, 0xFF, + 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x4C, 0x03, 0x00, + 0x30, 0xFF, 0xF0, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x21, 0x00, 0x10, + 0x00, 0x20, 0x03, 0x00, + 0x30, 0x7F, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, + 0x00, 0x20, 0x00, 0x08, + 0x00, 0x24, 0x03, 0x00, 0x30, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x1C, 0x07, 0x00, + 0x30, 0x1A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, 0x20, 0x03, 0x00, + 0x30, 0xC3, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, + 0x00, 0x80, 0x03, 0x00, + 0x30, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x84, 0x00, 0x31, 0x65, 0x77, + 0x77, 0x77, 0x78, 0x88, + 0x77, 0x77, 0x76, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0x77, 0x67, + 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x67, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x77, 0x66, 0x66, + 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66, 0x66, 0x76, 0x76, 0x66, 0x56, + 0x66, 0x66, 0x56, 0x55, + 0x65, 0x66, 0x66, 0x66, 0x65, 0x66, 0x66, 0x55, 0x66, 0x66, 0x65, 0x66, + 0x76, 0x76, 0x77, 0x77, + 0x66, 0x66, 0x66, 0x76, 0x67, 0x66, 0x77, 0x67, 0x66, 0x66, 0x66, 0x56, + 0x65, 0x66, 0x65, 0x66, + 0x66, 0x55, 0x55, 0x54, 0x55, 0x65, 0x66, 0x66, 0x66, 0x76, 0x77, 0x87, + 0x88, 0x77, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x65, 0x66, 0x55, 0x55, 0x65, 0x56, 0x55, + 0x55, 0x55, 0x54, 0x45, + 0x54, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, + 0x66, 0x26, 0x00, 0x28, + 0x00, 0xFF, 0x00, 0x0F, 0x00, 0xF0, 0xF0, 0x0F, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x30, 0x01, 0x02, + 0x00, 0x2C, 0x01, 0x28, 0x00, 0x20, 0x80, 0x00, 0x00, 0x0A, 0x00, 0x02, + 0x00, 0x0B, 0x00, 0x19, + 0x00, 0x40, 0x1F, 0x10, 0x27, 0x00, 0x0F, 0x03, 0x00, +}; + +/* Known interrupts */ + +static unsigned char empty_interrupt[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char interrupt1[] = { + 0x02, 0x00, 0x0E, 0x00, 0xF0, +}; + +static unsigned char interrupt2[] = { + 0x02, 0x04, 0x0A, 0x00, 0xF0, +}; + +static unsigned char interrupt3[] = { + 0x02, 0x00, 0x0A, 0x00, 0xF0, +}; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 2324b273..5970e316 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -305,6 +305,9 @@ extern struct fp_img_driver upektc_img_driver; #ifdef ENABLE_ETES603 extern struct fp_img_driver etes603_driver; #endif +#ifdef ENABLE_VFS0050 +extern struct fp_img_driver vfs0050_driver; +#endif extern libusb_context *fpi_usb_ctx; extern GSList *opened_devices; From 5e296959697643aab14feac709c8adda8726d582 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 9 Feb 2016 17:19:39 -0800 Subject: [PATCH 035/141] lib: move some functions from vfs5011.c into img.c --- libfprint/drivers/vfs5011.c | 37 ++----------------------------------- libfprint/fp_internal.h | 4 ++++ libfprint/img.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index fa1dcabc..90947d3f 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -252,39 +252,6 @@ static void usb_exchange_async(struct fpi_ssm *ssm, /* ====================== utils ======================= */ -#if VFS5011_LINE_SIZE > INT_MAX/(256*256) -#error We might get integer overflow while computing standard deviation! -#endif - -/* Calculade squared standand deviation */ -static int get_deviation(unsigned char *buf, int size) -{ - int res = 0, mean = 0, i; - for (i = 0; i < size; i++) - mean += buf[i]; - - mean /= size; - - for (i = 0; i < size; i++) { - int dev = (int)buf[i] - mean; - res += dev*dev; - } - - return res / size; -} - -/* Calculate mean square difference of two lines */ -static int get_diff_norm(unsigned char *buf1, unsigned char *buf2, int size) -{ - int res = 0, i; - for (i = 0; i < size; i++) { - int dev = (int)buf1[i] - (int)buf2[i]; - res += dev*dev; - } - - return res / size; -} - /* Calculade squared standand deviation of sum of two lines */ static int vfs5011_get_deviation2(struct fpi_line_asmbl_ctx *ctx, GSList *row1, GSList *row2) { @@ -395,7 +362,7 @@ static int process_chunk(struct vfs5011_data *data, int transferred) unsigned char *linebuf = data->capture_buffer + i * VFS5011_LINE_SIZE; - if (get_deviation(linebuf + 8, VFS5011_IMAGE_WIDTH) + if (fpi_std_sq_dev(linebuf + 8, VFS5011_IMAGE_WIDTH) < DEVIATION_THRESHOLD) { if (data->lines_captured == 0) continue; @@ -417,7 +384,7 @@ static int process_chunk(struct vfs5011_data *data, int transferred) } if ((data->lastline == NULL) - || (get_diff_norm( + || (fpi_mean_sq_diff_norm( data->lastline + 8, linebuf + 8, VFS5011_IMAGE_WIDTH) >= DIFFERENCE_THRESHOLD)) { diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 5970e316..e309ea97 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -489,5 +489,9 @@ void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img); void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result); void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error); +/* utils */ +int fpi_std_sq_dev(const unsigned char *buf, int size); +int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size); + #endif diff --git a/libfprint/img.c b/libfprint/img.c index f9545dbd..408dd564 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -511,3 +511,37 @@ API_EXPORTED struct fp_minutia **fp_img_get_minutiae(struct fp_img *img, return img->minutiae->list; } +/* Calculate squared standand deviation */ +int fpi_std_sq_dev(const unsigned char *buf, int size) +{ + int res = 0, mean = 0, i; + + if (size > (INT_MAX / 65536)) { + fp_err("%s: we might get an overflow!", __func__); + return -EOVERFLOW; + } + + for (i = 0; i < size; i++) + mean += buf[i]; + + mean /= size; + + for (i = 0; i < size; i++) { + int dev = (int)buf[i] - mean; + res += dev*dev; + } + + return res / size; +} + +/* Calculate normalized mean square difference of two lines */ +int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size) +{ + int res = 0, i; + for (i = 0; i < size; i++) { + int dev = (int)buf1[i] - (int)buf2[i]; + res += dev * dev; + } + + return res / size; +} From e4eedef27e0b8b9eb5a8f3ae68086e1013e90b85 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 9 Feb 2016 20:15:38 -0800 Subject: [PATCH 036/141] upeksonly: use fpi_std_sq_dev() and fpi_mean_sq_diff_norm() Use fpi_mean_sq_diff_norm() for blank line detection and fpi_mean_sq_diff_norm() for duplicate line detection. Fixes finger presence and removal detection. --- libfprint/drivers/upeksonly.c | 53 +++++++++++------------------------ 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 5048a5c7..44a9bb6a 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -43,6 +43,11 @@ #define MAX_ROWS 2048 #define MIN_ROWS 64 +#define BLANK_THRESHOLD 250 +#define FINGER_PRESENT_THRESHOLD 32 +#define FINGER_REMOVED_THRESHOLD 100 +#define DIFF_THRESHOLD 13 + enum { UPEKSONLY_2016, UPEKSONLY_1000, @@ -101,8 +106,6 @@ struct sonly_dev { int num_nonblank; enum sonly_fs finger_state; int last_seqnum; - int diff_thresh; - int total_thresh; enum sonly_kill_transfers_action killing_transfers; int kill_status_code; @@ -257,24 +260,6 @@ static void handoff_img(struct fp_img_dev *dev) cancel_img_transfers(dev); } -static void compute_rows(struct sonly_dev *sdev, unsigned char *a, unsigned char *b, int *diff, - int *total) -{ - int i; - int _total = 0; - int _diff = 0; - - for (i = 0; i < sdev->img_width; i++) { - if (a[i] > b[i]) - _diff += a[i] - b[i]; - else - _diff += b[i] - a[i]; - _total += b[i]; - } - *diff = _diff; - *total = _total; -} - static void row_complete(struct fp_img_dev *dev) { struct sonly_dev *sdev = dev->priv; @@ -282,10 +267,10 @@ static void row_complete(struct fp_img_dev *dev) if (sdev->num_rows > 0) { unsigned char *lastrow = sdev->rows->data; - int diff; - int total; + int std_sq_dev, mean_sq_diff; - compute_rows(sdev, lastrow, sdev->rowbuf, &diff, &total); + std_sq_dev = fpi_std_sq_dev(sdev->rowbuf, sdev->img_width); + mean_sq_diff = fpi_mean_sq_diff_norm(lastrow, sdev->rowbuf, sdev->img_width); switch (sdev->finger_state) { case AWAIT_FINGER: @@ -294,14 +279,14 @@ static void row_complete(struct fp_img_dev *dev) sdev->kill_ssm = sdev->loopsm; cancel_img_transfers(dev); } - fp_dbg("total: %d", total); - if (total < sdev->total_thresh) { + fp_dbg("std_sq_dev: %d", std_sq_dev); + if (std_sq_dev > BLANK_THRESHOLD) { sdev->num_nonblank++; } else { sdev->num_nonblank = 0; } - if (sdev->num_nonblank > 32) { + if (sdev->num_nonblank > FINGER_PRESENT_THRESHOLD) { sdev->finger_state = FINGER_DETECTED; fpi_imgdev_report_finger_status(dev, TRUE); } else { @@ -314,7 +299,7 @@ static void row_complete(struct fp_img_dev *dev) break; } - if (total < sdev->total_thresh) { + if (std_sq_dev > BLANK_THRESHOLD) { sdev->num_blank = 0; } else { sdev->num_blank++; @@ -325,16 +310,16 @@ static void row_complete(struct fp_img_dev *dev) * actual scan. Happens most commonly if scan is started * from before the first joint resulting in a gap after the inital touch. */ - if ((sdev->num_blank > 32) - && ((sdev->num_rows > MIN_ROWS) || (sdev->num_blank > 5000))) { + if (sdev->num_blank > FINGER_REMOVED_THRESHOLD) { sdev->finger_state = FINGER_REMOVED; fp_dbg("detected finger removal. Blank rows: %d, Full rows: %d", sdev->num_blank, sdev->num_rows); handoff_img(dev); return; } } - fp_dbg("diff is %d", diff); - if (diff < sdev->diff_thresh) { + fp_dbg("mean_sq_diff: %d, std_sq_dev: %d", mean_sq_diff, std_sq_dev); + fp_dbg("num_blank: %d", sdev->num_blank); + if (mean_sq_diff < DIFF_THRESHOLD) { return; } } @@ -1370,22 +1355,16 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) sdev->img_width = IMG_WIDTH_1000; upeksonly_driver.img_width = IMG_WIDTH_1000; assembling_ctx.line_width = IMG_WIDTH_1000; - sdev->diff_thresh = 1200; - sdev->total_thresh = 52000; break; case UPEKSONLY_1001: sdev->img_width = IMG_WIDTH_1001; upeksonly_driver.img_width = IMG_WIDTH_1001; assembling_ctx.line_width = IMG_WIDTH_1001; - sdev->diff_thresh = 400; - sdev->total_thresh = 40000; break; case UPEKSONLY_2016: sdev->img_width = IMG_WIDTH_2016; upeksonly_driver.img_width = IMG_WIDTH_2016; assembling_ctx.line_width = IMG_WIDTH_2016; - sdev->diff_thresh = 1200; - sdev->total_thresh = 52000; break; } fpi_imgdev_open_complete(dev, 0); From a1f36c71c9063a5ec179acb2cfbcc56206ba2e4f Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 11 Feb 2016 00:14:47 -0800 Subject: [PATCH 037/141] upeksonly: decrease bz3_threshold for 147e:1001 Its width is only 216 pixels, and it appears not to be enough for matching at default threshold. --- libfprint/drivers/upeksonly.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 44a9bb6a..e4dce7c8 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -1359,6 +1359,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) case UPEKSONLY_1001: sdev->img_width = IMG_WIDTH_1001; upeksonly_driver.img_width = IMG_WIDTH_1001; + upeksonly_driver.bz3_threshold = 25; assembling_ctx.line_width = IMG_WIDTH_1001; break; case UPEKSONLY_2016: From 2162aa9f48a739cc8e3b25643f9f8cba979d545e Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 18 Jul 2016 20:46:20 -0700 Subject: [PATCH 038/141] uru4k: decrypt image if necessary Add naive detection of image encryption: if stddev between two adjacent rows is higher than threshold assume that image is encrypted and decrypt it. Fixes fd.o bug 88945 --- libfprint/drivers/uru4000.c | 41 ++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 462b86ac..e07db502 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -45,6 +45,8 @@ #define IMAGE_HEIGHT 290 #define IMAGE_WIDTH 384 +#define ENC_THRESHOLD 1000 + enum { IRQDATA_SCANPWR_ON = 0x56aa, IRQDATA_FINGER_ON = 0x0101, @@ -664,6 +666,34 @@ static uint32_t do_decode(uint8_t *data, int num_bytes, uint32_t key) return update_key(key); } +static int calc_dev2(struct uru4k_image *img) +{ + uint8_t *b[2] = { NULL, NULL }; + int res = 0, mean = 0, i, r, j, idx; + + for (i = r = idx = 0; i < array_n_elements(img->block_info) && idx < 2; i++) { + if (img->block_info[i].flags & BLOCKF_NOT_PRESENT) + continue; + for (j = 0; j < img->block_info[i].num_lines && idx < 2; j++) + b[idx++] = img->data[r++]; + } + if (!b[0] || !b[1]) { + fp_dbg("NULL! %p %p", b[0], b[1]); + return 0; + } + for (i = 0; i < IMAGE_WIDTH; i++) + mean += (int)b[0][i] + (int)b[1][i]; + + mean /= IMAGE_WIDTH; + + for (i = 0; i < IMAGE_WIDTH; i++) { + int dev = (int)b[0][i] + (int)b[1][i] - mean; + res += dev * dev; + } + + return res / IMAGE_WIDTH; +} + static void imaging_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = ssm->priv; @@ -672,7 +702,7 @@ static void imaging_run_state(struct fpi_ssm *ssm) struct fp_img *fpimg; uint32_t key; uint8_t flags, num_lines; - int i, r, to; + int i, r, to, dev2; char buf[5]; switch (ssm->cur_state) { @@ -698,8 +728,13 @@ static void imaging_run_state(struct fpi_ssm *ssm) return; } if (!urudev->profile->encryption) { - fpi_ssm_jump_to_state(ssm, IMAGING_REPORT_IMAGE); - return; + dev2 = calc_dev2(img); + fp_dbg("dev2: %d", dev2); + if (dev2 < ENC_THRESHOLD) { + fpi_ssm_jump_to_state(ssm, IMAGING_REPORT_IMAGE); + return; + } + fp_info("image seems to be encrypted"); } buf[0] = img->key_number; buf[1] = urudev->img_enc_seed; From 5a7e6e07ffa34fd4131f95fbfe5ca23d7eedc592 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 7 Nov 2016 08:10:44 -0800 Subject: [PATCH 039/141] etes603: fix compilation error caused by a0bbbd7d3 --- libfprint/drivers/etes603.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 44cacbcb..97957579 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -1465,7 +1465,7 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) ret = libusb_claim_interface(idev->udev, 0); if (ret != LIBUSB_SUCCESS) { - fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(r)); + fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(ret)); return ret; } From d82847a6b4bbd2864388f2bf8e6a2b9d1aed05c4 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 14 May 2017 09:26:30 -0700 Subject: [PATCH 040/141] 0.7.0 --- NEWS | 22 ++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 26fdc064..815edc6d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,28 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2017-05-14: v0.7.0 release +* Drivers: + - Add VFS0050 driver + - Fix possible crash in AES3500 and AES4000 + - Fix broken enrollment in VFS101 + - Better verification with small sensor scanners + - Plenty of fixes in VFS5011 + - Fix memory corruption in AES1610 + - Improve calibration settings for AES1610 + - Improve image assembling in upeksonly driver + - Autodetect whether image is encrypted in uru4k + +* Library: + - NBIS: Remove false minutia at the edge of partial image + - Introduce routines to assemble image from lines (used in VFS5011 and upeksonly) + - Fix a bug that can cause driver state machine to enter into endless loop. + +* Udev rules: + - Add driver name to the USB properties + +* Plenty of build fixes + 2015-02-03: v0.6.0 release * Drivers: diff --git a/configure.ac b/configure.ac index 58ea9e93..8b291190 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([libfprint], [0.6.0]) +AC_INIT([libfprint], [0.7.0]) AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz check-news subdir-objects]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([libfprint/core.c]) From cfe60c0640e445d4bf0af25482f5187a89bc643b Mon Sep 17 00:00:00 2001 From: Igor Filatov Date: Sun, 15 Oct 2017 16:38:29 +0300 Subject: [PATCH 041/141] Add Elan driver --- configure.ac | 13 +- libfprint/Makefile.am | 6 + libfprint/core.c | 3 + libfprint/drivers/driver_ids.h | 1 + libfprint/drivers/elan.c | 630 +++++++++++++++++++++++++++++++++ libfprint/drivers/elan.h | 176 +++++++++ libfprint/fp_internal.h | 3 + 7 files changed, 831 insertions(+), 1 deletion(-) create mode 100644 libfprint/drivers/elan.c create mode 100644 libfprint/drivers/elan.h diff --git a/configure.ac b/configure.ac index 8b291190..bc38434d 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_SUBST(lt_major) AC_SUBST(lt_revision) 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" +all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes1660 aes2501 aes2550 aes2660 aes3500 aes4000 vfs101 vfs301 vfs5011 upektc_img etes603 vfs0050 elan" require_imaging='no' require_aeslib='no' @@ -49,6 +49,7 @@ enable_vfs5011='no' enable_upektc_img='no' enable_etes603='no' enable_vfs0050='no' +enable_elan='no' AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], [List of drivers to enable])], @@ -155,6 +156,10 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do AC_DEFINE([ENABLE_VFS0050], [], [Build Validity VFS0050 driver]) enable_vfs0050="yes" ;; + elan) + AC_DEFINE([ENABLE_ELAN], [], [Build Elan driver]) + enable_elan="yes" + ;; esac done @@ -181,6 +186,7 @@ AM_CONDITIONAL([ENABLE_VFS5011], [test "$enable_vfs5011" = "yes"]) 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"]) +AM_CONDITIONAL([ENABLE_ELAN], [test "$enable_elan" = "yes"]) PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) @@ -407,6 +413,11 @@ if test x$enable_vfs0050 != xno ; then else AC_MSG_NOTICE([ vfs0050 driver disabled]) fi +if test x$enable_elan != xno ; then + AC_MSG_NOTICE([** elan driver enabled]) +else + AC_MSG_NOTICE([ elan 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 a7fb162d..6d1e9c6a 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -22,6 +22,7 @@ VFS5011_SRC = drivers/vfs5011.c drivers/vfs5011_proto.h UPEKTC_IMG_SRC = drivers/upektc_img.c drivers/upektc_img.h ETES603_SRC = drivers/etes603.c VFS0050_SRC = drivers/vfs0050.c drivers/vfs0050.h +ELAN_SRC = drivers/elan.c drivers/elan.h EXTRA_DIST = \ $(UPEKE2_SRC) \ @@ -44,6 +45,7 @@ EXTRA_DIST = \ $(UPEKTC_IMG_SRC) \ $(ETES603_SRC) \ $(VFS0050_SRC) \ + $(ELAN_SRC) \ drivers/aesx660.c \ drivers/aesx660.h \ drivers/aes3k.c \ @@ -190,6 +192,10 @@ if ENABLE_VFS0050 DRIVER_SRC += $(VFS0050_SRC) endif +if ENABLE_ELAN +DRIVER_SRC += $(ELAN_SRC) +endif + if REQUIRE_PIXMAN OTHER_SRC += pixman.c libfprint_la_CFLAGS += $(IMAGING_CFLAGS) diff --git a/libfprint/core.c b/libfprint/core.c index 8b6fe438..522213e3 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -401,6 +401,9 @@ static struct fp_img_driver * const img_drivers[] = { #ifdef ENABLE_VFS0050 &vfs0050_driver, #endif +#ifdef ENABLE_ELAN + &elan_driver, +#endif /*#ifdef ENABLE_FDU2000 &fdu2000_driver, #endif diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h index 8143d01e..dbd76a7e 100644 --- a/libfprint/drivers/driver_ids.h +++ b/libfprint/drivers/driver_ids.h @@ -41,6 +41,7 @@ enum { ETES603_ID = 18, VFS5011_ID = 19, VFS0050_ID = 20, + ELAN_ID = 21, }; #endif diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c new file mode 100644 index 00000000..976ce079 --- /dev/null +++ b/libfprint/drivers/elan.c @@ -0,0 +1,630 @@ +/* + * Elan driver for libfprint + * + * Copyright (C) 2017 Igor Filatov + * + * 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 "elan" + +#include +#include +#include +#include +#include + +#include "elan.h" +#include "driver_ids.h" + +unsigned char elan_get_pixel(struct fpi_frame_asmbl_ctx *ctx, + struct fpi_frame *frame, unsigned int x, + unsigned int y) +{ + return frame->data[x + y * ctx->frame_width]; +} + +static struct fpi_frame_asmbl_ctx assembling_ctx = { + .frame_width = 0, + .frame_height = 0, + .image_width = 0, + .get_pixel = elan_get_pixel, +}; + +struct elan_dev { + gboolean deactivating; + + const struct elan_cmd *cmds; + size_t cmds_len; + int cmd_idx; + int cmd_timeout; + struct libusb_transfer *cur_transfer; + + unsigned char *last_read; + unsigned char frame_width; + unsigned char frame_height; + unsigned char raw_frame_width; + int num_frames; + GSList *frames; +}; + +static void elan_dev_reset(struct elan_dev *elandev) +{ + fp_dbg(""); + + BUG_ON(elandev->cur_transfer); + + elandev->deactivating = FALSE; + + elandev->cmds = NULL; + elandev->cmd_idx = 0; + elandev->cmd_timeout = ELAN_CMD_TIMEOUT; + + g_free(elandev->last_read); + elandev->last_read = NULL; + + g_slist_free_full(elandev->frames, g_free); + elandev->frames = NULL; + elandev->num_frames = 0; +} + +static void elan_save_frame(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + unsigned char raw_height = elandev->frame_width; + unsigned char raw_width = elandev->raw_frame_width; + unsigned short *frame = + g_malloc(elandev->frame_width * elandev->frame_height * 2); + + fp_dbg(""); + + /* Raw images are vertical and perpendicular to swipe direction of a + * normalized image, which means we need to make them horizontal before + * assembling. We also discard stirpes of ELAN_FRAME_MARGIN along raw + * height. */ + for (int y = 0; y < raw_height; y++) + for (int x = ELAN_FRAME_MARGIN; + x < raw_width - ELAN_FRAME_MARGIN; x++) { + int frame_idx = + y + (x - ELAN_FRAME_MARGIN) * raw_height; + int raw_idx = x + y * raw_width; + frame[frame_idx] = + ((unsigned short *)elandev->last_read)[raw_idx]; + } + + elandev->frames = g_slist_prepend(elandev->frames, frame); + elandev->num_frames += 1; +} + +/* Transform raw sesnsor data to normalized 8-bit grayscale image. */ +static void elan_process_frame(unsigned short *raw_frame, GSList ** frames) +{ + unsigned int frame_size = + assembling_ctx.frame_width * assembling_ctx.frame_height; + struct fpi_frame *frame = + g_malloc(frame_size + sizeof(struct fpi_frame)); + + fp_dbg(""); + + unsigned short min = 0xffff, max = 0; + for (int i = 0; i < frame_size; i++) { + if (raw_frame[i] < min) + min = raw_frame[i]; + if (raw_frame[i] > max) + max = raw_frame[i]; + } + + unsigned short px; + for (int i = 0; i < frame_size; i++) { + px = raw_frame[i]; + if (px <= min) + px = 0; + else if (px >= max) + px = 0xff; + else + px = (px - min) * 0xff / (max - min); + frame->data[i] = (unsigned char)px; + } + + *frames = g_slist_prepend(*frames, frame); +} + +static void elan_submit_image(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + GSList *frames = NULL; + struct fp_img *img; + + fp_dbg(""); + + for (int i = 0; i < ELAN_SKIP_LAST_FRAMES; i++) + elandev->frames = g_slist_next(elandev->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) elan_process_frame, &frames); + fpi_do_movement_estimation(&assembling_ctx, frames, + elandev->num_frames - ELAN_SKIP_LAST_FRAMES); + img = fpi_assemble_frames(&assembling_ctx, frames, + elandev->num_frames - ELAN_SKIP_LAST_FRAMES); + + img->flags |= FP_IMG_PARTIAL; + fpi_imgdev_image_captured(dev, img); +} + +static void elan_cmd_done(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elandev->cmd_idx += 1; + if (elandev->cmd_idx < elandev->cmds_len) + elan_run_next_cmd(ssm); + else + fpi_ssm_next_state(ssm); +} + +static void elan_cmd_cb(struct libusb_transfer *transfer) +{ + struct fpi_ssm *ssm = transfer->user_data; + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elandev->cur_transfer = NULL; + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + if (transfer->length != transfer->actual_length) { + fp_dbg("unexpected transfer length"); + elan_dev_reset(elandev); + fpi_ssm_mark_aborted(ssm, -EPROTO); + } else if (transfer->endpoint & LIBUSB_ENDPOINT_IN) + /* just finished receiving */ + elan_cmd_done(ssm); + else { + /* just finished sending */ + if (elandev->cmds[elandev->cmd_idx].response_len) + elan_cmd_read(ssm); + else + elan_cmd_done(ssm); + } + break; + case LIBUSB_TRANSFER_CANCELLED: + fp_dbg("transfer cancelled"); + fpi_ssm_mark_aborted(ssm, -ECANCELED); + break; + case LIBUSB_TRANSFER_TIMED_OUT: + fp_dbg("transfer timed out"); + // elan_dev_reset(elandev); + fpi_ssm_mark_aborted(ssm, -ETIMEDOUT); + break; + default: + fp_dbg("transfer failed: %d", transfer->status); + elan_dev_reset(elandev); + fpi_ssm_mark_aborted(ssm, -EIO); + } +} + +static void elan_cmd_read(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + int response_len = elandev->cmds[elandev->cmd_idx].response_len; + + fp_dbg(""); + + if (elandev->cmds[elandev->cmd_idx].cmd == read_cmds[0].cmd) + /* raw data has 2-byte "pixels" and the frame is vertical */ + response_len = + elandev->raw_frame_width * elandev->frame_width * 2; + + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + if (!transfer) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + return; + } + elandev->cur_transfer = transfer; + + g_free(elandev->last_read); + elandev->last_read = g_malloc(response_len); + + libusb_fill_bulk_transfer(transfer, dev->udev, + elandev->cmds[elandev->cmd_idx].response_in, + elandev->last_read, response_len, elan_cmd_cb, + ssm, elandev->cmd_timeout); + transfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER; + int r = libusb_submit_transfer(transfer); + if (r < 0) + fpi_ssm_mark_aborted(ssm, r); +} + +static void elan_run_next_cmd(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + if (!transfer) { + fpi_ssm_mark_aborted(ssm, -ENOMEM); + return; + } + elandev->cur_transfer = transfer; + + libusb_fill_bulk_transfer(transfer, dev->udev, ELAN_EP_CMD_OUT, + (unsigned char *)elandev->cmds[elandev-> + cmd_idx].cmd, + ELAN_CMD_LEN, elan_cmd_cb, ssm, + elandev->cmd_timeout); + transfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER; + int r = libusb_submit_transfer(transfer); + if (r < 0) + fpi_ssm_mark_aborted(ssm, r); + +} + +static void elan_run_cmds(struct fpi_ssm *ssm, const struct elan_cmd *cmds, + size_t cmds_len, int cmd_timeout) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elandev->cmds = cmds; + elandev->cmds_len = cmds_len; + elandev->cmd_idx = 0; + if (cmd_timeout != -1) + elandev->cmd_timeout = cmd_timeout; + elan_run_next_cmd(ssm); +} + +enum deactivate_states { + DEACTIVATE, + DEACTIVATE_NUM_STATES, +}; + +static void elan_deactivate_run_state(struct fpi_ssm *ssm) +{ + switch (ssm->cur_state) { + case DEACTIVATE: + elan_run_cmds(ssm, deactivate_cmds, deactivate_cmds_len, + ELAN_CMD_TIMEOUT); + break; + } +} + +static void deactivate_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + + fpi_imgdev_deactivate_complete(dev); +} + +static void elan_deactivate(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elan_dev_reset(elandev); + + struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_deactivate_run_state, + DEACTIVATE_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, deactivate_complete); +} + +enum capture_states { + CAPTURE_START, + CAPTURE_WAIT_FINGER, + CAPTURE_READ_DATA, + CAPTURE_SAVE_FRAME, + CAPTURE_NUM_STATES, +}; + +static void elan_capture_run_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + switch (ssm->cur_state) { + case CAPTURE_START: + elan_run_cmds(ssm, capture_start_cmds, capture_start_cmds_len, + ELAN_CMD_TIMEOUT); + break; + case CAPTURE_WAIT_FINGER: + elan_run_cmds(ssm, capture_wait_finger_cmds, + capture_wait_finger_cmds_len, -1); + break; + case CAPTURE_READ_DATA: + /* 0x55 - finger present + * 0xff - device not calibrated */ + if (elandev->last_read && elandev->last_read[0] == 0x55) { + fpi_imgdev_report_finger_status(dev, TRUE); + elan_run_cmds(ssm, read_cmds, read_cmds_len, + ELAN_CMD_TIMEOUT); + } else + fpi_ssm_mark_aborted(ssm, FP_VERIFY_RETRY); + break; + case CAPTURE_SAVE_FRAME: + elan_save_frame(dev); + if (elandev->num_frames < ELAN_MAX_FRAMES) { + /* quickly stop if finger is removed */ + elandev->cmd_timeout = ELAN_FINGER_TIMEOUT; + fpi_ssm_jump_to_state(ssm, CAPTURE_WAIT_FINGER); + } + break; + } +} + +static void elan_capture_async(void *data) +{ + elan_capture((struct fp_img_dev *)data); +} + +static void capture_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + if (elandev->deactivating) + elan_deactivate(dev); + + /* either max frames captured or timed out waiting for the next frame */ + else if (!ssm->error + || (ssm->error == -ETIMEDOUT + && ssm->cur_state == CAPTURE_WAIT_FINGER)) + if (elandev->num_frames >= ELAN_MIN_FRAMES) { + elan_submit_image(dev); + fpi_imgdev_report_finger_status(dev, FALSE); + } else + fpi_imgdev_session_error(dev, + FP_VERIFY_RETRY_TOO_SHORT); + + /* other error + * It says "...session_error" but repotring 1 during verification + * makes it successful! */ + else + fpi_imgdev_session_error(dev, FP_VERIFY_NO_MATCH); + + /* When enrolling the lib won't restart the capture after a stage has + * completed, so we need to keep feeding it images till it's had enough. + * But after that it can't finalize enrollemnt until this callback exits. + * That's why we schedule elan_capture instead of running it directly. */ + if (dev->dev->state == DEV_STATE_ENROLLING + && !fpi_timeout_add(10, elan_capture_async, dev)) + fpi_imgdev_session_error(dev, -ETIME); + + fpi_ssm_free(ssm); +} + +static void elan_capture(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elan_dev_reset(elandev); + struct fpi_ssm *ssm = + fpi_ssm_new(dev->dev, elan_capture_run_state, CAPTURE_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, capture_complete); +} + +enum calibrate_states { + CALIBRATE_START_1, + CALIBRATE_READ_DATA_1, + CALIBRATE_END_1, + CALIBRATE_START_2, + CALIBRATE_READ_DATA_2, + CALIBRATE_END_2, + CALIBRATE_NUM_STATES, +}; + +static void elan_calibrate_run_state(struct fpi_ssm *ssm) +{ + switch (ssm->cur_state) { + case CALIBRATE_START_1: + case CALIBRATE_START_2: + elan_run_cmds(ssm, calibrate_start_cmds, + calibrate_start_cmds_len, ELAN_CMD_TIMEOUT); + break; + case CALIBRATE_READ_DATA_1: + case CALIBRATE_READ_DATA_2: + elan_run_cmds(ssm, read_cmds, read_cmds_len, ELAN_CMD_TIMEOUT); + break; + case CALIBRATE_END_1: + case CALIBRATE_END_2: + elan_run_cmds(ssm, calibrate_end_cmds, calibrate_end_cmds_len, + ELAN_CMD_TIMEOUT); + } +} + +static void calibrate_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + if (elandev->deactivating) + elan_deactivate(dev); + else if (ssm->error) + fpi_imgdev_session_error(dev, ssm->error); + else { + fpi_imgdev_activate_complete(dev, ssm->error); + elan_capture(dev); + } + fpi_ssm_free(ssm); +} + +static void elan_calibrate(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elan_dev_reset(elandev); + struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_calibrate_run_state, + CALIBRATE_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, calibrate_complete); +} + +enum activate_states { + ACTIVATE_GET_SENSOR_DIM, + ACTIVATE_SET_SENSOR_DIM, + ACTIVATE_START, + ACTIVATE_READ_DATA, + ACTIVATE_END, + ACTIVATE_NUM_STATES, +}; + +static void elan_activate_run_state(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + switch (ssm->cur_state) { + case ACTIVATE_GET_SENSOR_DIM: + elan_run_cmds(ssm, get_sensor_dim_cmds, get_sensor_dim_cmds_len, + ELAN_CMD_TIMEOUT); + break; + case ACTIVATE_SET_SENSOR_DIM: + elandev->frame_width = elandev->last_read[2]; + elandev->raw_frame_width = elandev->last_read[0]; + elandev->frame_height = + elandev->raw_frame_width - 2 * ELAN_FRAME_MARGIN; + fpi_ssm_next_state(ssm); + break; + case ACTIVATE_START: + elan_run_cmds(ssm, init_start_cmds, init_start_cmds_len, + ELAN_CMD_TIMEOUT); + break; + case ACTIVATE_READ_DATA: + elan_run_cmds(ssm, read_cmds, read_cmds_len, ELAN_CMD_TIMEOUT); + break; + case ACTIVATE_END: + elan_run_cmds(ssm, init_end_cmds, init_end_cmds_len, + ELAN_CMD_TIMEOUT); + } +} + +static void activate_complete(struct fpi_ssm *ssm) +{ + struct fp_img_dev *dev = ssm->priv; + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + if (elandev->deactivating) + elan_deactivate(dev); + else if (ssm->error) + fpi_imgdev_session_error(dev, ssm->error); + else + elan_calibrate(dev); + fpi_ssm_free(ssm); +} + +static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) +{ + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elan_dev_reset(elandev); + struct fpi_ssm *ssm = + fpi_ssm_new(dev->dev, elan_activate_run_state, ACTIVATE_NUM_STATES); + ssm->priv = dev; + fpi_ssm_start(ssm, activate_complete); + + return 0; +} + +static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) +{ + struct elan_dev *elandev; + int r; + + fp_dbg(""); + + r = libusb_claim_interface(dev->udev, 0); + if (r < 0) { + fp_err("could not claim interface 0: %s", libusb_error_name(r)); + return r; + } + + dev->priv = elandev = g_malloc0(sizeof(struct elan_dev)); + fpi_imgdev_open_complete(dev, 0); + return 0; +} + +static void dev_deinit(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elan_dev_reset(elandev); + g_free(elandev); + libusb_release_interface(dev->udev, 0); + fpi_imgdev_close_complete(dev); +} + +static void dev_deactivate(struct fp_img_dev *dev) +{ + struct elan_dev *elandev = dev->priv; + + fp_dbg(""); + + elandev->deactivating = TRUE; + + if (elandev->cur_transfer) + libusb_cancel_transfer(elandev->cur_transfer); + else + elan_deactivate(dev); +} + +static const struct usb_id id_table[] = { + {.vendor = 0x04f3,.product = 0x0907}, + {0, 0, 0,}, +}; + +struct fp_img_driver elan_driver = { + .driver = { + .id = ELAN_ID, + .name = FP_COMPONENT, + .full_name = "ElanTech Fingerprint Sensor", + .id_table = id_table, + .scan_type = FP_SCAN_TYPE_SWIPE, + }, + .flags = 0, + + .bz3_threshold = 22, + + .open = dev_init, + .close = dev_deinit, + .activate = dev_activate, + .deactivate = dev_deactivate, +}; diff --git a/libfprint/drivers/elan.h b/libfprint/drivers/elan.h new file mode 100644 index 00000000..1b47dbc6 --- /dev/null +++ b/libfprint/drivers/elan.h @@ -0,0 +1,176 @@ +/* + * Elan driver for libfprint + * + * Copyright (C) 2017 Igor Filatov + * + * 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 __ELAN_H +#define __ELAN_H + +#include +#include + +/* number of pixels to discard on left and right (along raw image height) + * because they have different intensity from the rest of the frame */ +#define ELAN_FRAME_MARGIN 12 + +/* min and max frames in a capture */ +#define ELAN_MIN_FRAMES 7 +#define ELAN_MAX_FRAMES 30 + +/* 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_CMD_LEN 0x2 +#define ELAN_EP_CMD_OUT (0x1 | LIBUSB_ENDPOINT_OUT) +#define ELAN_EP_CMD_IN (0x3 | LIBUSB_ENDPOINT_IN) +#define ELAN_EP_IMG_IN (0x2 | LIBUSB_ENDPOINT_IN) + +/* usual command timeout and timeout for when we need to check if the finger is + * still on the device */ +#define ELAN_CMD_TIMEOUT 10000 +#define ELAN_FINGER_TIMEOUT 200 + +struct elan_cmd { + unsigned char cmd[ELAN_CMD_LEN]; + int response_len; + int response_in; +}; + +static const struct elan_cmd get_sensor_dim_cmds[] = { + { + .cmd = {0x00, 0x0c}, + .response_len = 0x4, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static const size_t get_sensor_dim_cmds_len = +array_n_elements(get_sensor_dim_cmds); + +static const struct elan_cmd init_start_cmds[] = { + { + .cmd = {0x40, 0x19}, + .response_len = 0x2, + .response_in = ELAN_EP_CMD_IN, + }, + { + .cmd = {0x40, 0x2a}, + .response_len = 0x2, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static const size_t init_start_cmds_len = array_n_elements(init_start_cmds); + +static const struct elan_cmd read_cmds[] = { + /* raw frame sizes are calculated from image dimesions reported by the + * device */ + { + .cmd = {0x00, 0x09}, + .response_len = -1, + .response_in = ELAN_EP_IMG_IN, + }, +}; + +const size_t read_cmds_len = array_n_elements(read_cmds); + +/* issued after data reads during init and calibration */ +static const struct elan_cmd init_end_cmds[] = { + { + .cmd = {0x40, 0x24}, + .response_len = 0x2, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static const size_t init_end_cmds_len = array_n_elements(init_end_cmds); + +/* same command 2 times + * original driver may observe return value to determine how many times it + * should be repeated */ +static const struct elan_cmd calibrate_start_cmds[] = { + { + .cmd = {0x40, 0x23}, + .response_len = 0x1, + .response_in = ELAN_EP_CMD_IN, + }, + { + .cmd = {0x40, 0x23}, + .response_len = 0x1, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static const size_t calibrate_start_cmds_len = +array_n_elements(calibrate_start_cmds); + +/* issued after data reads during init and calibration */ +static const struct elan_cmd calibrate_end_cmds[] = { + { + .cmd = {0x40, 0x24}, + .response_len = 0x2, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static const size_t calibrate_end_cmds_len = +array_n_elements(calibrate_end_cmds); + +static const struct elan_cmd capture_start_cmds[] = { + /* led on */ + { + .cmd = {0x40, 0x31}, + .response_len = 0x0, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static size_t capture_start_cmds_len = array_n_elements(capture_start_cmds); + +static const struct elan_cmd capture_wait_finger_cmds[] = { + /* wait for finger + * subsequent read will not complete until finger is placed on the reader */ + { + .cmd = {0x40, 0x3f}, + .response_len = 0x1, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static size_t capture_wait_finger_cmds_len = +array_n_elements(capture_wait_finger_cmds); + +static const struct elan_cmd deactivate_cmds[] = { + /* led off */ + { + .cmd = {0x00, 0x0b}, + .response_len = 0x0, + .response_in = ELAN_EP_CMD_IN, + }, +}; + +static const size_t deactivate_cmds_len = array_n_elements(deactivate_cmds); + +static void elan_cmd_cb(struct libusb_transfer *transfer); +static void elan_cmd_read(struct fpi_ssm *ssm); +static void elan_run_next_cmd(struct fpi_ssm *ssm); + +static void elan_capture(struct fp_img_dev *dev); + +#endif diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index e309ea97..7897a2e9 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -308,6 +308,9 @@ extern struct fp_img_driver etes603_driver; #ifdef ENABLE_VFS0050 extern struct fp_img_driver vfs0050_driver; #endif +#ifdef ENABLE_ELAN +extern struct fp_img_driver elan_driver; +#endif extern libusb_context *fpi_usb_ctx; extern GSList *opened_devices; From 4d7afd9b4f45ec2e83ec7d2174ef8459c3503202 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 10 Nov 2016 14:25:28 -0800 Subject: [PATCH 042/141] uru4k: increase threshold to detect encryption Otherwise we get false positives on devices without encryption --- libfprint/drivers/uru4000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index e07db502..ae32a6b2 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -45,7 +45,7 @@ #define IMAGE_HEIGHT 290 #define IMAGE_WIDTH 384 -#define ENC_THRESHOLD 1000 +#define ENC_THRESHOLD 5000 enum { IRQDATA_SCANPWR_ON = 0x56aa, From 4bfee76eada7a107d39d8605ca6a2981df64142f Mon Sep 17 00:00:00 2001 From: Alan Davidson Date: Thu, 18 Aug 2016 17:16:05 -0400 Subject: [PATCH 043/141] Fix security hole: zero out memory when allocated --- libfprint/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/data.c b/libfprint/data.c index 3c138c3c..70f020f7 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -112,7 +112,7 @@ void fpi_print_data_item_free(struct fp_print_data_item *item) struct fp_print_data_item *fpi_print_data_item_new(size_t length) { - struct fp_print_data_item *item = g_malloc(sizeof(*item) + length); + struct fp_print_data_item *item = g_malloc0(sizeof(*item) + length); item->length = length; return item; From 69de32f7007f50eb0485d601cda9f365fa25c9a4 Mon Sep 17 00:00:00 2001 From: Anton Eliasson Date: Wed, 15 Jun 2016 17:18:11 +0200 Subject: [PATCH 044/141] vfs5011: Don't submit an image if there was an error capturing it --- libfprint/drivers/vfs5011.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 90947d3f..facb32c8 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -747,8 +747,7 @@ static void activate_loop_complete(struct fpi_ssm *ssm) if (data->init_sequence.receive_buf != NULL) g_free(data->init_sequence.receive_buf); data->init_sequence.receive_buf = NULL; - /* We don't want to submit image if we're in deactivating process */ - if (!data->deactivating) { + if (!data->deactivating && !r) { submit_image(ssm, data); fpi_imgdev_report_finger_status(dev, FALSE); } From 1c73c36ed7e9a5f55725810aeb2aab5df4dd59c4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Dec 2017 08:41:54 +0100 Subject: [PATCH 045/141] fprint-list-udev-rules: Remove white-list entries which have a driver now Remove 2 entries from the whitelist for finger-print models for which we have a driver now, so they no longer need to be on the whitelist. --- libfprint/fprint-list-udev-rules.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c index b8fbd4c9..025686ee 100644 --- a/libfprint/fprint-list-udev-rules.c +++ b/libfprint/fprint-list-udev-rules.c @@ -24,9 +24,6 @@ #include "fp_internal.h" static const struct usb_id whitelist_id_table[] = { - { .vendor = 0x08ff, .product = 0x2810 }, - /* https://bugzilla.redhat.com/show_bug.cgi?id=1173367 */ - { .vendor = 0x138a, .product = 0x0017 }, { 0, 0, 0, }, }; From 041e6a1078c78cfeced5c21e127d02cae80b1740 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Dec 2017 08:41:55 +0100 Subject: [PATCH 046/141] fprint-list-udev-rules: Add some unsupported Elantech readers to the whitelist --- libfprint/fprint-list-udev-rules.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c index 025686ee..b5a756c1 100644 --- a/libfprint/fprint-list-udev-rules.c +++ b/libfprint/fprint-list-udev-rules.c @@ -24,6 +24,10 @@ #include "fp_internal.h" static const struct usb_id whitelist_id_table[] = { + /* Unsupported (for now) Elantech finger print readers */ + { .vendor = 0x04f3, .product = 0x0c03 }, + { .vendor = 0x04f3, .product = 0x0c16 }, + { .vendor = 0x04f3, .product = 0x0c26 }, { 0, 0, 0, }, }; From d35da0ce99c11bf43d06c2400f9fec6580814919 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 12 Dec 2017 08:41:56 +0100 Subject: [PATCH 047/141] fprint-list-udev-rules: Add some unsupported Validity Sensors readers to the whitelist --- libfprint/fprint-list-udev-rules.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libfprint/fprint-list-udev-rules.c b/libfprint/fprint-list-udev-rules.c index b5a756c1..f78ede19 100644 --- a/libfprint/fprint-list-udev-rules.c +++ b/libfprint/fprint-list-udev-rules.c @@ -28,6 +28,11 @@ static const struct usb_id whitelist_id_table[] = { { .vendor = 0x04f3, .product = 0x0c03 }, { .vendor = 0x04f3, .product = 0x0c16 }, { .vendor = 0x04f3, .product = 0x0c26 }, + /* Unsupported (for now) Validity Sensors finger print readers */ + { .vendor = 0x138a, .product = 0x0090 }, /* Found on e.g. Lenovo T460s */ + { .vendor = 0x138a, .product = 0x0091 }, + { .vendor = 0x138a, .product = 0x0094 }, + { .vendor = 0x138a, .product = 0x0097 }, /* Found on e.g. Lenovo T470s */ { 0, 0, 0, }, }; From 58ba9b02ed4da8c7ee24d8024a85582731f8ec68 Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Sat, 10 Mar 2018 18:14:42 +0000 Subject: [PATCH 048/141] lib: Fix memory leak patch in device discovery libusb_free_device_list() needs to be called on the list of USB devices obtained through libusb_get_device_list() or the list and its elements will be leaked. https://bugs.freedesktop.org/show_bug.cgi?id=105427 --- libfprint/core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libfprint/core.c b/libfprint/core.c index 522213e3..97aa5fda 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -561,9 +561,13 @@ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) struct fp_dscv_dev *ddev = discover_dev(udev); if (!ddev) continue; + /* discover_dev() doesn't hold a reference to the udev, + * so increase the reference for ddev to hold this ref */ + libusb_ref_device(udev); tmplist = g_slist_prepend(tmplist, (gpointer) ddev); dscv_count++; } + libusb_free_device_list(devs, 1); /* Convert our temporary GSList into a standard NULL-terminated pointer * array. */ @@ -594,8 +598,10 @@ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs) if (!devs) return; - for (i = 0; devs[i]; i++) + for (i = 0; devs[i]; i++) { + libusb_unref_device(devs[i]->udev); g_free(devs[i]); + } g_free(devs); } From 7ff667f58d53937f2188836b6baa476c1dad0638 Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Sun, 11 Mar 2018 13:44:31 +0100 Subject: [PATCH 049/141] examples: Fix memory leaked by device discovery https://bugs.freedesktop.org/show_bug.cgi?id=105427 --- examples/img_capture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/img_capture.c b/examples/img_capture.c index 65280317..ba256df8 100644 --- a/examples/img_capture.c +++ b/examples/img_capture.c @@ -57,6 +57,7 @@ int main(void) ddev = discover_device(discovered_devs); if (!ddev) { + fp_dscv_devs_free(discovered_devs); fprintf(stderr, "No devices detected.\n"); goto out; } From 54deaa1b24e074bb65fb3c87483cb5010374f6f9 Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Sun, 11 Mar 2018 13:38:56 -0700 Subject: [PATCH 050/141] mindtct: Fix compilation warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nbis/mindtct/morph.c:152:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation] nbis/mindtct/morph.c:176:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation] nbis/mindtct/morph.c:200:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation] nbis/mindtct/morph.c:222:4: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation] https://bugs.freedesktop.org/show_bug.cgi?id=105429 --- libfprint/nbis/mindtct/morph.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libfprint/nbis/mindtct/morph.c b/libfprint/nbis/mindtct/morph.c index b6be74f3..d4ec85f3 100644 --- a/libfprint/nbis/mindtct/morph.c +++ b/libfprint/nbis/mindtct/morph.c @@ -151,7 +151,7 @@ char get_south8_2(char *ptr, const int row, const int iw, const int ih, { if (row >= ih-1) /* catch case where image is undefined southwards */ return failcode; /* use plane geometry and return code. */ - + else return *(ptr+iw); } @@ -175,7 +175,7 @@ char get_north8_2(char *ptr, const int row, const int iw, { if (row < 1) /* catch case where image is undefined northwards */ return failcode; /* use plane geometry and return code. */ - + else return *(ptr-iw); } @@ -199,7 +199,7 @@ char get_east8_2(char *ptr, const int col, const int iw, { if (col >= iw-1) /* catch case where image is undefined eastwards */ return failcode; /* use plane geometry and return code. */ - + else return *(ptr+ 1); } @@ -221,6 +221,6 @@ char get_west8_2(char *ptr, const int col, const int failcode) { if (col < 1) /* catch case where image is undefined westwards */ return failcode; /* use plane geometry and return code. */ - + else return *(ptr- 1); } From 5226467fc237341dbe6f88ebb1d8d52586513059 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 27 Apr 2018 14:07:20 +0200 Subject: [PATCH 051/141] build: Make NSS (and URU4000) driver optional In case NSS isn't available. https://bugs.freedesktop.org/show_bug.cgi?id=106278 --- configure.ac | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index bc38434d..ad88a30e 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ require_imaging='no' require_aeslib='no' require_aesX660='no' require_aes3k='no' +require_nss='no' enable_upeke2='no' enable_upekts='no' enable_upektc='no' @@ -81,6 +82,7 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do uru4000) AC_DEFINE([ENABLE_URU4000], [], [Build Digital Persona U.are.U 4000 driver]) enable_uru4000="yes" + require_nss="yes" ;; fdu2000) AC_DEFINE([ENABLE_FDU2000], [], [Build Secugen FDU 2000 driver]) @@ -193,8 +195,13 @@ PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) AC_SUBST(LIBUSB_CFLAGS) AC_SUBST(LIBUSB_LIBS) -# check for OpenSSL's libcrypto -PKG_CHECK_MODULES(CRYPTO, nss) +if test "$require_nss" = "yes"; then + # check for NSS + PKG_CHECK_MODULES(CRYPTO, nss, [nss_found=yes], [nss_found=no]) + if test "$nss_found" != "yes"; then + AC_MSG_ERROR([NSS is required for the URU4000/URU4500 driver]) + fi +fi AC_SUBST(CRYPTO_CFLAGS) AC_SUBST(CRYPTO_LIBS) From 3bf55a3e0766ca90f5befc1ed161b1c83005a962 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 14 May 2018 17:11:37 +0200 Subject: [PATCH 052/141] examples: Fix compile-time warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix "function declaration isn’t a prototype" warning --- examples/img_capture_continuous.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/img_capture_continuous.c b/examples/img_capture_continuous.c index b30f2b1d..94459b13 100644 --- a/examples/img_capture_continuous.c +++ b/examples/img_capture_continuous.c @@ -84,7 +84,7 @@ static void display_frame(struct fp_img *img) 0, 0, width, height, 0, 0, width, height); } -static void QueryXv() +static void QueryXv(void) { unsigned int num_adaptors; int num_formats; From 3661d146a7dccd201314a762e354ec4624ed99a7 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 11 May 2018 14:27:44 +0200 Subject: [PATCH 053/141] drivers: Remove UPEKE2 driver The device is already handled by upektc_img driver, and its sources still exist in git if needed. https://bugs.freedesktop.org/show_bug.cgi?id=106514 --- configure.ac | 11 - libfprint/Makefile.am | 6 - libfprint/core.c | 3 - libfprint/drivers/driver_ids.h | 2 +- libfprint/drivers/upeke2.c | 1483 -------------------------------- libfprint/drivers/upektc_img.c | 4 - libfprint/fp_internal.h | 3 - 7 files changed, 1 insertion(+), 1511 deletions(-) delete mode 100644 libfprint/drivers/upeke2.c diff --git a/configure.ac b/configure.ac index ad88a30e..d8b21192 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,6 @@ require_aeslib='no' require_aesX660='no' require_aes3k='no' require_nss='no' -enable_upeke2='no' enable_upekts='no' enable_upektc='no' enable_upeksonly='no' @@ -67,10 +66,6 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do AC_DEFINE([ENABLE_UPEKTS], [], [Build UPEK TouchStrip driver]) enable_upekts="yes" ;; - upeke2) - AC_DEFINE([ENABLE_UPEKE2], [], [Build UPEK Eikon 2]) - enable_upeke2="yes" - ;; upektc) AC_DEFINE([ENABLE_UPEKTC], [], [Build UPEK TouchChip driver]) enable_upektc="yes" @@ -166,7 +161,6 @@ for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do done AM_CONDITIONAL([ENABLE_UPEKTS], [test "$enable_upekts" = "yes"]) -AM_CONDITIONAL([ENABLE_UPEKE2], [test "$enable_upeke2" = "yes"]) AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" = "yes"]) AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" = "yes"]) AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" = "yes"]) @@ -325,11 +319,6 @@ if test x$enable_upekts != xno ; then else AC_MSG_NOTICE([ upekts driver disabled]) fi -if test x$enable_upeke2 != xno ; then - AC_MSG_NOTICE([** upeke2 driver enabled]) -else - AC_MSG_NOTICE([ upeke2 driver disabled (handled by upektc_img driver)]) -fi if test x$enable_upektc != xno ; then AC_MSG_NOTICE([** upektc driver enabled]) else diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am index 6d1e9c6a..29ecd40b 100644 --- a/libfprint/Makefile.am +++ b/libfprint/Makefile.am @@ -2,7 +2,6 @@ lib_LTLIBRARIES = libfprint.la noinst_PROGRAMS = fprint-list-udev-rules MOSTLYCLEANFILES = $(udev_rules_DATA) -UPEKE2_SRC = drivers/upeke2.c UPEKTS_SRC = drivers/upekts.c UPEKTC_SRC = drivers/upektc.c drivers/upektc.h UPEKSONLY_SRC = drivers/upeksonly.c drivers/upeksonly.h @@ -25,7 +24,6 @@ VFS0050_SRC = drivers/vfs0050.c drivers/vfs0050.h ELAN_SRC = drivers/elan.c drivers/elan.h EXTRA_DIST = \ - $(UPEKE2_SRC) \ $(UPEKTS_SRC) \ $(UPEKTC_SRC) \ $(UPEKSONLY_SRC) \ @@ -112,10 +110,6 @@ $(udev_rules_DATA): fprint-list-udev-rules $(builddir)/fprint-list-udev-rules > $@ endif -if ENABLE_UPEKE2 -DRIVER_SRC += $(UPEKE2_SRC) -endif - if ENABLE_UPEKTS DRIVER_SRC += $(UPEKTS_SRC) endif diff --git a/libfprint/core.c b/libfprint/core.c index 97aa5fda..6f3729e2 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -343,9 +343,6 @@ static struct fp_driver * const primitive_drivers[] = { #ifdef ENABLE_UPEKTS &upekts_driver, #endif -#ifdef ENABLE_UPEKE2 - &upeke2_driver, -#endif }; static struct fp_img_driver * const img_drivers[] = { diff --git a/libfprint/drivers/driver_ids.h b/libfprint/drivers/driver_ids.h index dbd76a7e..8839a744 100644 --- a/libfprint/drivers/driver_ids.h +++ b/libfprint/drivers/driver_ids.h @@ -33,7 +33,7 @@ enum { VFS101_ID = 10, VFS301_ID = 11, AES2550_ID = 12, - UPEKE2_ID = 13, + /* UPEKE2_ID = 13 */ AES1660_ID = 14, AES2660_ID = 15, AES3500_ID = 16, diff --git a/libfprint/drivers/upeke2.c b/libfprint/drivers/upeke2.c deleted file mode 100644 index 3f05e809..00000000 --- a/libfprint/drivers/upeke2.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * Copyright (C) 2010 Jorge Suarez de Lis - * - * Heavily based on UPEK TouchStrip driver for libfprint - * Copyright (C) 2007-2008 Daniel Drake - * - * Based in part on libthinkfinger: - * Copyright (C) 2006-2007 Timo Hoenig - * Copyright (C) 2006 Pavel Machek - * - * LGPL CRC code copied from GStreamer-0.10.10: - * Copyright (C) <1999> Erik Walthinsen - * Copyright (C) 2004,2006 Thomas Vander Stichele - - * 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; version - * 2.1 of the License. - * - * 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 "upeke2" - -#include -#include - -#include -#include - -#include - -#include "driver_ids.h" - -#define EP_IN (1 | LIBUSB_ENDPOINT_IN) -#define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) -#define TIMEOUT 5000 - -#define MSG_READ_BUF_SIZE 0x40 -#define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9) - -enum { - UPEKE2_2016, -}; - -struct upeke2_dev { - gboolean enroll_passed; - gboolean first_verify_iteration; - gboolean stop_verify; - uint8_t seq; /* FIXME: improve/automate seq handling */ -}; - -static const uint16_t crc_table[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 -}; - -static uint16_t udf_crc(unsigned char *buffer, size_t size) -{ - uint16_t crc = 0; - while (size--) - crc = (uint16_t) ((crc << 8) ^ - crc_table[((crc >> 8) & 0x00ff) ^ *buffer++]); - return crc; -} - -/* - * MESSAGE FORMAT - * - * Messages to and from the device have the same format. - * - * Byte-wise: - * 'C' 'i' 'a' 'o' A B L C1 C2 - * - * Ciao prefixes all messages. The rightmost 4 bits of B become the uppermost - * 4 bits of L, and when combined with the lower 8 bits listed as 'L', L is - * the length of the data, is L bytes long. C1 and C2 are the - * UDF-CRC16 for the whole message minus the Ciao prefix. - * - * When the device wants to command the driver to do something, it sends - * a message where B=0 and A!=0. The A value indicates the type of command. - * If the system is expected to respond to the command, it sends a message back - * with B=0 and A incremented. - * - * When the driver sends a command to the device, A=0 and B is used as a - * sequence counter. It starts at 0, increments by 0x10 on each command, and - * wraps around. - * After each command is sent, the device responds with another message - * indicating completion of the command including any data that was requested. - * This message has the same A and B values. - * - * When the driver is sending commands as above, and when the device is - * responding, the seems to follow this structure: - * - * 28 L1 L2 0 0 S - * - * Where the length of is L-3, and S is some kind of subcommand - * code. L1 is the least significant bits of L, L2 is the most significant. In - * the device's response to a command, the subcommand code will be unchanged. - * - * After deducing and documenting the above, I found a few places where the - * above doesn't hold true. Those are marked with FIXME's below. - */ - -#define CMD_SEQ_INCREMENT 0x10 - -static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev, - unsigned char seq_a, unsigned char seq_b, const unsigned char *data, - uint16_t len, libusb_transfer_cb_fn callback, void *user_data) -{ - struct libusb_transfer *transfer = libusb_alloc_transfer(0); - uint16_t crc; - - /* 9 bytes extra for: 4 byte 'Ciao', 1 byte A, 1 byte B | lenHI, - * 1 byte lenLO, 2 byte CRC */ - size_t urblen = len + 9; - unsigned char *buf; - - if (!transfer) - return NULL; - - if (!data && len > 0) { - fp_err("len>0 but no data?"); - return NULL; - } - - buf = g_malloc(urblen); - - /* Write header */ - strncpy(buf, "Ciao", 4); - len = GUINT16_TO_LE(len); - buf[4] = seq_a; - buf[5] = seq_b | ((len & 0xf00) >> 8); - buf[6] = len & 0x00ff; - - /* Copy data */ - if (data) - memcpy(buf + 7, data, len); - - /* Append CRC */ - crc = GUINT16_TO_BE(udf_crc(buf + 4, urblen - 6)); - buf[urblen - 2] = crc >> 8; - buf[urblen - 1] = crc & 0xff; - - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, buf, urblen, - callback, user_data, TIMEOUT); - return transfer; -} - -static struct libusb_transfer *alloc_send_cmd28_transfer(struct fp_dev *dev, - unsigned char subcmd, const unsigned char *data, uint16_t innerlen, - libusb_transfer_cb_fn callback, void *user_data) -{ - uint16_t _innerlen = innerlen; - size_t len = innerlen + 6; - unsigned char *buf = g_malloc0(len); - struct upeke2_dev *upekdev = dev->priv; - uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT; - struct libusb_transfer *ret; - - fp_dbg("seq=%02x subcmd=%02x with %d bytes of data", seq, subcmd, innerlen); - - _innerlen = GUINT16_TO_LE(innerlen + 3); - buf[0] = 0x28; - buf[1] = _innerlen & 0x00ff; - buf[2] = (_innerlen & 0xff00) >> 8; - buf[5] = subcmd; - memcpy(buf + 6, data, innerlen); - - ret = alloc_send_cmd_transfer(dev, 0, seq, buf, len, callback, user_data); - upekdev->seq = seq; - - g_free(buf); - return ret; -} - -static struct libusb_transfer *alloc_send_cmdresponse_transfer( - struct fp_dev *dev, unsigned char seq, const unsigned char *data, - uint8_t len, libusb_transfer_cb_fn callback, void *user_data) -{ - fp_dbg("seq=%02x len=%d", seq, len); - return alloc_send_cmd_transfer(dev, seq, 0, data, len, callback, user_data); -} - -enum read_msg_status { - READ_MSG_ERROR, - READ_MSG_CMD, - READ_MSG_RESPONSE, -}; - -typedef void (*read_msg_cb_fn)(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data); - -struct read_msg_data { - struct fp_dev *dev; - read_msg_cb_fn callback; - void *user_data; -}; - -static int __read_msg_async(struct read_msg_data *udata); - -#define READ_MSG_DATA_CB_ERR(udata) (udata)->callback((udata)->dev, \ - READ_MSG_ERROR, 0, 0, NULL, 0, (udata)->user_data) - -static void busy_ack_sent_cb(struct libusb_transfer *transfer) -{ - struct read_msg_data *udata = transfer->user_data; - - if (transfer->status != LIBUSB_TRANSFER_COMPLETED || - transfer->length != transfer->actual_length) { - READ_MSG_DATA_CB_ERR(udata); - g_free(udata); - } else { - int r = __read_msg_async(udata); - if (r < 0) { - READ_MSG_DATA_CB_ERR(udata); - g_free(udata); - } - } - libusb_free_transfer(transfer); -} - -static int busy_ack_retry_read(struct read_msg_data *udata) -{ - struct libusb_transfer *transfer; - int r; - - transfer = alloc_send_cmdresponse_transfer(udata->dev, 0x09, NULL, 0, - busy_ack_sent_cb, udata); - if (!transfer) - return -ENOMEM; - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - } - return r; -} - -/* Returns 0 if message was handled, 1 if it was a device-busy message, and - * negative on error. */ -static int __handle_incoming_msg(struct read_msg_data *udata, - unsigned char *buf) -{ - uint16_t len = GUINT16_FROM_LE(((buf[5] & 0xf) << 8) | buf[6]); - uint16_t computed_crc = udf_crc(buf + 4, len + 3); - uint16_t msg_crc = GUINT16_FROM_LE((buf[len + 8] << 8) | buf[len + 7]); - unsigned char *retdata = NULL; - unsigned char code_a, code_b; - - if (computed_crc != msg_crc) { - fp_err("CRC failed, got %04x expected %04x", msg_crc, computed_crc); - return -1; - } - - code_a = buf[4]; - code_b = buf[5] & 0xf0; - len = GUINT16_FROM_LE(((buf[5] & 0xf) << 8) | buf[6]); - fp_dbg("A=%02x B=%02x len=%d", code_a, code_b, len); - - if (code_a && !code_b) { - /* device sends command to driver */ - fp_dbg("cmd %x from device to driver", code_a); - - if (code_a == 0x08) { - int r; - fp_dbg("device busy, send busy-ack"); - r = busy_ack_retry_read(udata); - return (r < 0) ? r : 1; - } - - if (len > 0) { - retdata = g_malloc(len); - memcpy(retdata, buf + 7, len); - } - udata->callback(udata->dev, READ_MSG_CMD, code_a, 0, retdata, len, - udata->user_data); - g_free(retdata); - } else if (!code_a) { - /* device sends response to a previously executed command */ - unsigned char *innerbuf = buf + 7; - unsigned char _subcmd; - uint16_t innerlen; - - if (len < 6) { - fp_err("cmd response too short (%d)", len); - return -1; - } - if (innerbuf[0] != 0x28) { - fp_err("cmd response without 28 byte?"); - return -1; - } - - /* not really sure what these 2 bytes are. on most people's hardware, - * these bytes are always 0. However, Alon Bar-Lev's hardware gives - * 0xfb 0xff during the READ28_OB initsm stage. so don't error out - * if they are different... */ - if (innerbuf[3] || innerbuf[4]) - fp_dbg("non-zero bytes in cmd response"); - - innerlen = innerbuf[1] | (innerbuf[2] << 8); - innerlen = GUINT16_FROM_LE(innerlen) - 3; - _subcmd = innerbuf[5]; - fp_dbg("device responds to subcmd %x with %d bytes", _subcmd, innerlen); - if (innerlen > 0) { - retdata = g_malloc(innerlen); - memcpy(retdata, innerbuf + 6, innerlen); - } - udata->callback(udata->dev, READ_MSG_RESPONSE, code_b, _subcmd, - retdata, innerlen, udata->user_data); - g_free(retdata); - } else { - fp_err("don't know how to handle this message"); - return -1; - } - return 0; -} - -static void read_msg_extend_cb(struct libusb_transfer *transfer) -{ - struct read_msg_data *udata = transfer->user_data; - unsigned char *buf = transfer->buffer - MSG_READ_BUF_SIZE; - int handle_result = 0; - - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - fp_err("extended msg read failed, code %d", transfer->status); - goto err; - } - if (transfer->actual_length < transfer->length) { - fp_err("extended msg short read (%d/%d)", transfer->actual_length, - transfer->length); - goto err; - } - - handle_result = __handle_incoming_msg(udata, buf); - if (handle_result < 0) - goto err; - goto out; - -err: - READ_MSG_DATA_CB_ERR(udata); -out: - if (handle_result != 1) - g_free(udata); - g_free(buf); - libusb_free_transfer(transfer); -} - -static void read_msg_cb(struct libusb_transfer *transfer) -{ - struct read_msg_data *udata = transfer->user_data; - unsigned char *data = transfer->buffer; - uint16_t len; - int handle_result = 0; - - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - fp_err("async msg read failed, code %d", transfer->status); - goto err; - } - if (transfer->actual_length < 9) { - fp_err("async msg read too short (%d)", transfer->actual_length); - goto err; - } - - if (strncmp(data, "Ciao", 4) != 0) { - fp_err("no Ciao for you!!"); - goto err; - } - - len = GUINT16_FROM_LE(((data[5] & 0xf) << 8) | data[6]); - if (transfer->actual_length != MSG_READ_BUF_SIZE - && (len + 9) > transfer->actual_length) { - /* Check that the length claimed inside the message is in line with - * the amount of data that was transferred over USB. */ - fp_err("msg didn't include enough data, expected=%d recv=%d", - len + 9, transfer->actual_length); - goto err; - } - - /* We use a 64 byte buffer for reading messages. However, sometimes - * messages are longer, in which case we have to do another USB bulk read - * to read the remainder. This is handled below. */ - if (len > MAX_DATA_IN_READ_BUF) { - int needed = len - MAX_DATA_IN_READ_BUF; - struct libusb_transfer *etransfer = libusb_alloc_transfer(0); - int r; - - if (!transfer) - goto err; - - fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed); - data = g_realloc((gpointer) data, MSG_READ_BUF_SIZE + needed); - - libusb_fill_bulk_transfer(etransfer, udata->dev->udev, EP_IN, - data + MSG_READ_BUF_SIZE, needed, read_msg_extend_cb, udata, - TIMEOUT); - - r = libusb_submit_transfer(etransfer); - if (r < 0) { - fp_err("extended read submission failed"); - /* FIXME memory leak here? */ - goto err; - } - libusb_free_transfer(transfer); - return; - } - - handle_result = __handle_incoming_msg(udata, data); - if (handle_result < 0) - goto err; - goto out; - -err: - READ_MSG_DATA_CB_ERR(udata); -out: - libusb_free_transfer(transfer); - if (handle_result != 1) - g_free(udata); - g_free(data); -} - -static int __read_msg_async(struct read_msg_data *udata) -{ - unsigned char *buf = g_malloc(MSG_READ_BUF_SIZE); - struct libusb_transfer *transfer = libusb_alloc_transfer(0); - int r; - - if (!transfer) { - g_free(buf); - return -ENOMEM; - } - - libusb_fill_bulk_transfer(transfer, udata->dev->udev, EP_IN, buf, - MSG_READ_BUF_SIZE, read_msg_cb, udata, TIMEOUT); - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(buf); - libusb_free_transfer(transfer); - } - - return r; -} - -static int read_msg_async(struct fp_dev *dev, read_msg_cb_fn callback, - void *user_data) -{ - struct read_msg_data *udata = g_malloc(sizeof(*udata)); - int r; - - udata->dev = dev; - udata->callback = callback; - udata->user_data = user_data; - r = __read_msg_async(udata); - if (r) - g_free(udata); - return r; -} - -static const unsigned char init_resp03[] = { - 0x01, 0x00, 0xbc, 0x02, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char init28_08[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x38, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x05, 0x1f, 0x88, 0x59, 0x2a, 0x09, 0x7e, 0x35, 0x2f, 0x68, 0xc8, 0x10, 0x4f, 0x19, - 0xd6, 0xea, 0xc8, 0xd9, 0x41, 0x73, 0x14, 0x99, 0xa8, 0x77, 0x94, 0xa0, 0x9c, 0xe3, 0x8b, 0x77, - 0xf8, 0x83, 0xdc, 0x14, 0xef, 0x2b, 0x5f, 0xaa, 0xb7, 0x18, 0x3b, 0x7d, 0x11, 0x71, 0xf5, 0x95, - 0x18, 0x6f, 0x40, 0xcd, 0x5d, 0xbd, 0x13, 0x58, 0x15, 0x10, 0x03, 0xdb, 0x96, 0x86, 0xc6, 0x25, - 0xdd, 0x61, 0x7f, 0x54 -}; - -/* device initialisation state machine */ - -enum initsm_states { - WRITE_CTRL400 = 0, - READ_MSG03, - SEND_RESP03, - READ_MSG05, - SEND28_06, - READ28_06, - SEND28_51, - READ28_51, - SEND28_07, - READ28_07, - SEND28_08, - READ28_08, - INITSM_NUM_STATES -}; - -static void initsm_read_msg_response_cb(struct fpi_ssm *ssm, - enum read_msg_status status, uint8_t seq, - unsigned char expect_subcmd, unsigned char subcmd) -{ - struct fp_dev *dev = ssm->dev; - struct upeke2_dev *upekdev = dev->priv; - - if (status != READ_MSG_RESPONSE) { - fp_err("expected response, got %d seq=%x in state %d", status, seq, - ssm->cur_state); - fpi_ssm_mark_aborted(ssm, -1); - } else if (subcmd != expect_subcmd) { - fp_warn("expected response to subcmd 0x%02x, got response to %02x in " - "state %d", expect_subcmd, subcmd, ssm->cur_state); - fpi_ssm_mark_aborted(ssm, -1); - } else if (seq != upekdev->seq) { - fp_err("expected response to cmd seq=%02x, got response to %02x " - "in state %d", upekdev->seq, seq, ssm->cur_state); - fpi_ssm_mark_aborted(ssm, -1); - } else { - fp_dbg("state %d completed", ssm->cur_state); - fpi_ssm_next_state(ssm); - } -} -static void read28_08_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq, - 0x08, subcmd); -} - -static void read28_07_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq, - 0x07, subcmd); -} - -static void read28_51_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq, - 0x51, subcmd); -} - -static void read28_06_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - initsm_read_msg_response_cb((struct fpi_ssm *) user_data, status, seq, - 0x06, subcmd); -} - -static void initsm_read_msg_cmd_cb(struct fpi_ssm *ssm, - enum read_msg_status status, uint8_t expect_seq, uint8_t seq) -{ - struct fp_dev *dev = ssm->dev; - struct upeke2_dev *upekdev = dev->priv; - - if (status == READ_MSG_ERROR) { - fpi_ssm_mark_aborted(ssm, -1); - return; - } else if (status != READ_MSG_CMD) { - fp_err("expected command, got %d seq=%x in state %d", status, seq, - ssm->cur_state); - fpi_ssm_mark_aborted(ssm, -1); - return; - } - upekdev->seq = seq; - if (seq != expect_seq) { - fp_err("expected seq=%x, got %x in state %d", expect_seq, seq, - ssm->cur_state); - fpi_ssm_mark_aborted(ssm, -1); - return; - } - - fpi_ssm_next_state(ssm); -} - -static void read_msg05_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - initsm_read_msg_cmd_cb((struct fpi_ssm *) user_data, status, 5, seq); -} - -static void read_msg03_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - initsm_read_msg_cmd_cb((struct fpi_ssm *) user_data, status, 3, seq); -} - -static void ctrl400_cb(struct libusb_transfer *transfer) -{ - struct fpi_ssm *ssm = transfer->user_data; - /* FIXME check length? */ - if (transfer->status == LIBUSB_TRANSFER_COMPLETED) - fpi_ssm_next_state(ssm); - else - fpi_ssm_mark_aborted(ssm, -1); - g_free(transfer->buffer); - libusb_free_transfer(transfer); -} - -static void initsm_read_msg_handler(struct fpi_ssm *ssm, - read_msg_cb_fn callback) -{ - int r = read_msg_async(ssm->dev, callback, ssm); - if (r < 0) { - fp_err("async read msg failed in state %d", ssm->cur_state); - fpi_ssm_mark_aborted(ssm, r); - } -} - -static void initsm_send_msg_cb(struct libusb_transfer *transfer) -{ - struct fpi_ssm *ssm = transfer->user_data; - if (transfer->status == LIBUSB_TRANSFER_COMPLETED - && transfer->length == transfer->actual_length) { - fp_dbg("state %d completed", ssm->cur_state); - fpi_ssm_next_state(ssm); - } else { - fp_err("failed, state=%d rqlength=%d actual_length=%d", ssm->cur_state, - transfer->length, transfer->actual_length); - fpi_ssm_mark_aborted(ssm, -1); - } - libusb_free_transfer(transfer); -} - -static void initsm_send_msg28_handler(struct fpi_ssm *ssm, - unsigned char subcmd, const unsigned char *data, uint16_t innerlen) -{ - struct fp_dev *dev = ssm->dev; - struct libusb_transfer *transfer; - int r; - - transfer = alloc_send_cmd28_transfer(dev, subcmd, data, innerlen, - initsm_send_msg_cb, ssm); - if (!transfer) { - fpi_ssm_mark_aborted(ssm, -ENOMEM); - return; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - fp_err("urb submission failed error %d in state %d", r, ssm->cur_state); - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_ssm_mark_aborted(ssm, -EIO); - } -} - -static void initsm_run_state(struct fpi_ssm *ssm) -{ - struct fp_dev *dev = ssm->dev; - struct upeke2_dev *upekdev = dev->priv; - struct libusb_transfer *transfer; - int r; - - switch (ssm->cur_state) { - case WRITE_CTRL400: ; - unsigned char *data; - - transfer = libusb_alloc_transfer(0); - if (!transfer) { - fpi_ssm_mark_aborted(ssm, -ENOMEM); - break; - } - - data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1); - libusb_fill_control_setup(data, - LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1); - libusb_fill_control_transfer(transfer, ssm->dev->udev, data, - ctrl400_cb, ssm, TIMEOUT); - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(data); - libusb_free_transfer(transfer); - fpi_ssm_mark_aborted(ssm, r); - } - break; - case READ_MSG03: - initsm_read_msg_handler(ssm, read_msg03_cb); - break; - case SEND_RESP03: ; - transfer = alloc_send_cmdresponse_transfer(dev, ++upekdev->seq, - init_resp03, sizeof(init_resp03), initsm_send_msg_cb, ssm); - if (!transfer) { - fpi_ssm_mark_aborted(ssm, -ENOMEM); - break; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_ssm_mark_aborted(ssm, r); - } - break; - case READ_MSG05: - initsm_read_msg_handler(ssm, read_msg05_cb); - break; - case SEND28_06: ; - unsigned char dummy28_06 = 0x04; - upekdev->seq = 0xf0; - initsm_send_msg28_handler(ssm, 0x06, &dummy28_06, 1); - break; - case READ28_06: - initsm_read_msg_handler(ssm, read28_06_cb); - break; - case SEND28_51: ; - unsigned char dummy28_51[] = { 0x04, 0x0a, 0x00, 0x00, 0x00 }; - initsm_send_msg28_handler(ssm, 0x51, dummy28_51, 5); - break; - case READ28_51: - initsm_read_msg_handler(ssm, read28_51_cb); - break; - case SEND28_07: ; - unsigned char dummy28_07[] = { 0x04, 0x20, 0x00, 0x00, 0x00 }; - initsm_send_msg28_handler(ssm, 0x07, dummy28_07, 5); - break; - case READ28_07: - initsm_read_msg_handler(ssm, read28_07_cb); - break; - case SEND28_08: - initsm_send_msg28_handler(ssm, 0x08, init28_08, sizeof(init28_08)); - break; - case READ28_08: - initsm_read_msg_handler(ssm, read28_08_cb); - break; - } -} - -static struct fpi_ssm *initsm_new(struct fp_dev *dev) -{ - return fpi_ssm_new(dev, initsm_run_state, INITSM_NUM_STATES); -} - -enum deinitsm_states { - SEND_RESP07 = 0, - READ_MSG01, - DEINITSM_NUM_STATES, -}; - -static void send_resp07_cb(struct libusb_transfer *transfer) -{ - struct fpi_ssm *ssm = transfer->user_data; - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) - fpi_ssm_mark_aborted(ssm, -EIO); - else if (transfer->length != transfer->actual_length) - fpi_ssm_mark_aborted(ssm, -EPROTO); - else - fpi_ssm_next_state(ssm); - libusb_free_transfer(transfer); -} - -static void read_msg01_cb(struct fp_dev *dev, enum read_msg_status status, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - struct fpi_ssm *ssm = user_data; - struct upeke2_dev *upekdev = dev->priv; - - if (status == READ_MSG_ERROR) { - fpi_ssm_mark_aborted(ssm, -1); - return; - } else if (status != READ_MSG_CMD) { - fp_err("expected command, got %d seq=%x", status, seq); - fpi_ssm_mark_aborted(ssm, -1); - return; - } - upekdev->seq = seq; - if (seq != 1) { - fp_err("expected seq=1, got %x", seq); - fpi_ssm_mark_aborted(ssm, -1); - return; - } - - fpi_ssm_next_state(ssm); -} - -static void deinitsm_state_handler(struct fpi_ssm *ssm) -{ - struct fp_dev *dev = ssm->dev; - int r; - - switch (ssm->cur_state) { - case SEND_RESP07: ; - struct libusb_transfer *transfer; - unsigned char dummy = 0; - - transfer = alloc_send_cmdresponse_transfer(dev, 0x07, &dummy, 1, - send_resp07_cb, ssm); - if (!transfer) { - fpi_ssm_mark_aborted(ssm, -ENOMEM); - break; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_ssm_mark_aborted(ssm, r); - } - break; - case READ_MSG01: ; - r = read_msg_async(dev, read_msg01_cb, ssm); - if (r < 0) - fpi_ssm_mark_aborted(ssm, r); - break; - } -} - -static struct fpi_ssm *deinitsm_new(struct fp_dev *dev) -{ - return fpi_ssm_new(dev, deinitsm_state_handler, DEINITSM_NUM_STATES); -} - -static int discover(struct libusb_device_descriptor *dsc, uint32_t *devtype) -{ - if (dsc->idProduct == 0x2016 && dsc->bcdDevice == 2) - return 1; - - return 0; -} - -static int dev_init(struct fp_dev *dev, unsigned long driver_data) -{ - struct upeke2_dev *upekdev = NULL; - int r; - - r = libusb_claim_interface(dev->udev, 0); - if (r < 0) { - fp_err("could not claim interface 0: %s", libusb_error_name(r)); - return r; - } - - upekdev = g_malloc(sizeof(*upekdev)); - upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */ - dev->priv = upekdev; - dev->nr_enroll_stages = 5; - - fpi_drvcb_open_complete(dev, 0); - return 0; -} - -static void dev_exit(struct fp_dev *dev) -{ - libusb_release_interface(dev->udev, 0); - g_free(dev->priv); - fpi_drvcb_close_complete(dev); -} - -static const unsigned char enroll_init[] = { - 0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08 -}; -static const unsigned char scan_comp[] = { - 0x12, 0xff, 0xff, 0xff, 0xff /* scan completion, prefixes print data */ -}; - -/* used for enrollment and verification */ -static const unsigned char poll_data[] = { 0x30, 0x01 }; - -enum enroll_start_sm_states { - RUN_INITSM = 0, - ENROLL_INIT, - READ_ENROLL_MSG28, - ENROLL_START_NUM_STATES, -}; - -/* Called when the device initialization state machine completes */ -static void enroll_start_sm_cb_initsm(struct fpi_ssm *initsm) -{ - struct fpi_ssm *enroll_start_ssm = initsm->priv; - int error = initsm->error; - - fpi_ssm_free(initsm); - if (error) - fpi_ssm_mark_aborted(enroll_start_ssm, error); - else - fpi_ssm_next_state(enroll_start_ssm); -} - -/* called when enroll init URB has completed */ -static void enroll_start_sm_cb_init(struct libusb_transfer *transfer) -{ - struct fpi_ssm *ssm = transfer->user_data; - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) - fpi_ssm_mark_aborted(ssm, -EIO); - else if (transfer->length != transfer->actual_length) - fpi_ssm_mark_aborted(ssm, -EPROTO); - else - fpi_ssm_next_state(ssm); - libusb_free_transfer(transfer); -} - -static void enroll_start_sm_cb_msg28(struct fp_dev *dev, - enum read_msg_status status, uint8_t seq, unsigned char subcmd, - unsigned char *data, size_t data_len, void *user_data) -{ - struct upeke2_dev *upekdev = dev->priv; - struct fpi_ssm *ssm = user_data; - - if (status != READ_MSG_RESPONSE) { - fp_err("expected response, got %d seq=%x", status, seq); - fpi_ssm_mark_aborted(ssm, -1); - } else if (subcmd != 0) { - fp_warn("expected response to subcmd 0, got response to %02x", - subcmd); - fpi_ssm_mark_aborted(ssm, -1); - } else if (seq != upekdev->seq) { - fp_err("expected response to cmd seq=%02x, got response to %02x", - upekdev->seq, seq); - fpi_ssm_mark_aborted(ssm, -1); - } else { - fpi_ssm_next_state(ssm); - } -} - -static void enroll_start_sm_run_state(struct fpi_ssm *ssm) -{ - struct fp_dev *dev = ssm->dev; - int r; - - switch (ssm->cur_state) { - case RUN_INITSM: ; - struct fpi_ssm *initsm = initsm_new(dev); - initsm->priv = ssm; - fpi_ssm_start(initsm, enroll_start_sm_cb_initsm); - break; - case ENROLL_INIT: ; - struct libusb_transfer *transfer; - transfer = alloc_send_cmd28_transfer(dev, 0x02, enroll_init, - sizeof(enroll_init), enroll_start_sm_cb_init, ssm); - if (!transfer) { - fpi_ssm_mark_aborted(ssm, -ENOMEM); - break; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_ssm_mark_aborted(ssm, r); - } - break; - case READ_ENROLL_MSG28: ; - /* FIXME: protocol misunderstanding here. device receives response - * to subcmd 0 after submitting subcmd 2? */ - /* actually this is probably a poll response? does the above cmd - * include a 30 01 poll somewhere? */ - r = read_msg_async(dev, enroll_start_sm_cb_msg28, ssm); - //if (r < 0) - //fpi_ssm_mark_aborted(ssm, r); - break; - } -} - -static void enroll_iterate(struct fp_dev *dev); - -static void e_handle_resp00(struct fp_dev *dev, unsigned char *data, - size_t data_len) -{ - - - struct upeke2_dev *upekdev = dev->priv; - unsigned char status; - int result = 0; - - if (data_len != 14) { - fp_err("received 3001 poll response of %d bytes?", data_len); - fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL); - return; - } - - status = data[5]; - fp_dbg("poll result = %02x", status); - - switch (status) { - case 0x0c: - case 0x0d: - case 0x0e: - case 0x26: - case 0x27: - case 0x2e: - /* if we previously completed a non-last enrollment stage, we'll - * get this code to indicate successful stage completion */ - if (upekdev->enroll_passed) { - result = FP_ENROLL_PASS; - upekdev->enroll_passed = FALSE; - } - /* otherwise it just means "no news" so we poll again */ - break; - case 0x1c: /* FIXME what does this one mean? */ - case 0x0b: /* FIXME what does this one mean? */ - case 0x23: /* FIXME what does this one mean? */ - result = FP_ENROLL_RETRY; - break; - case 0x0f: /* scan taking too long, remove finger and try again */ - result = FP_ENROLL_RETRY_REMOVE_FINGER; - break; - case 0x1e: /* swipe too short */ - result = FP_ENROLL_RETRY_TOO_SHORT; - break; - case 0x24: /* finger not centered */ - result = FP_ENROLL_RETRY_CENTER_FINGER; - break; - case 0x20: - /* finger scanned successfully */ - /* need to look at the next poll result to determine if enrollment is - * complete or not */ - upekdev->enroll_passed = 1; - break; - case 0x00: /* enrollment complete */ - /* we can now expect the enrollment data on the next poll, so we - * have nothing to do here */ - break; - default: - fp_err("unrecognised scan status code %02x", status); - result = -EPROTO; - break; - } - - if (result) { - fpi_drvcb_enroll_stage_completed(dev, result, NULL, NULL); - if (result > 0){ - enroll_iterate(dev); - } - } else { - enroll_iterate(dev); - } - - /* FIXME: need to extend protocol research to handle the case when - * enrolment fails, e.g. you scan a different finger on each stage */ - /* FIXME: should do proper tracking of when we expect cmd0 results and - * cmd2 results and enforce it */ -} - -static void e_handle_resp02(struct fp_dev *dev, unsigned char *data, - size_t data_len) -{ - struct fp_print_data *fdata = NULL; - struct fp_print_data_item *item = NULL; - int result = -EPROTO; - - if (data_len < sizeof(scan_comp)) { - fp_err("fingerprint data too short (%d bytes)", data_len); - } else if (memcmp(data, scan_comp, sizeof(scan_comp)) != 0) { - fp_err("unrecognised data prefix %x %x %x %x %x", - data[0], data[1], data[2], data[3], data[4]); - } else { - fdata = fpi_print_data_new(dev); - item = fpi_print_data_item_new(data_len - sizeof(scan_comp)); - memcpy(item->data, data + sizeof(scan_comp), - data_len - sizeof(scan_comp)); - fdata->prints = g_slist_prepend(fdata->prints, item); - - result = FP_ENROLL_COMPLETE; - } - - fpi_drvcb_enroll_stage_completed(dev, result, fdata, NULL); -} - -static void enroll_iterate_msg_cb(struct fp_dev *dev, - enum read_msg_status msgstat, uint8_t seq, unsigned char subcmd, - unsigned char *data, size_t data_len, void *user_data) -{ - if (msgstat != READ_MSG_RESPONSE) { - fp_err("expected response, got %d seq=%x", msgstat, seq); - fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL); - return; - } - if (subcmd == 0) { - e_handle_resp00(dev, data, data_len); - } else if (subcmd == 2) { - e_handle_resp02(dev, data, data_len); - } else { - fp_err("unexpected subcmd %d", subcmd); - fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL); - } - -} - -static void enroll_iterate_cmd_cb(struct libusb_transfer *transfer) -{ - struct fp_dev *dev = transfer->user_data; - - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - fpi_drvcb_enroll_stage_completed(dev, -EIO, NULL, NULL); - } else if (transfer->length != transfer->actual_length) { - fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL); - } else { - int r = read_msg_async(dev, enroll_iterate_msg_cb, NULL); - if (r < 0) - fpi_drvcb_enroll_stage_completed(dev, r, NULL, NULL); - } - libusb_free_transfer(transfer); -} - -static void enroll_iterate(struct fp_dev *dev) -{ - int r; - struct libusb_transfer *transfer = alloc_send_cmd28_transfer(dev, 0x00, - poll_data, sizeof(poll_data), enroll_iterate_cmd_cb, dev); - - if (!transfer) { - fpi_drvcb_enroll_stage_completed(dev, -ENOMEM, NULL, NULL); - return; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_drvcb_enroll_stage_completed(dev, -EIO, NULL, NULL); - } -} - -static void enroll_started(struct fpi_ssm *ssm) -{ - struct fp_dev *dev = ssm->dev; - fpi_drvcb_enroll_started(dev, ssm->error); - - if (!ssm->error) - enroll_iterate(dev); - - fpi_ssm_free(ssm); -} - -static int enroll_start(struct fp_dev *dev) -{ - struct upeke2_dev *upekdev = dev->priv; - - /* do_init state machine first */ - struct fpi_ssm *ssm = fpi_ssm_new(dev, enroll_start_sm_run_state, - ENROLL_START_NUM_STATES); - - upekdev->enroll_passed = FALSE; - fpi_ssm_start(ssm, enroll_started); - return 0; -} - -static void enroll_stop_deinit_cb(struct fpi_ssm *ssm) -{ - /* don't really care about errors */ - fpi_drvcb_enroll_stopped(ssm->dev); - fpi_ssm_free(ssm); -} - -static int enroll_stop(struct fp_dev *dev) -{ - struct fpi_ssm *ssm = deinitsm_new(dev); - fpi_ssm_start(ssm, enroll_stop_deinit_cb); - return 0; -} - -static void verify_stop_deinit_cb(struct fpi_ssm *ssm) -{ - /* don't really care about errors */ - fpi_drvcb_verify_stopped(ssm->dev); - fpi_ssm_free(ssm); -} - -static void do_verify_stop(struct fp_dev *dev) -{ - struct fpi_ssm *ssm = deinitsm_new(dev); - fpi_ssm_start(ssm, verify_stop_deinit_cb); -} - -static const unsigned char verify_hdr[] = { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xd4, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00 -}; - -enum { - VERIFY_RUN_INITSM = 0, - VERIFY_INIT, - VERIFY_NUM_STATES, -}; - -/* Called when the device initialization state machine completes */ -static void verify_start_sm_cb_initsm(struct fpi_ssm *initsm) -{ - struct fpi_ssm *verify_start_ssm = initsm->priv; - if (initsm->error) - fpi_ssm_mark_aborted(verify_start_ssm, initsm->error); - else - fpi_ssm_next_state(verify_start_ssm); - fpi_ssm_free(initsm); -} - -static void verify_init_2803_cb(struct libusb_transfer *transfer) -{ - struct fpi_ssm *ssm = transfer->user_data; - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) - fpi_ssm_mark_aborted(ssm, -EIO); - else if (transfer->length != transfer->actual_length) - fpi_ssm_mark_aborted(ssm, -EPROTO); - else - fpi_ssm_next_state(ssm); - libusb_free_transfer(transfer); -} - -static void verify_start_sm_run_state(struct fpi_ssm *ssm) -{ - struct fp_dev *dev = ssm->dev; - int r; - - switch (ssm->cur_state) { - case VERIFY_RUN_INITSM: ; - struct fpi_ssm *initsm = initsm_new(dev); - initsm->priv = ssm; - fpi_ssm_start(initsm, verify_start_sm_cb_initsm); - break; - case VERIFY_INIT: ; - struct fp_print_data *print = dev->verify_data; - struct fp_print_data_item *item = print->prints->data; - size_t data_len = sizeof(verify_hdr) + item->length; - unsigned char *data = g_malloc(data_len); - struct libusb_transfer *transfer; - - memcpy(data, verify_hdr, sizeof(verify_hdr)); - memcpy(data + sizeof(verify_hdr), item->data, item->length); - transfer = alloc_send_cmd28_transfer(dev, 0x03, data, data_len, - verify_init_2803_cb, ssm); - g_free(data); - if (!transfer) { - fpi_ssm_mark_aborted(ssm, -ENOMEM); - break; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_ssm_mark_aborted(ssm, -EIO); - } - break; - } -} - -static void verify_iterate(struct fp_dev *dev); - -static void v_handle_resp00(struct fp_dev *dev, unsigned char *data, - size_t data_len) -{ - unsigned char status; - int r = 0; - - if (data_len != 14) { - fp_err("received 3001 poll response of %d bytes?", data_len); - r = -EPROTO; - goto out; - } - - status = data[5]; - fp_dbg("poll result = %02x", status); - - /* These codes indicate that we're waiting for a finger scan, so poll - * again */ - switch (status) { - case 0x0c: /* no news, poll again */ - break; - case 0x20: - fp_dbg("processing scan for verification"); - break; - case 0x00: - fp_dbg("good image"); - break; - case 0x1c: /* FIXME what does this one mean? */ - case 0x0b: /* FIXME what does this one mean? */ - case 0x23: /* FIXME what does this one mean? */ - r = FP_VERIFY_RETRY; - break; - case 0x0f: /* scan taking too long, remove finger and try again */ - r = FP_VERIFY_RETRY_REMOVE_FINGER; - break; - case 0x1e: /* swipe too short */ - r = FP_VERIFY_RETRY_TOO_SHORT; - break; - case 0x24: /* finger not centered */ - r = FP_VERIFY_RETRY_CENTER_FINGER; - break; - default: - fp_err("unrecognised verify status code %02x", status); - r = -EPROTO; - } - -out: - if (r) - fpi_drvcb_report_verify_result(dev, r, NULL); - if (r >= 0) - verify_iterate(dev); -} - -static void v_handle_resp03(struct fp_dev *dev, unsigned char *data, - size_t data_len) -{ - int r; - - if (data_len < 2) { - fp_err("verify result abnormally short!"); - r = -EPROTO; - } else if (data[0] != 0x12) { - fp_err("unexpected verify header byte %02x", data[0]); - r = -EPROTO; - } else if (data[1] == 0x00) { - r = FP_VERIFY_NO_MATCH; - } else if (data[1] == 0x01) { - r = FP_VERIFY_MATCH; - } else { - fp_err("unrecognised verify result %02x", data[1]); - r = -EPROTO; - } - fpi_drvcb_report_verify_result(dev, r, NULL); -} - -static void verify_rd2800_cb(struct fp_dev *dev, enum read_msg_status msgstat, - uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, - void *user_data) -{ - struct upeke2_dev *upekdev = dev->priv; - - if (msgstat != READ_MSG_RESPONSE) { - fp_err("expected response, got %d seq=%x", msgstat, seq); - fpi_drvcb_report_verify_result(dev, -EPROTO, NULL); - return; - } else if (seq != upekdev->seq) { - fp_err("expected response to cmd seq=%02x, got response to %02x", - upekdev->seq, seq); - fpi_drvcb_report_verify_result(dev, -EPROTO, NULL); - return; - } - - if (subcmd == 0) - v_handle_resp00(dev, data, data_len); - else if (subcmd == 3) - v_handle_resp03(dev, data, data_len); - else - fpi_drvcb_report_verify_result(dev, -EPROTO, NULL); -} - -static void verify_wr2800_cb(struct libusb_transfer *transfer) -{ - struct fp_dev *dev = transfer->user_data; - - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - fpi_drvcb_report_verify_result(dev, -EIO, NULL); - } else if (transfer->length != transfer->actual_length) { - fpi_drvcb_report_verify_result(dev, -EIO, NULL); - } else { - int r = read_msg_async(dev, verify_rd2800_cb, NULL); - if (r < 0) - fpi_drvcb_report_verify_result(dev, r, NULL); - } - libusb_free_transfer(transfer); -} - -static void verify_iterate(struct fp_dev *dev) -{ - struct upeke2_dev *upekdev = dev->priv; - - if (upekdev->stop_verify) { - do_verify_stop(dev); - return; - } - - /* FIXME: this doesn't flow well, should the first cmd be moved from - * verify init to here? */ - if (upekdev->first_verify_iteration) { - int r = read_msg_async(dev, verify_rd2800_cb, NULL); - upekdev->first_verify_iteration = FALSE; - if (r < 0) - fpi_drvcb_report_verify_result(dev, r, NULL); - } else { - int r; - struct libusb_transfer *transfer = alloc_send_cmd28_transfer(dev, - 0x00, poll_data, sizeof(poll_data), verify_wr2800_cb, dev); - - if (!transfer) { - fpi_drvcb_report_verify_result(dev, -ENOMEM, NULL); - return; - } - - r = libusb_submit_transfer(transfer); - if (r < 0) { - g_free(transfer->buffer); - libusb_free_transfer(transfer); - fpi_drvcb_report_verify_result(dev, -EIO, NULL); - } - } -} - -static void verify_started(struct fpi_ssm *ssm) -{ - struct fp_dev *dev = ssm->dev; - struct upeke2_dev *upekdev = dev->priv; - - fpi_drvcb_verify_started(dev, ssm->error); - if (!ssm->error) { - upekdev->first_verify_iteration = TRUE; - verify_iterate(dev); - } - - fpi_ssm_free(ssm); -} - -static int verify_start(struct fp_dev *dev) -{ - struct upeke2_dev *upekdev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev, verify_start_sm_run_state, - VERIFY_NUM_STATES); - upekdev->stop_verify = FALSE; - fpi_ssm_start(ssm, verify_started); - return 0; -} - -static int verify_stop(struct fp_dev *dev, gboolean iterating) -{ - struct upeke2_dev *upekdev = dev->priv; - - if (!iterating) - do_verify_stop(dev); - else - upekdev->stop_verify = TRUE; - return 0; -} - -static const struct usb_id id_table[] = { - { .vendor = 0x147e, .product = 0x2016, .driver_data = UPEKE2_2016 }, - { 0, 0, 0, }, /* terminating entry */ -}; - -struct fp_driver upeke2_driver = { - .id = UPEKE2_ID, - .name = FP_COMPONENT, - .full_name = "UPEK Eikon 2", - .id_table = id_table, - .scan_type = FP_SCAN_TYPE_SWIPE, - .discover = discover, - .open = dev_init, - .close = dev_exit, - .enroll_start = enroll_start, - .enroll_stop = enroll_stop, - .verify_start = verify_start, - .verify_stop = verify_stop, -}; - diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 18e271b6..622b73e8 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -671,18 +671,14 @@ static int discover(struct libusb_device_descriptor *dsc, uint32_t *devtype) { if (dsc->idProduct == 0x2020 && dsc->bcdDevice == 1) return 1; -#ifndef ENABLE_UPEKE2 if (dsc->idProduct == 0x2016 && dsc->bcdDevice == 2) return 1; -#endif return 0; } static const struct usb_id id_table[] = { -#ifndef ENABLE_UPEKE2 { .vendor = 0x147e, .product = 0x2016 }, -#endif { .vendor = 0x147e, .product = 0x2020 }, { 0, 0, 0, }, }; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 7897a2e9..68bf7a34 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -251,9 +251,6 @@ struct fp_img_driver { #ifdef ENABLE_UPEKTS extern struct fp_driver upekts_driver; #endif -#ifdef ENABLE_UPEKE2 -extern struct fp_driver upeke2_driver; -#endif #ifdef ENABLE_UPEKTC extern struct fp_img_driver upektc_driver; #endif From dac153d24a4e28ec0c2f605f96e3631e9793a068 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 14 May 2018 15:15:52 +0200 Subject: [PATCH 054/141] build: Port to meson And remove the autotools. Faster, cleaner. https://bugs.freedesktop.org/show_bug.cgi?id=106514 --- Makefile.am | 25 -- autogen.sh | 20 -- configure.ac | 435 ---------------------------- doc/Makefile.am | 10 - doc/{doxygen.cfg => doxygen.cfg.in} | 4 +- doc/meson.build | 17 ++ examples/Makefile.am | 26 -- examples/meson.build | 29 ++ libfprint.pc.in | 11 - libfprint/Makefile.am | 227 --------------- libfprint/meson.build | 194 +++++++++++++ meson.build | 117 ++++++++ meson_options.txt | 24 ++ 13 files changed, 383 insertions(+), 756 deletions(-) delete mode 100644 Makefile.am delete mode 100755 autogen.sh delete mode 100644 configure.ac delete mode 100644 doc/Makefile.am rename doc/{doxygen.cfg => doxygen.cfg.in} (99%) create mode 100644 doc/meson.build delete mode 100644 examples/Makefile.am create mode 100644 examples/meson.build delete mode 100644 libfprint.pc.in delete mode 100644 libfprint/Makefile.am create mode 100644 libfprint/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 74f0971d..00000000 --- a/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = THANKS TODO HACKING libfprint.pc.in -DISTCLEANFILES = ChangeLog libfprint.pc - -SUBDIRS = libfprint doc - -if BUILD_EXAMPLES -SUBDIRS += examples -endif - -DIST_SUBDIRS = libfprint doc examples - -DISTCHECK_CONFIGURE_FLAGS = --with-drivers=all --enable-examples-build --enable-x11-examples-build --with-udev-rules-dir='$${libdir}/udev/rules.d-distcheck' - -pkgconfigdir=$(libdir)/pkgconfig -pkgconfig_DATA=libfprint.pc - -.PHONY: ChangeLog dist-up -ChangeLog: - git --git-dir $(top_srcdir)/.git log > ChangeLog || touch ChangeLog - -dist-hook: ChangeLog - -dist-up: dist - rsync $(distdir).tar.bz2 frs.sourceforge.net:uploads/ diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index cd72a669..00000000 --- a/autogen.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -srcdir=`dirname $0` -test -z "$srcdir" && srcdir=. - -olddir="`pwd`" - -cd "$srcdir" - -libtoolize --copy --force || exit 1 -aclocal || exit 1 -autoheader || exit 1 -autoconf || exit 1 -automake -a -c || exit 1 -cd "$olddir" - -if test -z "$NOCONFIGURE"; then - $srcdir/configure --enable-maintainer-mode --enable-examples-build \ - --enable-x11-examples-build --enable-debug-log $* -fi diff --git a/configure.ac b/configure.ac deleted file mode 100644 index d8b21192..00000000 --- a/configure.ac +++ /dev/null @@ -1,435 +0,0 @@ -AC_INIT([libfprint], [0.7.0]) -AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz check-news subdir-objects]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_SRCDIR([libfprint/core.c]) -AC_CONFIG_HEADERS([config.h]) - -# Enable silent build when available (Automake 1.11) -m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) - -AC_PREREQ([2.50]) -AC_PROG_CC -AC_PROG_LIBTOOL -AC_C_INLINE -AM_PROG_CC_C_O -AC_PROG_CXX -AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions]) - -# Library versioning -lt_major="0" -lt_revision="0" -lt_age="0" -AC_SUBST(lt_major) -AC_SUBST(lt_revision) -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 elan" - -require_imaging='no' -require_aeslib='no' -require_aesX660='no' -require_aes3k='no' -require_nss='no' -enable_upekts='no' -enable_upektc='no' -enable_upeksonly='no' -enable_vcom5s='no' -enable_uru4000='no' -enable_fdu2000='no' -enable_aes1610='no' -enable_aes1660='no' -enable_aes2501='no' -enable_aes2550='no' -enable_aes2660='no' -enable_aes3500='no' -enable_aes4000='no' -enable_vfs101='no' -enable_vfs301='no' -enable_vfs5011='no' -enable_upektc_img='no' -enable_etes603='no' -enable_vfs0050='no' -enable_elan='no' - -AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], - [List of drivers to enable])], - [drivers="$withval"], - [drivers="$all_drivers"]) - -if test "x$drivers" = "xall" ; then - drivers=$all_drivers -fi - -for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do - case ${driver} in - upekts) - AC_DEFINE([ENABLE_UPEKTS], [], [Build UPEK TouchStrip driver]) - enable_upekts="yes" - ;; - upektc) - AC_DEFINE([ENABLE_UPEKTC], [], [Build UPEK TouchChip driver]) - enable_upektc="yes" - ;; - upeksonly) - AC_DEFINE([ENABLE_UPEKSONLY], [], [Build UPEK TouchStrip sensor-only driver]) - enable_upeksonly="yes" - ;; - uru4000) - AC_DEFINE([ENABLE_URU4000], [], [Build Digital Persona U.are.U 4000 driver]) - enable_uru4000="yes" - require_nss="yes" - ;; - fdu2000) - AC_DEFINE([ENABLE_FDU2000], [], [Build Secugen FDU 2000 driver]) - enable_fdu2000="no" - # Driver not ported - ;; - vcom5s) - AC_DEFINE([ENABLE_VCOM5S], [], [Build Veridicom 5thSense driver]) - enable_vcom5s="yes" - ;; - aes2501) - AC_DEFINE([ENABLE_AES2501], [], [Build AuthenTec AES2501 driver]) - require_aeslib="yes" - enable_aes2501="yes" - ;; - aes2550) - AC_DEFINE([ENABLE_AES2550], [], [Build AuthenTec AES2550/AES2810 driver]) - require_aeslib="yes" - enable_aes2550="yes" - ;; - aes1610) - AC_DEFINE([ENABLE_AES1610], [], [Build AuthenTec AES1610 driver]) - require_aeslib="yes" - enable_aes1610="yes" - ;; - aes1660) - AC_DEFINE([ENABLE_AES1660], [], [Build AuthenTec AES1660 driver]) - require_aeslib="yes" - require_aesX660="yes" - enable_aes1660="yes" - ;; - aes2660) - AC_DEFINE([ENABLE_AES2660], [], [Build AuthenTec AES1660 driver]) - require_aeslib="yes" - require_aesX660="yes" - enable_aes2660="yes" - ;; - aes3500) - AC_DEFINE([ENABLE_AES3500], [], [Build AuthenTec AES3500 driver]) - require_aeslib="yes" - require_imaging="yes" - require_aes3k="yes" - enable_aes3500="yes" - ;; - aes4000) - AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver]) - require_aeslib="yes" - require_imaging="yes" - require_aes3k="yes" - enable_aes4000="yes" - ;; - vfs101) - AC_DEFINE([ENABLE_VFS101], [], [Build Validity VFS101 driver]) - enable_vfs101="yes" - ;; - vfs301) - AC_DEFINE([ENABLE_VFS301], [], [Build Validity VFS301/VFS300 driver]) - enable_vfs301="yes" - ;; - vfs5011) - AC_DEFINE([ENABLE_VFS5011], [], [Build Validity VFS5011 driver]) - enable_vfs5011="yes" - ;; - upektc_img) - AC_DEFINE([ENABLE_UPEKTC_IMG], [], [Build Upek TouchChip Fingerprint Coprocessor driver]) - enable_upektc_img="yes" - ;; - etes603) - AC_DEFINE([ENABLE_ETES603], [], [Build EgisTec ES603 driver]) - enable_etes603="yes" - ;; - vfs0050) - AC_DEFINE([ENABLE_VFS0050], [], [Build Validity VFS0050 driver]) - enable_vfs0050="yes" - ;; - elan) - AC_DEFINE([ENABLE_ELAN], [], [Build Elan driver]) - enable_elan="yes" - ;; - esac -done - -AM_CONDITIONAL([ENABLE_UPEKTS], [test "$enable_upekts" = "yes"]) -AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" = "yes"]) -AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" = "yes"]) -AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" = "yes"]) -AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" = "yes"]) -AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" = "yes"]) -AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" = "yes"]) -AM_CONDITIONAL([ENABLE_AES1660], [test "$enable_aes1660" = "yes"]) -AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" = "yes"]) -AM_CONDITIONAL([ENABLE_AES2550], [test "$enable_aes2550" = "yes"]) -AM_CONDITIONAL([ENABLE_AES2660], [test "$enable_aes2660" = "yes"]) -AM_CONDITIONAL([ENABLE_AES3500], [test "$enable_aes3500" = "yes"]) -AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" = "yes"]) -AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" = "yes"]) -AM_CONDITIONAL([REQUIRE_AESX660], [test "$require_aesX660" = "yes"]) -AM_CONDITIONAL([REQUIRE_AES3K], [test "$require_aes3k" = "yes"]) -AM_CONDITIONAL([ENABLE_VFS101], [test "$enable_vfs101" = "yes"]) -AM_CONDITIONAL([ENABLE_VFS301], [test "$enable_vfs301" = "yes"]) -AM_CONDITIONAL([ENABLE_VFS5011], [test "$enable_vfs5011" = "yes"]) -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"]) -AM_CONDITIONAL([ENABLE_ELAN], [test "$enable_elan" = "yes"]) - - -PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) -AC_SUBST(LIBUSB_CFLAGS) -AC_SUBST(LIBUSB_LIBS) - -if test "$require_nss" = "yes"; then - # check for NSS - PKG_CHECK_MODULES(CRYPTO, nss, [nss_found=yes], [nss_found=no]) - if test "$nss_found" != "yes"; then - AC_MSG_ERROR([NSS is required for the URU4000/URU4500 driver]) - fi -fi -AC_SUBST(CRYPTO_CFLAGS) -AC_SUBST(CRYPTO_LIBS) - -PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.28]) -AC_SUBST(GLIB_CFLAGS) -AC_SUBST(GLIB_LIBS) - -pixman_found=no - -AC_ARG_ENABLE(udev-rules, - AC_HELP_STRING([--enable-udev-rules],[Update the udev rules]), - [case "${enableval}" in - yes) ENABLE_UDEV_RULES=yes ;; - no) ENABLE_UDEV_RULES=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-udev-rules) ;; - esac], - [ENABLE_UDEV_RULES=yes]) dnl Default value -AM_CONDITIONAL(ENABLE_UDEV_RULES, test x$ENABLE_UDEV_RULES = "xyes") - -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], - [ac_with_udev_rules_dir=""]) - -if test "${ac_with_udev_rules_dir}" = ""; then - ac_with_udev_rules_dir=`$PKG_CONFIG --variable=udevdir udev`/rules.d -fi -AC_MSG_NOTICE([installing udev rules in ${ac_with_udev_rules_dir}]) -AC_SUBST([udev_rulesdir],[${ac_with_udev_rules_dir}]) - -if test "$require_imaging" = "yes"; then - PKG_CHECK_MODULES(IMAGING, pixman-1, [pixman_found=yes], [pixman_found=no]) - if test "$pixman_found" != "yes"; then - AC_MSG_ERROR([pixman is required for imaging support]) - fi -fi - -AM_CONDITIONAL([REQUIRE_PIXMAN], [test "$pixman_found" = "yes"]) -AC_SUBST(IMAGING_CFLAGS) -AC_SUBST(IMAGING_LIBS) - -# Examples build -AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build], - [build example applications (default n)])], - [build_examples=$enableval], - [build_examples='no']) -AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"]) - -# Examples build -AC_ARG_ENABLE([x11-examples-build], [AS_HELP_STRING([--enable-x11-examples-build], - [build X11 example applications (default n)])], - [build_x11_examples=$enableval], - [build_x11_examples='no']) -AM_CONDITIONAL([BUILD_X11_EXAMPLES], [test "x$build_x11_examples" != "xno"]) - - -if test "x$build_x11_examples" != "xno"; then - # check for Xv extensions - # imported from Coriander - AC_DEFUN([AC_CHECK_XV],[ - AC_SUBST(XV_CFLAGS) - AC_SUBST(XV_LIBS) - AC_MSG_CHECKING(for Xv extensions) - AC_TRY_COMPILE([ - #include - #include ],[ - int main(void) { (void) XvGetPortAttribute(0, 0, 0, 0); return 0; } - ],xv=yes,xv=no); - AC_MSG_RESULT($xv) - if test x$xv = xyes; then - XV_LIBS="-lXv -lXext" - XV_CFLAGS="" - AC_DEFINE(HAVE_XV,1,[defined if XV video overlay is available]) - else - AC_MSG_ERROR([XV is required for X11 examples]) - fi - ]) - AC_CHECK_XV -fi - -# Message logging -AC_ARG_ENABLE([log], [AS_HELP_STRING([--disable-log], [disable all logging])], - [log_enabled=$enableval], - [log_enabled='yes']) -if test "x$log_enabled" != "xno"; then - AC_DEFINE([ENABLE_LOGGING], 1, [Message logging]) -fi - -AC_ARG_ENABLE([debug-log], [AS_HELP_STRING([--enable-debug-log], - [enable debug logging (default n)])], - [debug_log_enabled=$enableval], - [debug_log_enabled='no']) -if test "x$debug_log_enabled" != "xno"; then - AC_DEFINE([ENABLE_DEBUG_LOGGING], 1, [Debug message logging]) -fi - -# Restore gnu89 inline semantics on gcc 4.3 and newer -saved_cflags="$CFLAGS" -CFLAGS="$CFLAGS -fgnu89-inline" -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])], inline_cflags="-fgnu89-inline", inline_cflags="") -CFLAGS="$saved_cflags" - -AC_DEFINE([API_EXPORTED], [__attribute__((visibility("default")))], [Default visibility]) -AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow" -AC_SUBST(AM_CFLAGS) - -if test "$require_imaging" = "yes"; then - if test x$pixman_found != no; then - AC_MSG_NOTICE([** Using pixman for imaging]) - fi -else - AC_MSG_NOTICE([ Imaging support disabled]) -fi - -if test x$enable_upekts != xno ; then - AC_MSG_NOTICE([** upekts driver enabled]) -else - AC_MSG_NOTICE([ upekts driver disabled]) -fi -if test x$enable_upektc != xno ; then - AC_MSG_NOTICE([** upektc driver enabled]) -else - AC_MSG_NOTICE([ upektc driver disabled]) -fi -if test x$enable_upeksonly != xno ; then - AC_MSG_NOTICE([** upeksonly driver enabled]) -else - AC_MSG_NOTICE([ upeksonly driver disabled]) -fi -if test x$enable_vcom5s != xno ; then - AC_MSG_NOTICE([** vcom5s driver enabled]) -else - AC_MSG_NOTICE([ vcom5s driver disabled]) -fi -if test x$enable_uru4000 != xno ; then - AC_MSG_NOTICE([** uru4000 driver enabled]) -else - AC_MSG_NOTICE([ uru4000 driver disabled]) -fi -if test x$enable_fdu2000 != xno ; then - AC_MSG_NOTICE([** fdu2000 driver enabled]) -else - AC_MSG_NOTICE([ fdu2000 driver disabled (not ported)]) -fi -if test x$enable_aes1610 != xno ; then - AC_MSG_NOTICE([** aes1610 driver enabled]) -else - AC_MSG_NOTICE([ aes1610 driver disabled]) -fi -if test x$enable_aes1660 != xno ; then - AC_MSG_NOTICE([** aes1660 driver enabled]) -else - AC_MSG_NOTICE([ aes1660 driver disabled]) -fi -if test x$enable_aes2501 != xno ; then - AC_MSG_NOTICE([** aes2501 driver enabled]) -else - AC_MSG_NOTICE([ aes2501 driver disabled]) -fi -if test x$enable_aes2550 != xno ; then - AC_MSG_NOTICE([** aes2550/aes2810 driver enabled]) -else - AC_MSG_NOTICE([ aes2550/aes2810 driver disabled]) -fi -if test x$enable_aes2660 != xno ; then - AC_MSG_NOTICE([** aes2660 driver enabled]) -else - AC_MSG_NOTICE([ aes2660 driver disabled]) -fi -if test x$enable_aes3500 != xno ; then - AC_MSG_NOTICE([** aes3500 driver enabled]) -else - AC_MSG_NOTICE([ aes3500 driver disabled]) -fi -if test x$enable_aes4000 != xno ; then - AC_MSG_NOTICE([** aes4000 driver enabled]) -else - AC_MSG_NOTICE([ aes4000 driver disabled]) -fi -if test x$enable_vfs101 != xno ; then - AC_MSG_NOTICE([** vfs101 driver enabled]) -else - AC_MSG_NOTICE([ vfs101 driver disabled]) -fi -if test x$enable_vfs301 != xno ; then - AC_MSG_NOTICE([** vfs301 driver enabled]) -else - AC_MSG_NOTICE([ vfs301 driver disabled]) -fi -if test x$enable_vfs5011 != xno ; then - AC_MSG_NOTICE([** vfs5011 driver enabled]) -else - AC_MSG_NOTICE([ vfs5011 driver disabled]) -fi -if test x$enable_upektc_img != xno ; then - AC_MSG_NOTICE([** upektc_img driver enabled]) -else - AC_MSG_NOTICE([ upektc_img driver disabled]) -fi -if test x$enable_etes603 != xno ; then - AC_MSG_NOTICE([** etes603 driver enabled]) -else - AC_MSG_NOTICE([ etes603 driver disabled]) -fi -if test x$enable_vfs0050 != xno ; then - AC_MSG_NOTICE([** vfs0050 driver enabled]) -else - AC_MSG_NOTICE([ vfs0050 driver disabled]) -fi -if test x$enable_elan != xno ; then - AC_MSG_NOTICE([** elan driver enabled]) -else - AC_MSG_NOTICE([ elan driver disabled]) -fi -if test x$require_aeslib != xno ; then - AC_MSG_NOTICE([** aeslib helper functions enabled]) -else - AC_MSG_NOTICE([ aeslib helper functions disabled]) -fi -if test x$require_aesX660 != xno ; then - AC_MSG_NOTICE([** aesX660 common routines enabled]) -else - AC_MSG_NOTICE([ aesX660 common routines disabled]) -fi -if test x$require_aes3k != xno ; then - AC_MSG_NOTICE([** aes3k common routines enabled]) -else - AC_MSG_NOTICE([ aes3k common routines disabled]) -fi - -AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] [examples/Makefile] [doc/Makefile]) -AC_OUTPUT - diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index 7f200a0b..00000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -EXTRA_DIST = doxygen.cfg - -docs: doxygen.cfg - doxygen $^ - -docs-upload: docs - ln -s html api - ncftpput -f ~/.ncftp/reactivated -m -R httpdocs/fprint api/ - rm -f api - diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg.in similarity index 99% rename from doc/doxygen.cfg rename to doc/doxygen.cfg.in index 3548e662..da7bf494 100644 --- a/doc/doxygen.cfg +++ b/doc/doxygen.cfg.in @@ -477,7 +477,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../libfprint +INPUT = "@SRCDIR@" # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default @@ -672,7 +672,7 @@ GENERATE_HTML = YES # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. -HTML_OUTPUT = html +HTML_OUTPUT = "@BUILDDIR@/html" # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 00000000..717efac7 --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,17 @@ +cdata = configuration_data() +cdata.set('SRCDIR', join_paths(meson.source_root(), 'libfprint')) +cdata.set('BUILDDIR', join_paths(meson.build_root(), 'doc')) + +cfg = configure_file(input: 'doxygen.cfg.in', + output: 'doxygen.cfg', + configuration: cdata, + install: false) + +doxygen = find_program('doxygen') +datadir = join_paths(get_option('datadir'), 'doc', 'libfprint-devel') +custom_target('docs', + input: cfg, + output: 'html', + command: [ doxygen, '@INPUT@' ], + install: true, + install_dir: datadir) diff --git a/examples/Makefile.am b/examples/Makefile.am deleted file mode 100644 index 8aa486c5..00000000 --- a/examples/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -AM_CFLAGS = -I$(top_srcdir) -noinst_PROGRAMS = verify_live enroll verify img_capture cpp-test - -verify_live_SOURCES = verify_live.c -verify_live_LDADD = ../libfprint/libfprint.la - -enroll_SOURCES = enroll.c -enroll_LDADD = ../libfprint/libfprint.la - -verify_SOURCES = verify.c -verify_LDADD = ../libfprint/libfprint.la - -img_capture_SOURCES = img_capture.c -img_capture_LDADD = ../libfprint/libfprint.la - -cpp_test_SOURCES = cpp-test.cpp -cpp_test_LDADD = ../libfprint/libfprint.la - -if BUILD_X11_EXAMPLES -noinst_PROGRAMS += img_capture_continuous - -img_capture_continuous_CFLAGS = $(X_CFLAGS) $(XV_CFLAGS) -img_capture_continuous_SOURCES = img_capture_continuous.c -img_capture_continuous_LDADD = ../libfprint/libfprint.la $(X_LIBS) $(X_PRE_LIBS) $(XV_LIBS) -lX11 $(X_EXTRA_LIBS); -endif - diff --git a/examples/meson.build b/examples/meson.build new file mode 100644 index 00000000..cba326fb --- /dev/null +++ b/examples/meson.build @@ -0,0 +1,29 @@ + +examples = [ 'verify_live', 'enroll', 'verify', 'img_capture' ] +foreach example: examples + executable(example, + example + '.c', + dependencies: libfprint_dep, + include_directories: [ + root_inc, + ], + c_args: common_cflags) +endforeach + +executable('cpp-test', + 'cpp-test.cpp', + dependencies: libfprint_dep, + include_directories: [ + root_inc, + ], + c_args: common_cflags) + +if get_option('x11-examples') + executable('img_capture_continuous', + 'img_capture_continuous.c', + dependencies: [ libfprint_dep, xv_dep, x11_dep ], + include_directories: [ + root_inc, + ], + c_args: common_cflags) +endif diff --git a/libfprint.pc.in b/libfprint.pc.in deleted file mode 100644 index 30687d13..00000000 --- a/libfprint.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libfprint -Description: Generic C API for fingerprint reader access -Version: @VERSION@ -Libs: -L${libdir} -lfprint -Cflags: -I${includedir}/libfprint - diff --git a/libfprint/Makefile.am b/libfprint/Makefile.am deleted file mode 100644 index 29ecd40b..00000000 --- a/libfprint/Makefile.am +++ /dev/null @@ -1,227 +0,0 @@ -lib_LTLIBRARIES = libfprint.la -noinst_PROGRAMS = fprint-list-udev-rules -MOSTLYCLEANFILES = $(udev_rules_DATA) - -UPEKTS_SRC = drivers/upekts.c -UPEKTC_SRC = drivers/upektc.c drivers/upektc.h -UPEKSONLY_SRC = drivers/upeksonly.c drivers/upeksonly.h -URU4000_SRC = drivers/uru4000.c -AES1610_SRC = drivers/aes1610.c -AES1660_SRC = drivers/aes1660.c drivers/aes1660.h -AES2501_SRC = drivers/aes2501.c drivers/aes2501.h -AES2550_SRC = drivers/aes2550.c drivers/aes2550.h -AES2660_SRC = drivers/aes2660.c drivers/aes2660.h -AES3500_SRC = drivers/aes3500.c -AES4000_SRC = drivers/aes4000.c -FDU2000_SRC = drivers/fdu2000.c -VCOM5S_SRC = drivers/vcom5s.c -VFS101_SRC = drivers/vfs101.c -VFS301_SRC = drivers/vfs301.c drivers/vfs301_proto.c drivers/vfs301_proto.h drivers/vfs301_proto_fragments.h -VFS5011_SRC = drivers/vfs5011.c drivers/vfs5011_proto.h -UPEKTC_IMG_SRC = drivers/upektc_img.c drivers/upektc_img.h -ETES603_SRC = drivers/etes603.c -VFS0050_SRC = drivers/vfs0050.c drivers/vfs0050.h -ELAN_SRC = drivers/elan.c drivers/elan.h - -EXTRA_DIST = \ - $(UPEKTS_SRC) \ - $(UPEKTC_SRC) \ - $(UPEKSONLY_SRC) \ - $(URU4000_SRC) \ - $(AES1610_SRC) \ - $(AES1660_SRC) \ - $(AES2501_SRC) \ - $(AES2550_SRC) \ - $(AES2660_SRC) \ - $(AES3500_SRC) \ - $(AES4000_SRC) \ - $(FDU2000_SRC) \ - $(VCOM5S_SRC) \ - $(VFS101_SRC) \ - $(VFS301_SRC) \ - $(VFS5011_SRC) \ - $(UPEKTC_IMG_SRC) \ - $(ETES603_SRC) \ - $(VFS0050_SRC) \ - $(ELAN_SRC) \ - drivers/aesx660.c \ - drivers/aesx660.h \ - drivers/aes3k.c \ - drivers/aes3k.h \ - drivers/driver_ids.h \ - aeslib.c aeslib.h \ - assembling.c \ - assembling.h \ - pixman.c \ - 60-fprint-autosuspend.rules - -DRIVER_SRC = -OTHER_SRC = - -NBIS_SRC = \ - 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 \ - nbis/bozorth3/bz_gbls.c \ - nbis/bozorth3/bz_io.c \ - nbis/bozorth3/bz_sort.c \ - nbis/mindtct/binar.c \ - nbis/mindtct/block.c \ - nbis/mindtct/contour.c \ - nbis/mindtct/detect.c \ - nbis/mindtct/dft.c \ - nbis/mindtct/free.c \ - nbis/mindtct/globals.c \ - nbis/mindtct/imgutil.c \ - nbis/mindtct/init.c \ - nbis/mindtct/line.c \ - nbis/mindtct/log.c \ - nbis/mindtct/loop.c \ - nbis/mindtct/maps.c \ - nbis/mindtct/matchpat.c \ - nbis/mindtct/minutia.c \ - nbis/mindtct/morph.c \ - nbis/mindtct/quality.c \ - nbis/mindtct/remove.c \ - nbis/mindtct/ridges.c \ - nbis/mindtct/shape.c \ - nbis/mindtct/sort.c \ - nbis/mindtct/util.c - -libfprint_la_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS) -libfprint_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ -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) $(CRYPTO_CFLAGS) $(AM_CFLAGS) -fprint_list_udev_rules_LDADD = $(builddir)/libfprint.la $(GLIB_LIBS) - -udev_rules_DATA = 60-fprint-autosuspend.rules - -if ENABLE_UDEV_RULES -$(udev_rules_DATA): fprint-list-udev-rules - $(builddir)/fprint-list-udev-rules > $@ -endif - -if ENABLE_UPEKTS -DRIVER_SRC += $(UPEKTS_SRC) -endif - -if ENABLE_UPEKSONLY -DRIVER_SRC += $(UPEKSONLY_SRC) -endif - -if ENABLE_UPEKTC -DRIVER_SRC += $(UPEKTC_SRC) -endif - -if ENABLE_URU4000 -DRIVER_SRC += $(URU4000_SRC) -endif - -if ENABLE_VCOM5S -DRIVER_SRC += $(VCOM5S_SRC) -endif - -#if ENABLE_FDU2000 -#DRIVER_SRC += $(FDU2000_SRC) -#endif - -if ENABLE_AES1610 -DRIVER_SRC += $(AES1610_SRC) -endif - -if ENABLE_AES1660 -DRIVER_SRC += $(AES1660_SRC) -endif - -if ENABLE_AES2501 -DRIVER_SRC += $(AES2501_SRC) -endif - -if ENABLE_AES2550 -DRIVER_SRC += $(AES2550_SRC) -endif - -if ENABLE_AES2660 -DRIVER_SRC += $(AES2660_SRC) -endif - -if ENABLE_AES3500 -DRIVER_SRC += $(AES3500_SRC) -endif - -if ENABLE_AES4000 -DRIVER_SRC += $(AES4000_SRC) -endif - -if ENABLE_VFS101 -DRIVER_SRC += $(VFS101_SRC) -endif - -if ENABLE_VFS301 -DRIVER_SRC += $(VFS301_SRC) -endif - -if ENABLE_VFS5011 -DRIVER_SRC += $(VFS5011_SRC) -endif - -if ENABLE_UPEKTC_IMG -DRIVER_SRC += $(UPEKTC_IMG_SRC) -endif - -if ENABLE_ETES603 -DRIVER_SRC += $(ETES603_SRC) -endif - -if ENABLE_VFS0050 -DRIVER_SRC += $(VFS0050_SRC) -endif - -if ENABLE_ELAN -DRIVER_SRC += $(ELAN_SRC) -endif - -if REQUIRE_PIXMAN -OTHER_SRC += pixman.c -libfprint_la_CFLAGS += $(IMAGING_CFLAGS) -libfprint_la_LIBADD += $(IMAGING_LIBS) -endif - -if REQUIRE_AESLIB -OTHER_SRC += aeslib.c aeslib.h -endif - -if REQUIRE_AESX660 -OTHER_SRC += drivers/aesx660.c drivers/aesx660.h -endif - -if REQUIRE_AES3K -OTHER_SRC += drivers/aes3k.c drivers/aes3k.h -endif - -libfprint_la_SOURCES = \ - fp_internal.h \ - async.c \ - core.c \ - data.c \ - drv.c \ - img.c \ - imgdev.c \ - poll.c \ - sync.c \ - assembling.c \ - assembling.h \ - $(DRIVER_SRC) \ - $(OTHER_SRC) \ - $(NBIS_SRC) - -pkginclude_HEADERS = fprint.h diff --git a/libfprint/meson.build b/libfprint/meson.build new file mode 100644 index 00000000..6bb919f2 --- /dev/null +++ b/libfprint/meson.build @@ -0,0 +1,194 @@ +libfprint_sources = [ + 'fp_internal.h', + 'async.c', + 'core.c', + 'data.c', + 'drv.c', + 'img.c', + 'imgdev.c', + 'poll.c', + 'sync.c', + 'assembling.c', + 'assembling.h', + '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', + 'nbis/bozorth3/bz_gbls.c', + 'nbis/bozorth3/bz_io.c', + 'nbis/bozorth3/bz_sort.c', + 'nbis/mindtct/binar.c', + 'nbis/mindtct/block.c', + 'nbis/mindtct/contour.c', + 'nbis/mindtct/detect.c', + 'nbis/mindtct/dft.c', + 'nbis/mindtct/free.c', + 'nbis/mindtct/globals.c', + 'nbis/mindtct/imgutil.c', + 'nbis/mindtct/init.c', + 'nbis/mindtct/line.c', + 'nbis/mindtct/log.c', + 'nbis/mindtct/loop.c', + 'nbis/mindtct/maps.c', + 'nbis/mindtct/matchpat.c', + 'nbis/mindtct/minutia.c', + 'nbis/mindtct/morph.c', + 'nbis/mindtct/quality.c', + 'nbis/mindtct/remove.c', + 'nbis/mindtct/ridges.c', + 'nbis/mindtct/shape.c', + 'nbis/mindtct/sort.c', + 'nbis/mindtct/util.c', +] + +aeslib = false +aesx660 = false +aes3k = false +drivers_sources = [] +drivers_cflags = [] +foreach driver: drivers + if driver == 'upekts' + drivers_sources += [ 'drivers/upekts.c' ] + endif + if driver == 'upektc' + drivers_sources += [ 'drivers/upektc.c', 'drivers/upektc.h' ] + endif + if driver == 'upeksonly' + drivers_sources += [ 'drivers/upeksonly.c', 'drivers/upeksonly.h' ] + endif + if driver == 'uru4000' + drivers_sources += [ 'drivers/uru4000.c' ] + endif + if driver == 'aes1610' + drivers_sources += [ 'drivers/aes1610.c' ] + aeslib = true + endif + if driver == 'aes1660' + drivers_sources += [ 'drivers/aes1660.c', 'drivers/aes1660.h' ] + aeslib = true + aesx660 = true + endif + if driver == 'aes2501' + drivers_sources += [ 'drivers/aes2501.c', 'drivers/aes2501.h' ] + aeslib = true + endif + if driver == 'aes2550' + drivers_sources += [ 'drivers/aes2550.c', 'drivers/aes2550.h' ] + aeslib = true + endif + if driver == 'aes2660' + drivers_sources += [ 'drivers/aes2660.c', 'drivers/aes2660.h' ] + aeslib = true + aesx660 = true + endif + if driver == 'aes3500' + drivers_sources += [ 'drivers/aes3500.c' ] + aeslib = true + aes3k = true + endif + if driver == 'aes4000' + drivers_sources += [ 'drivers/aes4000.c' ] + aeslib = true + aes3k = true + endif + if driver == 'fdu2000' + drivers_sources += [ 'drivers/fdu2000.c' ] + endif + if driver == 'vcom5s' + drivers_sources += [ 'drivers/vcom5s.c' ] + endif + if driver == 'vfs101' + 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' ] + endif + if driver == 'vfs5011' + drivers_sources += [ 'drivers/vfs5011.c', 'drivers/vfs5011_proto.h' ] + endif + if driver == 'upektc_img' + drivers_sources += [ 'drivers/upektc_img.c', 'drivers/upektc_img.h' ] + endif + if driver == 'etes603' + drivers_sources += [ 'drivers/etes603.c' ] + endif + if driver == 'vfs0050' + drivers_sources += [ 'drivers/vfs0050.c', 'drivers/vfs0050.h' ] + endif + if driver == 'elan' + drivers_sources += [ 'drivers/elan.c', 'drivers/elan.h' ] + endif + drivers_cflags += [ '-DENABLE_' + driver.to_upper() + '=1' ] +endforeach + +if aeslib + drivers_sources += [ 'aeslib.c', 'aeslib.h' ] +endif +if aesx660 + drivers_sources += ['drivers/aesx660.c', 'drivers/aesx660.h' ] +endif +if aes3k + drivers_sources += ['drivers/aes3k.c', 'drivers/aes3k.h' ] +endif + +other_sources = [] +if imaging_dep.found() + other_sources += [ 'pixman.c' ] +endif + +deps = [ mathlib_dep, glib_dep, libusb_dep, nss_dep, imaging_dep ] +libfprint = library('fprint', + libfprint_sources + drivers_sources + nbis_sources + other_sources, + soversion: soversion, + version: libversion, + c_args: common_cflags + drivers_cflags, + include_directories: [ + root_inc, + include_directories('nbis/include'), + ], + dependencies: deps, + install: true) + +libfprint_dep = declare_dependency(link_with: libfprint, + include_directories: root_inc) + +install_headers(['fprint.h']) + +udev_rules = executable('fprint-list-udev-rules', + 'fprint-list-udev-rules.c', + include_directories: [ + root_inc, + ], + dependencies: [ deps, libfprint_dep ], + install: false) + +if get_option('udev_rules') + custom_target('udev-rules', + output: '60-fprint-autosuspend.rules', + capture: true, + command: [ udev_rules ], + install: true, + install_dir: udev_rules_dir) +endif + +# MOSTLYCLEANFILES = $(udev_rules_DATA) + +# EXTRA_DIST = \ +# 60-fprint-autosuspend.rules + +# udev_rules_DATA = 60-fprint-autosuspend.rules + +# if ENABLE_UDEV_RULES +# $(udev_rules_DATA): fprint-list-udev-rules +# $(builddir)/fprint-list-udev-rules > $@ +#endif diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..f30732a1 --- /dev/null +++ b/meson.build @@ -0,0 +1,117 @@ +project('libfprint', [ 'c', 'cpp' ], + version: '0.7.0', + license: 'LGPLv2.1+', + default_options: [ + 'buildtype=debugoptimized', + 'warning_level=1', + 'c_std=c99', + ], + meson_version: '>= 0.45.0') + +add_project_arguments([ '-D_GNU_SOURCE' ], language: 'c') + +libfprint_conf = configuration_data() + +cc = meson.get_compiler('c') +cpp = meson.get_compiler('cpp') +host_system = host_machine.system() + +common_cflags = cc.get_supported_arguments([ + '-fgnu89-inline', + '-fvisibility=hidden', + '-std=gnu99', + '-Wall', + '-Wundef', + '-Wunused', + '-Wstrict-prototypes', + '-Werror-implicit-function-declaration', + '-Wno-pointer-sign', + '-Wshadow' +]) + +# maintaining compatibility with the previous libtool versioning +# current = binary - interface +# revision = interface +soversion = 0 +current = 0 +revision = 0 +libversion = '@0@.@1@.@2@'.format(soversion, current, revision) + +# Dependencies +glib_dep = dependency('glib-2.0', version: '>= 2.28') +libusb_dep = dependency('libusb-1.0', version: '>= 0.9.1') +mathlib_dep = cc.find_library('m', required: false) + +# Drivers +drivers = get_option('drivers').split(',') +all_drivers = [ 'upekts', 'upektc', 'upeksonly', 'vcom5s', 'uru4000', 'aes1610', 'aes1660', 'aes2501', 'aes2550', 'aes2660', 'aes3500', 'aes4000', 'vfs101', 'vfs301', 'vfs5011', 'upektc_img', 'etes603', 'vfs0050', 'elan' ] + +if drivers == [ 'all' ] + drivers = all_drivers +endif + +nss_dep = [] +imaging_dep = [] +foreach driver: drivers + if driver == 'uru4000' + nss_dep = dependency('nss', required: false) + if not nss_dep.found() + error('NSS is required for the URU4000/URU4500 driver') + endif + endif + if driver == 'aes3500' or driver == 'aes4000' + imaging_dep = dependency('pixman-1', required: false) + if not imaging_dep.found() + error('pixman is required for imaging support') + endif + endif + if not all_drivers.contains(driver) + error('Invalid driver \'' + driver + '\'') + endif +endforeach + + +root_inc = include_directories('.') + +if get_option('udev_rules') + udev_rules_dir = get_option('udev_rules_dir') + + if udev_rules_dir == 'auto' + udev_dep = dependency('udev') + udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + 'rules.d' + endif +endif + +if get_option('x11-examples') + x11_dep = cc.find_library('X11') + xv_dep = dependency('xv', required: false) + if not xv_dep.found() + error('XV is required for X11 examples') + endif +endif + +# Message logging +if get_option('log') + libfprint_conf.set('ENABLE_LOGGING', '1') +endif +if get_option('debug_log') + libfprint_conf.set('ENABLE_DEBUG_LOGGING', '1') +endif + +libfprint_conf.set('API_EXPORTED', '__attribute__((visibility("default")))') +configure_file(output: 'config.h', configuration: libfprint_conf) + +subdir('doc') +subdir('libfprint') +subdir('examples') + +pkgconfig = import('pkgconfig') +pkgconfig.generate( + name: 'libfprint', + description: 'Generic C API for fingerprint reader access', + version: meson.project_version(), + libraries: libfprint, + subdirs: 'libfprint', + filebase: 'libfprint', + install_dir: join_paths(get_option('libdir'), 'pkgconfig'), +) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..709e0eac --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,24 @@ +option('drivers', + description: 'Drivers to integrate', + type: 'string', + value: 'all') +option('udev_rules', + description: 'Whether to create a udev rules file', + type: 'boolean', + value: true) +option('udev_rules_dir', + description: 'Installation path for udev rules', + type: 'string', + value: 'auto') +option('x11-examples', + description: 'Whether to build X11 example applications', + type: 'boolean', + value: true) +option('log', + description: 'Message logging', + type: 'boolean', + value: true) +option('debug_log', + description: 'Debug message logging', + type: 'boolean', + value: false) From 231b8f9f92de81fc075a8083364511c02223a5fc Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 17 May 2018 02:58:59 +0200 Subject: [PATCH 055/141] doc: Port from Doxygen to gtk-doc Split the introduction into separate chapters, add filler documentation for async functions, fix mismatched function arguments. --- doc/advanced-topics.xml | 115 +++ doc/doxygen.cfg.in | 1294 --------------------------------- doc/getting-started.xml | 30 + doc/intro.xml | 106 +++ doc/libfprint-docs.xml | 53 ++ doc/libfprint-sections.txt | 127 ++++ doc/meson.build | 80 +- doc/xml/gtkdocentities.ent.in | 8 + doc/xml/meson.build | 10 + libfprint/async.c | 85 ++- libfprint/core.c | 492 +++++-------- libfprint/data.c | 173 +++-- libfprint/fprint.h | 225 ++++-- libfprint/img.c | 93 ++- libfprint/poll.c | 51 +- libfprint/sync.c | 112 +-- meson.build | 5 +- meson_options.txt | 4 + 18 files changed, 1216 insertions(+), 1847 deletions(-) create mode 100644 doc/advanced-topics.xml delete mode 100644 doc/doxygen.cfg.in create mode 100644 doc/getting-started.xml create mode 100644 doc/intro.xml create mode 100644 doc/libfprint-docs.xml create mode 100644 doc/libfprint-sections.txt create mode 100644 doc/xml/gtkdocentities.ent.in create mode 100644 doc/xml/meson.build diff --git a/doc/advanced-topics.xml b/doc/advanced-topics.xml new file mode 100644 index 00000000..bc674573 --- /dev/null +++ b/doc/advanced-topics.xml @@ -0,0 +1,115 @@ + + + + Advanced Topics + + + Device and print compatibility + + + Moving off generic conceptual ideas and onto libfprint-specific + implementation details, here are some introductory notes regarding how + libfprint copes with compatibility of fingerprints. + + + + libfprint deals with a whole variety of different fingerprint readers and + the design includes considerations of compatibility and interoperability + between multiple devices. Your application should also be prepared to + work with more than one type of fingerprint reader and should consider that + enrolled fingerprint X may not be compatible with the device the user has + plugged in today. + + + + libfprint implements the principle that fingerprints from different devices + are not necessarily compatible. For example, different devices may see + significantly different areas of fingerprint surface, and comparing images + between the devices would be unreliable. Also, devices can stretch and + distort images in different ways. + + + + libfprint also implements the principle that in some cases, fingerprints + are compatible between different devices. If you go and buy two + identical fingerprint readers, it seems logical that you should be able + to enroll on one and verify on another without problems. + + + + libfprint takes a fairly simplistic approach to these issues. Internally, + fingerprint hardware is driven by individual drivers. libfprint enforces + that a fingerprint that came from a device backed by driver X is never + compared to a fingerprint that came from a device backed by driver Y. + + + + Additionally, libfprint is designed for the situation where a single driver + may support a range of devices which differ in imaging or scanning + properties. For example, a driver may support two ranges of devices which + even though are programmed over the same interface, one device sees + substantially less of the finger flesh, therefore images from the two + device types should be incompatible despite being from the same driver. To + implement this, each driver assigns a device type to each device + that it detects based on its imaging characteristics. libfprint ensures that + two prints being compared have the same device type. + + + + In summary, libfprint represents fingerprints in several internal structures + and each representation will offer you a way of determining the + \ref driver_id "driver ID" and \ref devtype "devtype" of the print in + question. Prints are only compatible if the driver ID and devtypes + match. libfprint does offer you some "is this print compatible?" helper + functions, so you don't have to worry about these details too much. + + + + + Driver IDs + + + Each driver is assigned a unique ID by the project maintainer. These + assignments are + + documented on the wiki and will never change. + + + + The only reason you may be interested in retrieving the driver ID for a + driver is for the purpose of checking if some print data is compatible + with a device. libfprint uses the driver ID as one way of checking that + the print you are trying to verify is compatible with the device in + question - it ensures that enrollment data from one driver is never fed to + another. Note that libfprint does provide you with helper functions to + determine whether a print is compatible with a device, so under most + circumstances, you don't have to worry about driver IDs at all. + + + + + Device types + + + Internally, the \ref drv "driver" behind a device assigns a 32-bit + devtype identifier to the device. This cannot be used as a unique + ID for a specific device as many devices under the same range may share + the same devtype. The devtype may even be 0 in all cases. + + + + The only reason you may be interested in retrieving the devtype for a + device is for the purpose of checking if some print data is compatible + with a device. libfprint uses the devtype as one way of checking that the + print you are verifying is compatible with the device in question - the + devtypes must be equal. This effectively allows drivers to support more + than one type of device where the data from each one is not compatible with + the other. Note that libfprint does provide you with helper functions to + determine whether a print is compatible with a device, so under most + circumstances, you don't have to worry about devtypes at all. + + + + diff --git a/doc/doxygen.cfg.in b/doc/doxygen.cfg.in deleted file mode 100644 index da7bf494..00000000 --- a/doc/doxygen.cfg.in +++ /dev/null @@ -1,1294 +0,0 @@ -# Doxyfile 1.5.3 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file that -# follow. The default is UTF-8 which is also the encoding used for all text before -# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into -# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of -# possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = libfprint - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be extracted -# and appear in the documentation as a namespace called 'anonymous_namespace{file}', -# where file will be replaced with the base name of the file that contains the anonymous -# namespace. By default anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = "@SRCDIR@" - -# This tag can be used to specify the character encoding of the source files that -# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default -# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. -# See http://www.gnu.org/software/libiconv for the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = ../libfprint/fp_internal.h - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the output. -# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, -# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH -# then you must also enable this option. If you don't then doxygen will produce -# a warning and turn it on anyway - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = "@BUILDDIR@/html" - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = YES - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = API_EXPORTED= - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to -# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to -# specify the directory where the mscgen tool resides. If left empty the tool is assumed to -# be found in the default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the number -# of direct children of the root node in a graph is already larger than -# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/doc/getting-started.xml b/doc/getting-started.xml new file mode 100644 index 00000000..5c2d2080 --- /dev/null +++ b/doc/getting-started.xml @@ -0,0 +1,30 @@ + + + + Getting Started + + + libfprint includes several simple functional examples under the examples/ + directory in the libfprint source distribution. Those are good starting + points. + + + + Usually the first thing you want to do is determine which fingerprint + devices are present. This is done through \ref dscv_dev "device discovery". + + + + Once you have found a device you would like to operate, you should open it. + Refer to \ref dev "device operations". This section also details enrollment, + image capture, and verification. + + + + That should be enough to get you started, but do remember there are + documentation pages on other aspects of libfprint's API (see the modules + page). + + diff --git a/doc/intro.xml b/doc/intro.xml new file mode 100644 index 00000000..cfd91008 --- /dev/null +++ b/doc/intro.xml @@ -0,0 +1,106 @@ + + + + Introduction + + + libfprint is an open source library to provide access to fingerprint + scanning devices. For more info, see the + libfprint project homepage. + + + + This documentation is aimed at application developers who wish to integrate + fingerprint-related functionality into their software. libfprint has been + designed so that you only have to do this once - by integrating your + software with libfprint, you'll be supporting all the fingerprint readers + that we have got our hands on. As such, the API is rather general (and + therefore hopefully easy to comprehend!), and does its best to hide the + technical details that required to operate the hardware. + + + + This documentation is not aimed at developers wishing to develop and + contribute fingerprint device drivers to libfprint. + + + + Feedback on this API and its associated documentation is appreciated. Was + anything unclear? Does anything seem unreasonably complicated? Is anything + missing? Let us know on the + mailing list. + + + + Enrollment + + + Before you dive into the API, it's worth introducing a couple of concepts. + + + + The process of enrolling a finger is where you effectively scan your + finger for the purposes of teaching the system what your finger looks like. + This means that you scan your fingerprint, then the system processes it and + stores some data about your fingerprint to refer to later. + + + + + Verification + + + Verification is what most people think of when they think about fingerprint + scanning. The process of verification is effectively performing a fresh + fingerprint scan, and then comparing that scan to a finger that was + previously enrolled. + + + + As an example scenario, verification can be used to implement what people + would picture as fingerprint login (i.e. fingerprint replaces password). + For example: + + + + I enroll my fingerprint through some software that trusts I am who I say + I am. This is a prerequisite before I can perform fingerprint-based + login for my account. + + + Some time later, I want to login to my computer. I enter my username, + but instead of prompting me for a password, it asks me to scan my finger. + I scan my finger. + + + The system compares the finger I just scanned to the one that was + enrolled earlier. If the system decides that the fingerprints match, + I am successfully logged in. Otherwise, the system informs me that I am + not authorised to login as that user. + + + + + + Identification + + + Identification is the process of comparing a freshly scanned fingerprint + to a collection of previously enrolled fingerprints. For example, + imagine there are 100 people in an organisation, and they all have enrolled + their fingerprints. One user walks up to a fingerprint scanner and scans + their finger. With no other knowledge of who that user might be, + the system examines their fingerprint, looks in the database, and determines + that the user is user number #61. + + + + In other words, verification might be seen as a one-to-one fingerprint + comparison where you know the identity of the user that you wish to + authenticate, whereas identification is a one-to-many comparison where you + do not know the identity of the user that you wish to authenticate. + + + diff --git a/doc/libfprint-docs.xml b/doc/libfprint-docs.xml new file mode 100644 index 00000000..8a0ff38b --- /dev/null +++ b/doc/libfprint-docs.xml @@ -0,0 +1,53 @@ + + +]> + + + libfprint Reference Manual + + This document is the API reference for the libfprint library. + + The latest version of libfprint, as well as the latest version of + this API reference, is available online. + + + + + + Library Overview + + + + + + + API Documentation + + + + + + + + + + + + + + API Index + + + + Index of deprecated API + + + diff --git a/doc/libfprint-sections.txt b/doc/libfprint-sections.txt new file mode 100644 index 00000000..fbf13e58 --- /dev/null +++ b/doc/libfprint-sections.txt @@ -0,0 +1,127 @@ +fprint.h + +
+events +Initialisation and events handling +fp_set_debug +fp_init +fp_exit +fp_pollfd +fp_handle_events_timeout +fp_handle_events +fp_get_next_timeout +fp_get_pollfds +fp_set_pollfd_notifiers +
+ +
+discovery +Device discovery +fp_dscv_dev +fp_discover_devs +fp_dscv_devs_free +fp_dscv_dev_get_driver +fp_dscv_dev_get_devtype +fp_dscv_dev_supports_print_data +fp_dscv_dev_supports_dscv_print +fp_dscv_dev_for_print_data +fp_dscv_dev_for_dscv_print +
+ +
+drv +fp_driver +fp_driver_get_name +fp_driver_get_full_name +fp_driver_get_driver_id +fp_driver_get_scan_type +
+ +
+dev +fp_dev +fp_scan_type +fp_capture_result +fp_enroll_result +fp_verify_result + +fp_dev_get_driver +fp_dev_get_nr_enroll_stages +fp_dev_get_devtype +fp_dev_supports_print_data +fp_dev_supports_imaging +fp_dev_supports_identification +fp_dev_supports_dscv_print +fp_dev_get_img_width +fp_dev_get_img_height + +fp_dev_open +fp_async_dev_open + +fp_dev_close +fp_async_dev_close + +fp_enroll_finger +fp_enroll_finger_img +fp_async_enroll_start +fp_async_enroll_stop + +fp_verify_finger +fp_verify_finger_img +fp_async_verify_start +fp_async_verify_stop + +fp_identify_finger +fp_identify_finger_img +fp_async_identify_start +fp_async_identify_stop + +fp_dev_img_capture +fp_async_capture_start +fp_async_capture_stop +
+ +
+print_data +fp_finger +fp_print_data +fp_print_data +fp_print_data_get_data +fp_print_data_from_data +fp_print_data_save +fp_print_data_load +fp_print_data_delete +fp_print_data_from_dscv_print +fp_print_data_free +fp_print_data_get_driver_id +fp_print_data_get_devtype +
+ +
+dscv_print +fp_dscv_print +fp_discover_prints +fp_dscv_prints_free +fp_dscv_print_get_driver_id +fp_dscv_print_get_devtype +fp_dscv_print_get_finger +fp_dscv_print_delete +
+ +
+img +fp_img +fp_minutia +fp_img_free +fp_img_get_height +fp_img_get_width +fp_img_get_data +fp_img_save_to_file +fp_img_standardize +fp_img_binarize +fp_img_get_minutiae +
+ +
+poll +
diff --git a/doc/meson.build b/doc/meson.build index 717efac7..48358c8e 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -1,17 +1,67 @@ -cdata = configuration_data() -cdata.set('SRCDIR', join_paths(meson.source_root(), 'libfprint')) -cdata.set('BUILDDIR', join_paths(meson.build_root(), 'doc')) +subdir('xml') -cfg = configure_file(input: 'doxygen.cfg.in', - output: 'doxygen.cfg', - configuration: cdata, - install: false) +private_headers = [ + 'config.h', -doxygen = find_program('doxygen') -datadir = join_paths(get_option('datadir'), 'doc', 'libfprint-devel') -custom_target('docs', - input: cfg, - output: 'html', - command: [ doxygen, '@INPUT@' ], - install: true, - install_dir: datadir) + 'aeslib.h', + 'assembling.h', + 'fp_internal.h', + + # Drivers + 'aes1660.h', + 'aes2501.h', + 'aes2550.h', + 'aes2660.h', + 'aes3k.h', + 'aesx660.h', + 'driver_ids.h', + 'elan.h', + 'upeksonly.h', + 'upektc.h', + 'upektc_img.h', + 'vfs0050.h', + 'vfs301_proto_fragments.h', + 'vfs301_proto.h', + 'vfs5011_proto.h', + + # NBIS + 'morph.h', + 'sunrast.h', + 'bozorth.h', + 'defs.h', + 'log.h', + 'bz_array.h', + 'lfs.h', +] + +html_images = [ +] + +content_files = [ + 'intro.xml' +] + +expand_content_files = content_files + +glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix') +glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html') +docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html') + +gnome.gtkdoc('libfprint', + main_xml: 'libfprint-docs.xml', + src_dir: join_paths(meson.source_root(), 'libfprint'), + dependencies: libfprint_dep, + content_files: content_files, + expand_content_files: expand_content_files, + scan_args: [ + '--rebuild-types', + '--ignore-decorators=API_EXPORTED', + '--ignore-headers=' + ' '.join(private_headers), + ], + fixxref_args: [ + '--html-dir=@0@'.format(docpath), + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')), + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')), + ], + html_assets: html_images, + install: true) diff --git a/doc/xml/gtkdocentities.ent.in b/doc/xml/gtkdocentities.ent.in new file mode 100644 index 00000000..f12c9ff7 --- /dev/null +++ b/doc/xml/gtkdocentities.ent.in @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doc/xml/meson.build b/doc/xml/meson.build new file mode 100644 index 00000000..ea3ddf59 --- /dev/null +++ b/doc/xml/meson.build @@ -0,0 +1,10 @@ +ent_conf = configuration_data() +ent_conf.set('PACKAGE', 'libfprint') +ent_conf.set('PACKAGE_BUGREPORT', 'https://bugs.freedesktop.org/enter_bug.cgi?product=libfprint') +ent_conf.set('PACKAGE_NAME', 'libfprint') +ent_conf.set('PACKAGE_STRING', 'libfprint') +ent_conf.set('PACKAGE_TARNAME', 'libfprint-' + meson.project_version()) +ent_conf.set('PACKAGE_URL', 'https://www.freedesktop.org/wiki/Software/fprint/libfprint/') +ent_conf.set('PACKAGE_VERSION', meson.project_version()) +ent_conf.set('PACKAGE_API_VERSION', '1.0') +configure_file(input: 'gtkdocentities.ent.in', output: 'gtkdocentities.ent', configuration: ent_conf) diff --git a/libfprint/async.c b/libfprint/async.c index 128b7e90..2337a579 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -36,7 +36,15 @@ void fpi_drvcb_open_complete(struct fp_dev *dev, int status) dev->open_cb(dev, status, dev->open_cb_data); } -API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb cb, +/** + * fp_async_dev_open: + * @ddev: + * @callback: + * @user_data + * + * Returns: + */ +API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback, void *user_data) { struct fp_driver *drv = ddev->drv; @@ -56,7 +64,7 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb cb, dev->udev = udevh; dev->__enroll_stage = -1; dev->state = DEV_STATE_INITIALIZING; - dev->open_cb = cb; + dev->open_cb = callback; dev->open_cb_data = user_data; if (!drv->open) { @@ -87,6 +95,12 @@ void fpi_drvcb_close_complete(struct fp_dev *dev) g_free(dev); } +/** + * fp_async_dev_close: + * @dev: + * @callback: + * @user_data + */ API_EXPORTED void fp_async_dev_close(struct fp_dev *dev, fp_dev_close_cb callback, void *user_data) { @@ -127,6 +141,14 @@ void fpi_drvcb_enroll_started(struct fp_dev *dev, int status) } } +/** + * fp_async_enroll_start: + * @dev: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback, void *user_data) { @@ -181,6 +203,14 @@ void fpi_drvcb_enroll_stopped(struct fp_dev *dev) dev->enroll_stop_cb(dev, dev->enroll_stop_cb_data); } +/** + * fp_async_enroll_stop: + * @dev: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, fp_enroll_stop_cb callback, void *user_data) { @@ -210,6 +240,15 @@ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, return r; } +/** + * fp_async_verify_start: + * @dev: + * @data: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_verify_start(struct fp_dev *dev, struct fp_print_data *data, fp_verify_cb callback, void *user_data) { @@ -278,6 +317,14 @@ void fpi_drvcb_verify_stopped(struct fp_dev *dev) dev->verify_stop_cb(dev, dev->verify_stop_cb_data); } +/** + * fp_async_verify_stop: + * @dev: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, fp_verify_stop_cb callback, void *user_data) { @@ -311,6 +358,15 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, return r; } +/** + * fp_async_identify_start: + * @dev: + * @gallery: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_identify_start(struct fp_dev *dev, struct fp_print_data **gallery, fp_identify_cb callback, void *user_data) { @@ -369,6 +425,14 @@ void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result, fp_dbg("ignoring verify result as no callback is subscribed"); } +/** + * fp_async_identify_stop: + * @dev: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev, fp_identify_stop_cb callback, void *user_data) { @@ -412,6 +476,15 @@ void fpi_drvcb_identify_stopped(struct fp_dev *dev) dev->identify_stop_cb(dev, dev->identify_stop_cb_data); } +/** + * fp_async_capture_start: + * @dev: + * @unconditional: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_capture_cb callback, void *user_data) { @@ -479,6 +552,14 @@ void fpi_drvcb_capture_stopped(struct fp_dev *dev) dev->capture_stop_cb(dev, dev->capture_stop_cb_data); } +/** + * fp_async_capture_stop: + * @dev: + * @callback: + * @user_data: + * + * Returns: + */ API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev, fp_capture_stop_cb callback, void *user_data) { diff --git a/libfprint/core.c b/libfprint/core.c index 6f3729e2..e22b3bb5 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -34,163 +34,50 @@ libusb_context *fpi_usb_ctx = NULL; GSList *opened_devices = NULL; /** - * \mainpage libfprint API Reference - * libfprint is an open source library to provide access to fingerprint - * scanning devices. For more info, see the - * libfprint project - * homepage. + * SECTION:discovery + * @title: Device discovery * - * This documentation is aimed at application developers who wish to integrate - * fingerprint-related functionality into their software. libfprint has been - * designed so that you only have to do this once - by integrating your - * software with libfprint, you'll be supporting all the fingerprint readers - * that we have got our hands on. As such, the API is rather general (and - * therefore hopefully easy to comprehend!), and does its best to hide the - * technical details that required to operate the hardware. + * These functions allow you to scan the system for supported fingerprint + * scanning hardware. This is your starting point when integrating libfprint + * into your software. * - * This documentation is not aimed at developers wishing to develop and - * contribute fingerprint device drivers to libfprint. - * - * Feedback on this API and its associated documentation is appreciated. Was - * anything unclear? Does anything seem unreasonably complicated? Is anything - * missing? Let us know on the - * mailing list. - * - * \section enrollment Enrollment - * - * Before you dive into the API, it's worth introducing a couple of concepts. - * - * The process of enrolling a finger is where you effectively scan your - * finger for the purposes of teaching the system what your finger looks like. - * This means that you scan your fingerprint, then the system processes it and - * stores some data about your fingerprint to refer to later. - * - * \section verification Verification - * - * Verification is what most people think of when they think about fingerprint - * scanning. The process of verification is effectively performing a fresh - * fingerprint scan, and then comparing that scan to a finger that was - * previously enrolled. - * - * As an example scenario, verification can be used to implement what people - * would picture as fingerprint login (i.e. fingerprint replaces password). - * For example: - * - I enroll my fingerprint through some software that trusts I am who I say - * I am. This is a prerequisite before I can perform fingerprint-based - * login for my account. - * - Some time later, I want to login to my computer. I enter my username, - * but instead of prompting me for a password, it asks me to scan my finger. - * I scan my finger. - * - The system compares the finger I just scanned to the one that was - * enrolled earlier. If the system decides that the fingerprints match, - * I am successfully logged in. Otherwise, the system informs me that I am - * not authorised to login as that user. - * - * \section identification Identification - * - * Identification is the process of comparing a freshly scanned fingerprint - * to a collection of previously enrolled fingerprints. For example, - * imagine there are 100 people in an organisation, and they all have enrolled - * their fingerprints. One user walks up to a fingerprint scanner and scans - * their finger. With no other knowledge of who that user might be, - * the system examines their fingerprint, looks in the database, and determines - * that the user is user number #61. - * - * In other words, verification might be seen as a one-to-one fingerprint - * comparison where you know the identity of the user that you wish to - * authenticate, whereas identification is a one-to-many comparison where you - * do not know the identity of the user that you wish to authenticate. - * - * \section compat_general Device and print compatibility - * Moving off generic conceptual ideas and onto libfprint-specific - * implementation details, here are some introductory notes regarding how - * libfprint copes with compatibility of fingerprints. - * - * libfprint deals with a whole variety of different fingerprint readers and - * the design includes considerations of compatibility and interoperability - * between multiple devices. Your application should also be prepared to - * work with more than one type of fingerprint reader and should consider that - * enrolled fingerprint X may not be compatible with the device the user has - * plugged in today. - * - * libfprint implements the principle that fingerprints from different devices - * are not necessarily compatible. For example, different devices may see - * significantly different areas of fingerprint surface, and comparing images - * between the devices would be unreliable. Also, devices can stretch and - * distort images in different ways. - * - * libfprint also implements the principle that in some cases, fingerprints - * are compatible between different devices. If you go and buy two - * identical fingerprint readers, it seems logical that you should be able - * to enroll on one and verify on another without problems. - * - * libfprint takes a fairly simplistic approach to these issues. Internally, - * fingerprint hardware is driven by individual drivers. libfprint enforces - * that a fingerprint that came from a device backed by driver X is never - * compared to a fingerprint that came from a device backed by driver Y. - * - * Additionally, libfprint is designed for the situation where a single driver - * may support a range of devices which differ in imaging or scanning - * properties. For example, a driver may support two ranges of devices which - * even though are programmed over the same interface, one device sees - * substantially less of the finger flesh, therefore images from the two - * device types should be incompatible despite being from the same driver. To - * implement this, each driver assigns a device type to each device - * that it detects based on its imaging characteristics. libfprint ensures that - * two prints being compared have the same device type. - * - * In summary, libfprint represents fingerprints in several internal structures - * and each representation will offer you a way of determining the - * \ref driver_id "driver ID" and \ref devtype "devtype" of the print in - * question. Prints are only compatible if the driver ID and devtypes - * match. libfprint does offer you some "is this print compatible?" helper - * functions, so you don't have to worry about these details too much. - * - * \section sync Synchronity/asynchronity - * - * Currently, all data acquisition operations are synchronous and can - * potentially block for extended periods of time. For example, the enroll - * function will block for an unpredictable amount of time until the user - * scans their finger. - * - * Alternative asynchronous/non-blocking functionality will be offered in - * future but has not been implemented yet. - * - * \section getting_started Getting started - * - * libfprint includes several simple functional examples under the examples/ - * directory in the libfprint source distribution. Those are good starting - * points. - * - * Usually the first thing you want to do is determine which fingerprint - * devices are present. This is done through \ref dscv_dev "device discovery". - * - * Once you have found a device you would like to operate, you should open it. - * Refer to \ref dev "device operations". This section also details enrollment, - * image capture, and verification. - * - * - * That should be enough to get you started, but do remember there are - * documentation pages on other aspects of libfprint's API (see the modules - * page). + * When you've identified a discovered device that you would like to control, + * you can open it with fp_dev_open(). Note that discovered devices may no + * longer be available at the time when you want to open them, for example + * the user may have unplugged the device. */ -/** @defgroup core Core library operations */ +/** + * SECTION:drv + * @title: Driver operations + * + * Internally, libfprint is abstracted into various drivers to communicate + * with the different types of supported fingerprint readers. libfprint works + * hard so that you don't have to care about these internal abstractions, + * however there are some situations where you may be interested in a little + * behind-the-scenes driver info. + * + * You can obtain the driver for a device using fp_dev_get_driver(), which + * you can pass to the functions documented on this page. + */ /** - * @defgroup dev Device operations + * SECTION:dev + * @title: Devices operations + * * In order to interact with fingerprint scanners, your software will * interface primarily with libfprint's representation of devices, detailed * on this page. * - * \section enrolling Enrolling + * # Enrolling # {#enrolling} + * * Enrolling is represented within libfprint as a multi-stage process. This * slightly complicates things for application developers, but is required * for a smooth process. * * Some devices require the user to scan their finger multiple times in * order to complete the enrollment process. libfprint must return control - * to your application inbetween each scan in order for your application to + * to your application in-between each scan in order for your application to * instruct the user to swipe their finger again. Each scan is referred to * as a stage, so a device that requires 3 scans for enrollment corresponds * to you running 3 enrollment stages using libfprint. @@ -208,7 +95,8 @@ GSList *opened_devices = NULL; * fp_enroll_finger() documentation. You should pay careful attention to the * details. * - * \section imaging Imaging + * # Imaging # {#imaging} + * * libfprint provides you with some ways to retrieve images of scanned * fingers, such as the fp_dev_img_capture() function, or some enroll/verify * function variants which provide images. You may wish to do something with @@ -224,59 +112,6 @@ GSList *opened_devices = NULL; * on a particular device. Your application must be able to cope with the * fact that libfprint does support regular operations (e.g. enrolling and * verification) on some devices which do not provide images. - * - * \section devtype Devtypes - * Internally, the \ref drv "driver" behind a device assigns a 32-bit - * devtype identifier to the device. This cannot be used as a unique - * ID for a specific device as many devices under the same range may share - * the same devtype. The devtype may even be 0 in all cases. - * - * The only reason you may be interested in retrieving the devtype for a - * device is for the purpose of checking if some print data is compatible - * with a device. libfprint uses the devtype as one way of checking that the - * print you are verifying is compatible with the device in question - the - * devtypes must be equal. This effectively allows drivers to support more - * than one type of device where the data from each one is not compatible with - * the other. Note that libfprint does provide you with helper functions to - * determine whether a print is compatible with a device, so under most - * circumstances, you don't have to worry about devtypes at all. - */ - -/** @defgroup dscv_dev Device discovery - * These functions allow you to scan the system for supported fingerprint - * scanning hardware. This is your starting point when integrating libfprint - * into your software. - * - * When you've identified a discovered device that you would like to control, - * you can open it with fp_dev_open(). Note that discovered devices may no - * longer be available at the time when you want to open them, for example - * the user may have unplugged the device. - */ - -/** @defgroup drv Driver operations - * Internally, libfprint is abstracted into various drivers to communicate - * with the different types of supported fingerprint readers. libfprint works - * hard so that you don't have to care about these internal abstractions, - * however there are some situations where you may be interested in a little - * behind-the-scenes driver info. - * - * You can obtain the driver for a device using fp_dev_get_driver(), which - * you can pass to the functions documented on this page. - * - * \section driver_id Driver IDs - * Each driver is assigned a unique ID by the project maintainer. These - * assignments are - * - * documented on the wiki and will never change. - * - * The only reason you may be interested in retrieving the driver ID for a - * driver is for the purpose of checking if some print data is compatible - * with a device. libfprint uses the driver ID as one way of checking that - * the print you are trying to verify is compatible with the device in - * question - it ensures that enrollment data from one driver is never fed to - * another. Note that libfprint does provide you with helper functions to - * determine whether a print is compatible with a device, so under most - * circumstances, you don't have to worry about driver IDs at all. */ static GSList *registered_drivers = NULL; @@ -524,10 +359,13 @@ static struct fp_dscv_dev *discover_dev(libusb_device *udev) return ddev; } -/** \ingroup dscv_dev +/** + * 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. - * \returns a NULL-terminated list of discovered devices. Must be freed with + * + * Returns: a %NULL-terminated list of discovered devices. Must be freed with * fp_dscv_devs_free() after use. */ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) @@ -582,12 +420,14 @@ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) return list; } -/** \ingroup dscv_dev +/** + * fp_dscv_devs_free: + * @devs: the list of discovered devices. If %NULL, function simply + * returns. + * * Free a list of discovered devices. This function destroys the list and all * discovered devices that it included, so make sure you have opened your - * discovered device before freeing the list. - * \param devs the list of discovered devices. If NULL, function simply - * returns. + * discovered device before freeing the list. */ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs) { @@ -602,20 +442,26 @@ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs) g_free(devs); } -/** \ingroup dscv_dev - * Gets the \ref drv "driver" for a discovered device. - * \param dev the discovered device - * \returns the driver backing the device +/** + * fp_dscv_dev_get_driver: + * @dev: the discovered device + * + * Gets the #fp_driver "driver" for a discovered device. + * + * Returns: the driver backing the device */ API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev) { return dev->drv; } -/** \ingroup dscv_dev - * Gets the \ref devtype "devtype" for a discovered device. - * \param dev the discovered device - * \returns the devtype of the device +/** + * fp_dscv_dev_get_devtype: + * @dev: the discovered device + * + * Gets the [devtype](advanced-topics.html#device-types) for a discovered device. + * + * Returns: the devtype of the device */ API_EXPORTED uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev) { @@ -635,62 +481,74 @@ enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv) } } -/** \ingroup dscv_dev - * Determines if a specific \ref print_data "stored print" appears to be +/** + * fp_dscv_dev_supports_print_data: + * @dev: the discovered device + * @print: the print for compatibility checking + * + * Determines if a specific #fp_print_data "stored print" appears to be * compatible with a discovered device. - * \param dev the discovered device - * \param data the print for compatibility checking - * \returns 1 if the print is compatible with the device, 0 otherwise + * + * Returns: 1 if the print is compatible with the device, 0 otherwise */ API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, - struct fp_print_data *data) + struct fp_print_data *print) { return fpi_print_data_compatible(dev->drv->id, dev->devtype, - fpi_driver_get_data_type(dev->drv), data->driver_id, data->devtype, - data->type); + fpi_driver_get_data_type(dev->drv), print->driver_id, print->devtype, + print->type); } -/** \ingroup dscv_dev - * Determines if a specific \ref dscv_print "discovered print" appears to be +/** + * fp_dscv_dev_supports_dscv_print: + * @dev: the discovered device + * @print: the discovered print for compatibility checking + * + * Determines if a specific #fp_dscv_print "discovered print" appears to be * compatible with a discovered device. - * \param dev the discovered device - * \param data the discovered print for compatibility checking - * \returns 1 if the print is compatible with the device, 0 otherwise + * + * Returns: 1 if the print is compatible with the device, 0 otherwise */ API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev, - struct fp_dscv_print *data) + struct fp_dscv_print *print) { return fpi_print_data_compatible(dev->drv->id, dev->devtype, 0, - data->driver_id, data->devtype, 0); + print->driver_id, print->devtype, 0); } -/** \ingroup dscv_dev +/** + * fp_dscv_dev_for_print_data: + * @devs: a list of discovered devices + * @print: the print under inspection + * * Searches a list of discovered devices for a device that appears to be - * compatible with a \ref print_data "stored print". - * \param devs a list of discovered devices - * \param data the print under inspection - * \returns the first discovered device that appears to support the print, or - * NULL if no apparently compatible devices could be found + * compatible with a #fp_print_data "stored print". + * + * Returns: the first discovered device that appears to support the print, or + * %NULL if no apparently compatible devices could be found */ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs, - struct fp_print_data *data) + struct fp_print_data *print) { struct fp_dscv_dev *ddev; int i; for (i = 0; (ddev = devs[i]); i++) - if (fp_dscv_dev_supports_print_data(ddev, data)) + if (fp_dscv_dev_supports_print_data(ddev, print)) return ddev; return NULL; } -/** \ingroup dscv_dev +/** + * fp_dscv_dev_for_dscv_print: + * @devs: a list of discovered devices + * @print: the print under inspection + * * Searches a list of discovered devices for a device that appears to be - * compatible with a \ref dscv_print "discovered print". - * \param devs a list of discovered devices - * \param print the print under inspection - * \returns the first discovered device that appears to support the print, or - * NULL if no apparently compatible devices could be found + * compatible with a #fp_dscv_print "discovered print". + * + * Returns: the first discovered device that appears to support the print, or + * %NULL if no apparently compatible devices could be found */ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs, struct fp_dscv_print *print) @@ -704,42 +562,54 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev * return NULL; } -/** \ingroup dev - * Get the \ref drv "driver" for a fingerprint device. - * \param dev the device - * \returns the driver controlling the device +/** + * fp_dev_get_driver: + * @dev: the device + * + * Get the #fp_driver "driver" for a fingerprint device. + * + * Returns: the driver controlling the device */ API_EXPORTED struct fp_driver *fp_dev_get_driver(struct fp_dev *dev) { return dev->drv; } -/** \ingroup dev - * Gets the number of \ref enrolling "enroll stages" required to enroll a +/** + * fp_dev_get_nr_enroll_stages: + * @dev: the device + * + * Gets the number of [enroll stages](intro.html#enrollment) required to enroll a * fingerprint with the device. - * \param dev the device - * \returns the number of enroll stages + * + * Returns: the number of enroll stages */ API_EXPORTED int fp_dev_get_nr_enroll_stages(struct fp_dev *dev) { return dev->nr_enroll_stages; } -/** \ingroup dev - * Gets the \ref devtype "devtype" for a device. - * \param dev the device - * \returns the devtype +/** + * fp_dev_get_devtype: + * @dev: the device + * + * Gets the [devtype](advanced-topics.html#device-types) for a device. + * + * Returns: the devtype */ API_EXPORTED uint32_t fp_dev_get_devtype(struct fp_dev *dev) { return dev->devtype; } -/** \ingroup dev +/** + * fp_dev_supports_print_data: + * @dev: the device + * @data: the stored print + * * Determines if a stored print is compatible with a certain device. - * \param dev the device - * \param data the stored print - * \returns 1 if the print is compatible with the device, 0 if not + * + * Returns: 1 if the print is compatible with the device, 0 if not */ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev, struct fp_print_data *data) @@ -749,54 +619,69 @@ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev, data->type); } -/** \ingroup dev - * Determines if a \ref dscv_print "discovered print" appears to be compatible +/** + * fp_dev_supports_dscv_print: + * @dev: the device + * @print: the discovered print + * + * Determines if a #fp_dscv_print "discovered print" appears to be compatible * with a certain device. - * \param dev the device - * \param data the discovered print - * \returns 1 if the print is compatible with the device, 0 if not + * + * Returns: 1 if the print is compatible with the device, 0 if not */ API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev, - struct fp_dscv_print *data) + struct fp_dscv_print *print) { return fpi_print_data_compatible(dev->drv->id, dev->devtype, - 0, data->driver_id, data->devtype, 0); + 0, print->driver_id, print->devtype, 0); } -/** \ingroup drv +/** + * fp_driver_get_name: + * @drv: the driver + * * Retrieves the name of the driver. For example: "upekts" - * \param drv the driver - * \returns the driver name. Must not be modified or freed. + * + * Returns: the driver name. Must not be modified or freed. */ API_EXPORTED const char *fp_driver_get_name(struct fp_driver *drv) { return drv->name; } -/** \ingroup drv +/** + * fp_driver_get_full_name: + * @drv: the driver + * * Retrieves a descriptive name of the driver. For example: "UPEK TouchStrip" - * \param drv the driver - * \returns the descriptive name. Must not be modified or freed. + * + * Returns: the descriptive name. Must not be modified or freed. */ API_EXPORTED const char *fp_driver_get_full_name(struct fp_driver *drv) { return drv->full_name; } -/** \ingroup drv +/** + * fp_driver_get_driver_id: + * @drv: the driver + * * Retrieves the driver ID code for a driver. - * \param drv the driver - * \returns the driver ID + * + * Returns: the driver ID */ API_EXPORTED uint16_t fp_driver_get_driver_id(struct fp_driver *drv) { return drv->id; } -/** \ingroup drv +/** + * fp_driver_get_scan_type: + * @drv: the driver + * * Retrieves the scan type for the devices associated with the driver. - * \param drv the driver - * \returns the scan type + * + * Returns: the scan type */ API_EXPORTED enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv) { @@ -810,14 +695,17 @@ static struct fp_img_dev *dev_to_img_dev(struct fp_dev *dev) return dev->priv; } -/** \ingroup dev +/** + * fp_dev_supports_imaging: + * @dev: the fingerprint device + * * Determines if a device has imaging capabilities. If a device has imaging * capabilities you are able to perform imaging operations such as retrieving * scan images using fp_dev_img_capture(). However, not all devices are * imaging devices - some do all processing in hardware. This function will * indicate which class a device in question falls into. - * \param dev the fingerprint device - * \returns 1 if the device is an imaging device, 0 if the device does not + * + * Returns: 1 if the device is an imaging device, 0 if the device does not * provide images to the host computer */ API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev) @@ -825,25 +713,31 @@ API_EXPORTED int fp_dev_supports_imaging(struct fp_dev *dev) return dev->drv->capture_start != NULL; } -/** \ingroup dev - * Determines if a device is capable of \ref identification "identification" +/** + * fp_dev_supports_identification: + * @dev: the fingerprint device + * + * Determines if a device is capable of [identification](intro.html#identification) * through fp_identify_finger() and similar. Not all devices support this * functionality. - * \param dev the fingerprint device - * \returns 1 if the device is capable of identification, 0 otherwise. + * + * Returns: 1 if the device is capable of identification, 0 otherwise. */ API_EXPORTED int fp_dev_supports_identification(struct fp_dev *dev) { return dev->drv->identify_start != NULL; } -/** \ingroup dev +/** + * fp_dev_get_img_width: + * @dev: the fingerprint device + * * Gets the expected width of images that will be captured from the device. * This function will return -1 for devices that are not - * \ref imaging "imaging devices". If the width of images from this device + * [imaging devices](libfprint-Devices-operations.html#imaging). If the width of images from this device * can vary, 0 will be returned. - * \param dev the device - * \returns the expected image width, or 0 for variable, or -1 for non-imaging + * + * Returns: the expected image width, or 0 for variable, or -1 for non-imaging * devices. */ API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev) @@ -857,13 +751,16 @@ API_EXPORTED int fp_dev_get_img_width(struct fp_dev *dev) return fpi_imgdev_get_img_width(imgdev); } -/** \ingroup dev +/** + * fp_dev_get_img_height: + * @dev: the fingerprint device + * * Gets the expected height of images that will be captured from the device. * This function will return -1 for devices that are not - * \ref imaging "imaging devices". If the height of images from this device + * [imaging devices](libfprint-Devices-operations.html#imaging). If the height of images from this device * can vary, 0 will be returned. - * \param dev the device - * \returns the expected image height, or 0 for variable, or -1 for non-imaging + * + * Returns: the expected image height, or 0 for variable, or -1 for non-imaging * devices. */ API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev) @@ -877,7 +774,10 @@ API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev) return fpi_imgdev_get_img_height(imgdev); } -/** \ingroup core +/** + * fp_set_debug: + * @level: the verbosity level + * * Set message verbosity. * - Level 0: no messages ever printed by the library (default) * - Level 1: error messages are printed to stderr @@ -902,9 +802,6 @@ API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev) * * If libfprint was compiled with verbose debug message logging, this function * does nothing: you'll always get messages from all levels. - * - * \param ctx the context to operate on, or NULL for the default context - * \param level debug level to set */ API_EXPORTED void fp_set_debug(int level) { @@ -915,10 +812,13 @@ API_EXPORTED void fp_set_debug(int level) libusb_set_debug(fpi_usb_ctx, level); } -/** \ingroup core +/** + * fp_init: + * * Initialise libfprint. This function must be called before you attempt to * use the library in any way. - * \return 0 on success, non-zero on error. + * + * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_init(void) { @@ -943,7 +843,9 @@ API_EXPORTED int fp_init(void) return 0; } -/** \ingroup core +/** + * fp_exit: + * * Deinitialise libfprint. This function should be called during your program * exit sequence. You must not use any libfprint functions after calling this * function, unless you call fp_init() again. diff --git a/libfprint/data.c b/libfprint/data.c index 70f020f7..92fd7be6 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -32,8 +32,11 @@ #define DIR_PERMS 0700 -/** @defgroup print_data Stored prints - * Stored prints are represented by a structure named fp_print_data. +/** + * SECTION: print_data + * @title: Stored prints + * + * Stored prints are represented by a structure named #fp_print_data. * Stored prints are originally obtained from an enrollment function such as * fp_enroll_finger(). * @@ -124,14 +127,17 @@ struct fp_print_data *fpi_print_data_new(struct fp_dev *dev) fpi_driver_get_data_type(dev->drv)); } -/** \ingroup print_data +/** + * fp_print_data_get_data: + * @data: the stored print + * @ret: output location for the data buffer. Must be freed with free() + * after use. + * Convert a stored print into a unified representation inside a data buffer. * You can then store this data buffer in any way that suits you, and load * it back at some later time using fp_print_data_from_data(). - * \param data the stored print - * \param ret output location for the data buffer. Must be freed with free() - * after use. - * \returns the size of the freshly allocated buffer, or 0 on error. + * + * Returns: the size of the freshly allocated buffer, or 0 on error. */ API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data, unsigned char **ret) @@ -245,13 +251,16 @@ static struct fp_print_data *fpi_print_data_from_fp2_data(unsigned char *buf, } -/** \ingroup print_data +/** + * fp_print_data_from_data: + * @buf: the data buffer + * @buflen: the length of the buffer + * Load a stored print from a data buffer. The contents of said buffer must * be the untouched contents of a buffer previously supplied to you by the * fp_print_data_get_data() function. - * \param buf the data buffer - * \param buflen the length of the buffer - * \returns the stored print represented by the data, or NULL on error. Must + * + * Returns: the stored print represented by the data, or %NULL on error. Must * be freed with fp_print_data_free() after use. */ API_EXPORTED struct fp_print_data *fp_print_data_from_data(unsigned char *buf, @@ -305,7 +314,11 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger) return __get_path_to_print(dev->drv->id, dev->devtype, finger); } -/** \ingroup print_data +/** + * fp_print_data_save: + * @data: the stored print to save to disk + * @finger: the finger that this print corresponds to + * * Saves a stored print to disk, assigned to a specific finger. Even though * you are limited to storing only the 10 human fingers, this is a * per-device-type limit. For example, you can store the users right index @@ -316,9 +329,8 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger) * This function will unconditionally overwrite a fingerprint previously * saved for the same finger and device type. The print is saved in a hidden * directory beneath the current user's home directory. - * \param data the stored print to save to disk - * \param finger the finger that this print corresponds to - * \returns 0 on success, non-zero on error. + * + * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_print_data_save(struct fp_print_data *data, enum fp_finger finger) @@ -415,7 +427,13 @@ static int load_from_file(char *path, struct fp_print_data **data) return 0; } -/** \ingroup print_data +/** + * fp_print_data_load: + * @dev: the device you are loading the print for + * @finger: the finger of the file you are loading + * @data: output location to put the corresponding stored print. Must be + * freed with fp_print_data_free() after use. + * Loads a previously stored print from disk. The print must have been saved * earlier using the fp_print_data_save() function. * @@ -423,11 +441,7 @@ static int load_from_file(char *path, struct fp_print_data **data) * be found. Other error codes (both positive and negative) are possible for * obscure error conditions (e.g. corruption). * - * \param dev the device you are loading the print for - * \param finger the finger of the file you are loading - * \param data output location to put the corresponding stored print. Must be - * freed with fp_print_data_free() after use. - * \returns 0 on success, non-zero on error + * Returns: 0 on success, non-zero on error */ API_EXPORTED int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data) @@ -455,11 +469,14 @@ API_EXPORTED int fp_print_data_load(struct fp_dev *dev, return 0; } -/** \ingroup print_data +/** + * fp_print_data_delete: + * @dev: the device that the print belongs to + * @finger: the finger of the file you are deleting + * Removes a stored print from disk previously saved with fp_print_data_save(). - * \param dev the device that the print belongs to - * \param finger the finger of the file you are deleting - * \returns 0 on success, negative on error + * + * Returns: 0 on success, negative on error */ API_EXPORTED int fp_print_data_delete(struct fp_dev *dev, enum fp_finger finger) @@ -477,18 +494,20 @@ API_EXPORTED int fp_print_data_delete(struct fp_dev *dev, return r; } -/** \ingroup print_data - * Attempts to load a stored print based on a \ref dscv_print +/** + * fp_print_data_from_dscv_print: + * @print: the discovered print + * @data: output location to point to the corresponding stored print. Must + * be freed with fp_print_data_free() after use. + + * Attempts to load a stored print based on a #fp_dscv_print * "discovered print" record. * * A return code of -ENOENT indicates that the file referred to by the * discovered print could not be found. Other error codes (both positive and * negative) are possible for obscure error conditions (e.g. corruption). * - * \param print the discovered print - * \param data output location to point to the corresponding stored print. Must - * be freed with fp_print_data_free() after use. - * \returns 0 on success, non-zero on error. + * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print, struct fp_print_data **data) @@ -496,9 +515,11 @@ API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print, return load_from_file(print->path, data); } -/** \ingroup print_data +/** + * fp_print_data_free: + * @data: the stored print to destroy. If NULL, function simply returns. + * * Frees a stored print. Must be called when you are finished using the print. - * \param data the stored print to destroy. If NULL, function simply returns. */ API_EXPORTED void fp_print_data_free(struct fp_print_data *data) { @@ -507,31 +528,40 @@ API_EXPORTED void fp_print_data_free(struct fp_print_data *data) g_free(data); } -/** \ingroup print_data - * Gets the \ref driver_id "driver ID" for a stored print. The driver ID +/** + * fp_print_data_get_driver_id: + * @data: the stored print + + * Gets the [driver ID](advanced-topics.html#driver_id) for a stored print. The driver ID * indicates which driver the print originally came from. The print is * only usable with a device controlled by that driver. - * \param data the stored print - * \returns the driver ID of the driver compatible with the print + * + * Returns: the driver ID of the driver compatible with the print */ API_EXPORTED uint16_t fp_print_data_get_driver_id(struct fp_print_data *data) { return data->driver_id; } -/** \ingroup print_data - * Gets the \ref devtype "devtype" for a stored print. The devtype represents +/** + * fp_print_data_get_devtype: + * @data: the stored print + + * Gets the [devtype](advanced-topics.html#device-types) for a stored print. The devtype represents * which type of device under the parent driver is compatible with the print. - * \param data the stored print - * \returns the devtype of the device range compatible with the print + * + * Returns: the devtype of the device range compatible with the print */ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data) { return data->devtype; } -/** @defgroup dscv_print Print discovery - * The \ref print_data "stored print" documentation detailed a simple API +/** + * SECTION:dscv_print + * @title: Print discovery + * + * The [stored print](libfprint-Stored-prints.html) documentation detailed a simple API * for storing per-device prints for a single user, namely * fp_print_data_save(). It also detailed a load function, * fp_print_data_load(), but usage of this function is limited to scenarios @@ -542,7 +572,7 @@ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data) * previously saved prints, potentially even before device discovery. These * functions are designed to offer this functionality to you. * - * Discovered prints are stored in a dscv_print structure, and you + * Discovered prints are stored in a #fp_dscv_print structure, and you * can use functions documented below to access some information about these * prints. You can determine if a discovered print appears to be compatible * with a device using functions such as fp_dscv_dev_supports_dscv_print() and @@ -643,10 +673,13 @@ static GSList *scan_driver_store_dir(char *drvpath, uint16_t driver_id, return list; } -/** \ingroup dscv_print +/** + * fp_discover_prints: + * * Scans the users home directory and returns a list of prints that were * previously saved using fp_print_data_save(). - * \returns a NULL-terminated list of discovered prints, must be freed with + * + * Returns: a %NULL-terminated list of discovered prints, must be freed with * fp_dscv_prints_free() after use. */ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void) @@ -704,12 +737,14 @@ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void) return list; } -/** \ingroup dscv_print +/** + * fp_dscv_prints_free: + * @prints: the list of discovered prints. If NULL, function simply + * returns. + * * Frees a list of discovered prints. This function also frees the discovered * prints themselves, so make sure you do not use any discovered prints * after calling this function. - * \param prints the list of discovered prints. If NULL, function simply - * returns. */ API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints) { @@ -727,47 +762,59 @@ API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints) g_free(prints); } -/** \ingroup dscv_print - * Gets the \ref driver_id "driver ID" for a discovered print. The driver ID +/** + * fp_dscv_print_get_driver_id: + * @print: the discovered print + * + * Gets the [driver ID](advanced-topics.html#driver_id) for a discovered print. The driver ID * indicates which driver the print originally came from. The print is only * usable with a device controlled by that driver. - * \param print the discovered print - * \returns the driver ID of the driver compatible with the print + * + * Returns: the driver ID of the driver compatible with the print */ API_EXPORTED uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print) { return print->driver_id; } -/** \ingroup dscv_print - * Gets the \ref devtype "devtype" for a discovered print. The devtype +/** + * fp_dscv_print_get_devtype: + * @print: the discovered print + * + * Gets the [devtype](advanced-topics.html#device-types) for a discovered print. The devtype * represents which type of device under the parent driver is compatible * with the print. - * \param print the discovered print - * \returns the devtype of the device range compatible with the print + * + * Returns: the devtype of the device range compatible with the print */ API_EXPORTED uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print) { return print->devtype; } -/** \ingroup dscv_print +/** + * fp_dscv_print_get_finger: + * @print: discovered print + * * Gets the finger code for a discovered print. - * \param print discovered print - * \returns a finger code from #fp_finger + * + * Returns: a finger code from #fp_finger */ API_EXPORTED enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print) { return print->finger; } -/** \ingroup dscv_print +/** + * fp_dscv_print_delete: + * @print: the discovered print to remove from disk + * * Removes a discovered print from disk. After successful return of this * function, functions such as fp_dscv_print_get_finger() will continue to * operate as before, however calling fp_print_data_from_dscv_print() will * fail for obvious reasons. - * \param print the discovered print to remove from disk - * \returns 0 on success, negative on error + * + * Returns: 0 on success, negative on error */ API_EXPORTED int fp_dscv_print_delete(struct fp_dscv_print *print) { diff --git a/libfprint/fprint.h b/libfprint/fprint.h index af1d686b..46017aca 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -27,42 +27,86 @@ extern "C" { #include #include -/* structs that applications are not allowed to peek into */ +/** + * fp_dscv_dev: + * + */ struct fp_dscv_dev; + +/** + * fp_dscv_print: + * + */ struct fp_dscv_print; + +/** + * fp_dev: + * + */ struct fp_dev; + +/** + * fp_driver: + * + */ struct fp_driver; + +/** + * fp_print_data: + * + */ struct fp_print_data; + +/** + * fp_img: + * + */ struct fp_img; /* misc/general stuff */ -/** \ingroup print_data +/** + * fp_finger: + * @LEFT_THUMB: Left thumb + * @LEFT_INDEX: Left index finger + * @LEFT_MIDDLE: Left middle finger + * @LEFT_RING: Left ring finger + * @LEFT_LITTLE: Left little finger + * @RIGHT_THUMB: Right thumb + * @RIGHT_INDEX: Right index finger + * @RIGHT_MIDDLE: Right middle finger + * @RIGHT_RING: Right ring finger + * @RIGHT_LITTLE: Right little finger + * * Numeric codes used to refer to fingers (and thumbs) of a human. These are * purposely not available as strings, to avoid getting the library tangled up * in localization efforts. */ enum fp_finger { - LEFT_THUMB = 1, /** thumb (left hand) */ - LEFT_INDEX, /** index finger (left hand) */ - LEFT_MIDDLE, /** middle finger (left hand) */ - LEFT_RING, /** ring finger (left hand) */ - LEFT_LITTLE, /** little finger (left hand) */ - RIGHT_THUMB, /** thumb (right hand) */ - RIGHT_INDEX, /** index finger (right hand) */ - RIGHT_MIDDLE, /** middle finger (right hand) */ - RIGHT_RING, /** ring finger (right hand) */ - RIGHT_LITTLE, /** little finger (right hand) */ + LEFT_THUMB = 1, + LEFT_INDEX, + LEFT_MIDDLE, + LEFT_RING, + LEFT_LITTLE, + RIGHT_THUMB, + RIGHT_INDEX, + RIGHT_MIDDLE, + RIGHT_RING, + RIGHT_LITTLE, }; -/** \ingroup dev +/** + * fp_scan_type: + * @FP_SCAN_TYPE_PRESS: the reader has a surface area that covers the whole finger + * @FP_SCAN_TYPE_SWIPE: the reader requires swiping the finger on a smaller area + * * Numeric codes used to refer to the scan type of the device. Devices require * either swiping or pressing the finger on the device. This is useful for * front-ends. */ enum fp_scan_type { - FP_SCAN_TYPE_PRESS = 0, /** press */ - FP_SCAN_TYPE_SWIPE, /** swipe */ + FP_SCAN_TYPE_PRESS = 0, + FP_SCAN_TYPE_SWIPE, }; /* Drivers */ @@ -85,6 +129,12 @@ struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs, struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs, struct fp_dscv_print *print); +/** + * fp_dscv_dev_get_driver_id: + * @dev: a discovered fingerprint device + * + * Returns: the ID for the underlying driver for that device + */ static inline uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev) { return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)); @@ -107,68 +157,75 @@ uint32_t fp_dev_get_devtype(struct fp_dev *dev); int fp_dev_supports_print_data(struct fp_dev *dev, struct fp_print_data *data); int fp_dev_supports_dscv_print(struct fp_dev *dev, struct fp_dscv_print *print); -/** \ingroup dev - * Image capture result codes returned from fp_dev_img_capture(). +/** + * fp_capture_result: + * Whether a capture failed or completed. + * + * @FP_CAPTURE_COMPLETE: Capture completed successfully, the capture data has been returned to the caller. + * @FP_CAPTURE_FAIL: Capture failed + * */ enum fp_capture_result { - /** Capture completed successfully, the capture data has been - * returned to the caller. */ FP_CAPTURE_COMPLETE = 0, - /** Capture failed for some reason */ FP_CAPTURE_FAIL, }; int fp_dev_supports_imaging(struct fp_dev *dev); int fp_dev_img_capture(struct fp_dev *dev, int unconditional, - struct fp_img **image); + struct fp_img **img); int fp_dev_get_img_width(struct fp_dev *dev); int fp_dev_get_img_height(struct fp_dev *dev); -/** \ingroup dev +/** + * fp_enroll_result: + * @FP_ENROLL_COMPLETE: Enrollment completed successfully, the enrollment data has been + * returned to the caller. + * @FP_ENROLL_FAIL: Enrollment failed due to incomprehensible data; this may occur when + * the user scans a different finger on each enroll stage. + * @FP_ENROLL_PASS: Enroll stage passed; more stages are need to complete the process. + * @FP_ENROLL_RETRY: The enrollment scan did not succeed due to poor scan quality or + * other general user scanning problem. + * @FP_ENROLL_RETRY_TOO_SHORT: The enrollment scan did not succeed because the finger swipe was + * too short. + * @FP_ENROLL_RETRY_CENTER_FINGER: The enrollment scan did not succeed because the finger was not + * centered on the scanner. + * @FP_ENROLL_RETRY_REMOVE_FINGER: The verification scan did not succeed due to quality or pressure + * problems; the user should remove their finger from the scanner before + * retrying. + * + * * Enrollment result codes returned from fp_enroll_finger(). * Result codes with RETRY in the name suggest that the scan failed due to * user error. Applications will generally want to inform the user of the * problem and then retry the enrollment stage. For more info on the semantics * of interpreting these result codes and tracking enrollment process, see - * \ref enrolling. + * [Enrolling](libfprint-Devices-operations.html#enrolling) */ enum fp_enroll_result { - /** Enrollment completed successfully, the enrollment data has been - * returned to the caller. */ FP_ENROLL_COMPLETE = 1, - /** Enrollment failed due to incomprehensible data; this may occur when - * the user scans a different finger on each enroll stage. */ FP_ENROLL_FAIL, - /** Enroll stage passed; more stages are need to complete the process. */ FP_ENROLL_PASS, - /** The enrollment scan did not succeed due to poor scan quality or - * other general user scanning problem. */ FP_ENROLL_RETRY = 100, - /** The enrollment scan did not succeed because the finger swipe was - * too short. */ FP_ENROLL_RETRY_TOO_SHORT, - /** The enrollment scan did not succeed because the finger was not - * centered on the scanner. */ FP_ENROLL_RETRY_CENTER_FINGER, - /** The verification scan did not succeed due to quality or pressure - * problems; the user should remove their finger from the scanner before - * retrying. */ FP_ENROLL_RETRY_REMOVE_FINGER, }; int fp_enroll_finger_img(struct fp_dev *dev, struct fp_print_data **print_data, struct fp_img **img); -/** \ingroup dev - * Performs an enroll stage. See \ref enrolling for an explanation of enroll - * stages. This function is just a shortcut to calling fp_enroll_finger_img() - * with a NULL image parameter. Be sure to read the description of - * fp_enroll_finger_img() in order to understand its behaviour. - * - * \param dev the device - * \param print_data a location to return the resultant enrollment data from +/** + * fp_enroll_finger: + * @dev: the device + * @print_data: a location to return the resultant enrollment data from * the final stage. Must be freed with fp_print_data_free() after use. - * \return negative code on error, otherwise a code from #fp_enroll_result + * + * Performs an enroll stage. See [Enrolling](libfprint-Devices-operations.html#enrolling) + * for an explanation of enroll stages. This function is just a shortcut to + * calling fp_enroll_finger_img() with a %NULL image parameter. Be sure to read + * the description of fp_enroll_finger_img() in order to understand its behaviour. + * + * Returns: negative code on error, otherwise a code from #fp_enroll_result */ static inline int fp_enroll_finger(struct fp_dev *dev, struct fp_print_data **print_data) @@ -176,7 +233,23 @@ static inline int fp_enroll_finger(struct fp_dev *dev, return fp_enroll_finger_img(dev, print_data, NULL); } -/** \ingroup dev +/** + * fp_verify_result: + * @FP_VERIFY_NO_MATCH: The scan completed successfully, but the newly scanned fingerprint + * does not match the fingerprint being verified against. + * In the case of identification, this return code indicates that the + * scanned finger could not be found in the print gallery. + * @FP_VERIFY_MATCH: The scan completed successfully and the newly scanned fingerprint does + * match the fingerprint being verified, or in the case of identification, + * the scanned fingerprint was found in the print gallery. + * @FP_VERIFY_RETRY: The scan did not succeed due to poor scan quality or other general + * user scanning problem. + * @FP_VERIFY_RETRY_TOO_SHORT: The scan did not succeed because the finger swipe was too short. + * @FP_VERIFY_RETRY_CENTER_FINGER: The scan did not succeed because the finger was not centered on the + * scanner. + * @FP_VERIFY_RETRY_REMOVE_FINGER: The scan did not succeed due to quality or pressure problems; the user + * should remove their finger from the scanner before retrying. + * * Verification result codes returned from fp_verify_finger(). Return codes * are also shared with fp_identify_finger(). * Result codes with RETRY in the name suggest that the scan failed due to @@ -184,39 +257,28 @@ static inline int fp_enroll_finger(struct fp_dev *dev, * problem and then retry the verify operation. */ enum fp_verify_result { - /** The scan completed successfully, but the newly scanned fingerprint - * does not match the fingerprint being verified against. - * In the case of identification, this return code indicates that the - * scanned finger could not be found in the print gallery. */ FP_VERIFY_NO_MATCH = 0, - /** The scan completed successfully and the newly scanned fingerprint does - * match the fingerprint being verified, or in the case of identification, - * the scanned fingerprint was found in the print gallery. */ FP_VERIFY_MATCH = 1, - /** The scan did not succeed due to poor scan quality or other general - * user scanning problem. */ FP_VERIFY_RETRY = FP_ENROLL_RETRY, - /** The scan did not succeed because the finger swipe was too short. */ FP_VERIFY_RETRY_TOO_SHORT = FP_ENROLL_RETRY_TOO_SHORT, - /** The scan did not succeed because the finger was not centered on the - * scanner. */ FP_VERIFY_RETRY_CENTER_FINGER = FP_ENROLL_RETRY_CENTER_FINGER, - /** The scan did not succeed due to quality or pressure problems; the user - * should remove their finger from the scanner before retrying. */ FP_VERIFY_RETRY_REMOVE_FINGER = FP_ENROLL_RETRY_REMOVE_FINGER, }; int fp_verify_finger_img(struct fp_dev *dev, struct fp_print_data *enrolled_print, struct fp_img **img); -/** \ingroup dev +/** + * fp_verify_finger: + * @dev: the device to perform the scan. + * @enrolled_print: the print to verify against. Must have been previously + * enrolled with a device compatible to the device selected to perform the scan. + * * Performs a new scan and verify it against a previously enrolled print. This * function is just a shortcut to calling fp_verify_finger_img() with a NULL * image output parameter. - * \param dev the device to perform the scan. - * \param enrolled_print the print to verify against. Must have been previously - * enrolled with a device compatible to the device selected to perform the scan. - * \return negative code on error, otherwise a code from #fp_verify_result + * + * Returns: negative code on error, otherwise a code from #fp_verify_result * \sa fp_verify_finger_img() */ static inline int fp_verify_finger(struct fp_dev *dev, @@ -230,19 +292,22 @@ int fp_identify_finger_img(struct fp_dev *dev, struct fp_print_data **print_gallery, size_t *match_offset, struct fp_img **img); -/** \ingroup dev - * Performs a new scan and attempts to identify the scanned finger against a - * collection of previously enrolled fingerprints. This function is just a - * shortcut to calling fp_identify_finger_img() with a NULL image output - * parameter. - * \param dev the device to perform the scan. - * \param print_gallery NULL-terminated array of pointers to the prints to +/** + * fp_identify_finger: + * @dev: the device to perform the scan. + * @print_gallery: %NULL-terminated array of pointers to the prints to * identify against. Each one must have been previously enrolled with a device * compatible to the device selected to perform the scan. - * \param match_offset output location to store the array index of the matched + * @match_offset: output location to store the array index of the matched * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was * returned. - * \return negative code on error, otherwise a code from #fp_verify_result + + * Performs a new scan and attempts to identify the scanned finger against a + * collection of previously enrolled fingerprints. This function is just a + * shortcut to calling fp_identify_finger_img() with a %NULL image output + * parameter. + * + * Returns: negative code on error, otherwise a code from #fp_verify_result * \sa fp_identify_finger_img() */ static inline int fp_identify_finger(struct fp_dev *dev, @@ -267,7 +332,11 @@ uint32_t fp_print_data_get_devtype(struct fp_print_data *data); /* Image handling */ -/** \ingroup img */ +/** + * fp_minutia: + * + * FIXME + */ struct fp_minutia { int x; int y; @@ -294,6 +363,10 @@ void fp_img_free(struct fp_img *img); /* Polling and timing */ +/** + * fp_pollfd: + * + */ struct fp_pollfd { int fd; short events; diff --git a/libfprint/img.c b/libfprint/img.c index 408dd564..09cd2300 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -28,19 +28,22 @@ #include "nbis/include/bozorth.h" #include "nbis/include/lfs.h" -/** @defgroup img Image operations +/** + * SECTION:img + * @title: Image operations + * * libfprint offers several ways of retrieving images from imaging devices, * one example being the fp_dev_img_capture() function. The functions * documented below allow you to work with such images. * - * \section img_fmt Image format + * # Image format # {#img_fmt} * All images are represented as 8-bit greyscale data. * - * \section img_std Image standardization + * # Image standardization # {#img_std} * In some contexts, images you are provided through libfprint are raw images * from the hardware. The orientation of these varies from device-to-device, * as does the color scheme (black-on-white or white-on-black?). libfprint - * provides the fp_img_standardize function to convert images into standard + * provides the fp_img_standardize() function to convert images into standard * form, which is defined to be: finger flesh as black on white surroundings, * natural upright orientation. */ @@ -82,9 +85,11 @@ struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize) return g_realloc(img, sizeof(*img) + newsize); } -/** \ingroup img +/** + * fp_img_free: + * @img: the image to destroy. If NULL, function simply returns. + * * Frees an image. Must be called when you are finished working with an image. - * \param img the image to destroy. If NULL, function simply returns. */ API_EXPORTED void fp_img_free(struct fp_img *img) { @@ -98,43 +103,55 @@ API_EXPORTED void fp_img_free(struct fp_img *img) g_free(img); } -/** \ingroup img +/** + * fp_img_get_height: + * @img: an image + * * Gets the pixel height of an image. - * \param img an image - * \returns the height of the image + * + * Returns: the height of the image */ API_EXPORTED int fp_img_get_height(struct fp_img *img) { return img->height; } -/** \ingroup img +/** + * fp_img_get_width: + * @img: an image + * * Gets the pixel width of an image. - * \param img an image - * \returns the width of the image + * + * Returns: the width of the image */ API_EXPORTED int fp_img_get_width(struct fp_img *img) { return img->width; } -/** \ingroup img +/** + * fp_img_get_data: + * @img: an image + * * Gets the greyscale data for an image. This data must not be modified or * freed, and must not be used after fp_img_free() has been called. - * \param img an image - * \returns a pointer to libfprint's internal data for the image + * + * Returns: a pointer to libfprint's internal data for the image */ API_EXPORTED unsigned char *fp_img_get_data(struct fp_img *img) { return img->data; } -/** \ingroup img +/** + * fp_img_save_to_file: + * @img: the image to save + * @path: the path to save the image. Existing files will be overwritten. + * * A quick convenience function to save an image to a file in - * PGM format. - * \param img the image to save - * \param path the path to save the image. Existing files will be overwritten. - * \returns 0 on success, non-zero on error. + * [PGM format](http://netpbm.sourceforge.net/doc/pgm.html). + * + * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_img_save_to_file(struct fp_img *img, char *path) { @@ -209,12 +226,14 @@ static void invert_colors(struct fp_img *img) img->data[i] = 0xff - img->data[i]; } -/** \ingroup img - * \ref img_std "Standardizes" an image by normalizing its orientation, colors, +/** + * fp_img_standardize: + * @img: the image to standardize + * + * [Standardizes](libfprint-Image-operations.html#img_std) an image by normalizing its orientation, colors, * etc. It is safe to call this multiple times on an image, libfprint keeps * track of the work it needs to do to make an image standard and will not * perform these operations more than once for a given image. - * \param img the image to standardize */ API_EXPORTED void fp_img_standardize(struct fp_img *img) { @@ -419,23 +438,25 @@ int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, return FP_VERIFY_NO_MATCH; } -/** \ingroup img +/** + * fp_img_binarize: + * @img: a standardized image + * * Get a binarized form of a standardized scanned image. This is where the * fingerprint image has been "enhanced" and is a set of pure black ridges * on a pure white background. Internally, image processing happens on top * of the binarized image. * - * The image must have been \ref img_std "standardized" otherwise this function - * will fail. + * The image must have been [standardized](libfprint-Image-operations.html#img_std) + * otherwise this function will fail. * * It is safe to binarize an image and free the original while continuing * to use the binarized version. * * You cannot binarize an image twice. * - * \param img a standardized image - * \returns a new image representing the binarized form of the original, or - * NULL on error. Must be freed with fp_img_free() after use. + * Returns: a new image representing the binarized form of the original, or + * %NULL on error. Must be freed with fp_img_free() after use. */ API_EXPORTED struct fp_img *fp_img_binarize(struct fp_img *img) { @@ -467,15 +488,19 @@ API_EXPORTED struct fp_img *fp_img_binarize(struct fp_img *img) return ret; } -/** \ingroup img +/** + * fp_img_get_minutiae: + * @img: a standardized image + * @nr_minutiae: an output location to store minutiae list length + * * Get a list of minutiae detected in an image. A minutia point is a feature * detected on a fingerprint, typically where ridges end or split. * libfprint's image processing code relies upon comparing sets of minutiae, * so accurate placement of minutia points is critical for good imaging * performance. * - * The image must have been \ref img_std "standardized" otherwise this function - * will fail. + * The image must have been [standardized](libfprint-Image-operations.html#img_std) + * otherwise this function will fail. * * You cannot pass a binarized image to this function. Instead, pass the * original image. @@ -485,9 +510,7 @@ API_EXPORTED struct fp_img *fp_img_binarize(struct fp_img *img) * valid while the parent image has not been freed, and the minutiae data * must not be modified or freed. * - * \param img a standardized image - * \param nr_minutiae an output location to store minutiae list length - * \returns a list of minutiae points. Must not be modified or freed. + * Returns: a list of minutiae points. Must not be modified or freed. */ API_EXPORTED struct fp_minutia **fp_img_get_minutiae(struct fp_img *img, int *nr_minutiae) diff --git a/libfprint/poll.c b/libfprint/poll.c index e849ea4f..aad81d16 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -30,7 +30,9 @@ #include "fp_internal.h" /** - * @defgroup poll Polling and timing operations + * SECTION:events + * @title: Initialisation and events handling + * * These functions are only applicable to users of libfprint's asynchronous * API. * @@ -50,10 +52,10 @@ * If there are no events pending, fp_handle_events() will block for a few * seconds (and will handle any new events should anything occur in that time). * If you wish to customise this timeout, you can use - * fp_handle_events_timeout() instead. If you wish to do a nonblocking + * fp_handle_events_timeout() instead. If you wish to do a non-blocking * iteration, call fp_handle_events_timeout() with a zero timeout. * - * TODO: document how application is supposed to know when to call these + * FIXME: document how application is supposed to know when to call these * functions. */ @@ -192,14 +194,16 @@ static int handle_timeouts(void) return 0; } -/** \ingroup poll +/** + * fp_handle_events_timeout: + * @timeout: Maximum timeout for this blocking function + * * Handle any pending events. If a non-zero timeout is specified, the function * will potentially block for the specified amount of time, although it may * return sooner if events have been handled. The function acts as non-blocking * for a zero timeout. * - * \param timeout Maximum timeout for this blocking function - * \returns 0 on success, non-zero on error. + * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_handle_events_timeout(struct timeval *timeout) { @@ -236,12 +240,14 @@ API_EXPORTED int fp_handle_events_timeout(struct timeval *timeout) return handle_timeouts(); } -/** \ingroup poll +/** + * fp_handle_events: + * * Convenience function for calling fp_handle_events_timeout() with a sensible * default timeout value of two seconds (subject to change if we decide another * value is more sensible). * - * \returns 0 on success, non-zero on error. + * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_handle_events(void) { @@ -251,10 +257,14 @@ API_EXPORTED int fp_handle_events(void) return fp_handle_events_timeout(&tv); } -/* FIXME: docs - * returns 0 if no timeouts active - * returns 1 if timeout returned - * zero timeout means events are to be handled immediately */ +/** + * fp_get_next_timeout: + * @tv: a %timeval structure containing the duration to the next timeout. + * + * A zero filled @tv timeout means events are to be handled immediately + * + * Returns: returns 0 if no timeouts active, or 1 if timeout returned. + */ API_EXPORTED int fp_get_next_timeout(struct timeval *tv) { struct timeval fprint_timeout; @@ -286,16 +296,18 @@ API_EXPORTED int fp_get_next_timeout(struct timeval *tv) return 1; } -/** \ingroup poll +/** + * fp_get_pollfds: + * @pollfds: output location for a list of pollfds. If non-%NULL, must be + * released with free() when done. + * * Retrieve a list of file descriptors that should be polled for events * interesting to libfprint. This function is only for users who wish to * combine libfprint's file descriptor set with other event sources - more * simplistic users will be able to call fp_handle_events() or a variant * directly. * - * \param pollfds output location for a list of pollfds. If non-NULL, must be - * released with free() when done. - * \returns the number of pollfds in the resultant list, or negative on error. + * Returns: the number of pollfds in the resultant list, or negative on error. */ API_EXPORTED size_t fp_get_pollfds(struct fp_pollfd **pollfds) { @@ -326,7 +338,12 @@ API_EXPORTED size_t fp_get_pollfds(struct fp_pollfd **pollfds) return cnt; } -/* FIXME: docs */ +/** + * fp_set_pollfd_notifiers: + * @added_cb: + * @removed_cb: + * + */ API_EXPORTED void fp_set_pollfd_notifiers(fp_pollfd_added_cb added_cb, fp_pollfd_removed_cb removed_cb) { diff --git a/libfprint/sync.c b/libfprint/sync.c index b3b28983..ad1a7946 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -37,12 +37,15 @@ static void sync_open_cb(struct fp_dev *dev, int status, void *user_data) odata->status = status; } -/** \ingroup dev +/** + * fp_dev_open: + * @ddev: the discovered device to open + * * Opens and initialises a device. This is the function you call in order - * to convert a \ref dscv_dev "discovered device" into an actual device handle + * to convert a #fp_dscv_dev "discovered device" into an actual device handle * that you can perform operations with. - * \param ddev the discovered device to open - * \returns the opened device handle, or NULL on error + * + * Returns: (transfer none): the opened device handle, or %NULL on error */ API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev) { @@ -76,10 +79,12 @@ static void sync_close_cb(struct fp_dev *dev, void *user_data) *closed = TRUE; } -/** \ingroup dev +/** + * fp_dev_close: + * @dev: the device to close. If %NULL, function simply returns. + * * Close a device. You must call this function when you are finished using * a fingerprint device. - * \param dev the device to close. If NULL, function simply returns. */ API_EXPORTED void fp_dev_close(struct fp_dev *dev) { @@ -120,9 +125,17 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data) *stopped = TRUE; } -/** \ingroup dev - * Performs an enroll stage. See \ref enrolling for an explanation of enroll - * stages. +/** + * fp_enroll_finger_img: + * @dev: the device + * @print_data a location to return the resultant enrollment data from + * the final stage. Must be freed with fp_print_data_free() after use. + * @img: location to store the scan image. accepts %NULL for no image + * storage. If an image is returned, it must be freed with fp_img_free() after + * use. + * + * Performs an enroll stage. See [Enrolling](libfprint-Devices-operations.html#enrolling) + * for an explanation of enroll stages. * * If no enrollment is in process, this kicks of the process and runs the * first stage. If an enrollment is already in progress, calling this @@ -137,7 +150,7 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data) * 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 * 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 + * 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 * need to be retried several times. * @@ -159,19 +172,13 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data) * resultant enrollment data. The print_data parameter will not be modified * during any other enrollment stages, hence it is actually legal to pass NULL * as this argument for all but the final stage. - * + * * If the device is an imaging device, it can also return the image from * the scan, even when the enroll fails with a RETRY or FAIL code. It is legal * to call this function even on non-imaging devices, just don't expect them to * provide images. * - * \param dev the device - * \param print_data a location to return the resultant enrollment data from - * the final stage. Must be freed with fp_print_data_free() after use. - * \param img location to store the scan image. accepts NULL for no image - * storage. If an image is returned, it must be freed with fp_img_free() after - * use. - * \return negative code on error, otherwise a code from #fp_enroll_result + * Returns: negative code on error, otherwise a code from #fp_enroll_result */ API_EXPORTED int fp_enroll_finger_img(struct fp_dev *dev, struct fp_print_data **print_data, struct fp_img **img) @@ -302,20 +309,22 @@ static void verify_stop_cb(struct fp_dev *dev, void *user_data) *stopped = TRUE; } -/** \ingroup dev +/** + * fp_verify_finger_img: + * @dev: the device to perform the scan. + * @enrolled_print: the print to verify against. Must have been previously + * enrolled with a device compatible to the device selected to perform the scan. + * @img: location to store the scan image. accepts %NULL for no image + * storage. If an image is returned, it must be freed with fp_img_free() after + * use. + * Performs a new scan and verify it against a previously enrolled print. * If the device is an imaging device, it can also return the image from * the scan, even when the verify fails with a RETRY code. It is legal to * call this function even on non-imaging devices, just don't expect them to * provide images. * - * \param dev the device to perform the scan. - * \param enrolled_print the print to verify against. Must have been previously - * enrolled with a device compatible to the device selected to perform the scan. - * \param img location to store the scan image. accepts NULL for no image - * storage. If an image is returned, it must be freed with fp_img_free() after - * use. - * \return negative code on error, otherwise a code from #fp_verify_result + * Returns: negative code on error, otherwise a code from #fp_verify_result */ API_EXPORTED int fp_verify_finger_img(struct fp_dev *dev, struct fp_print_data *enrolled_print, struct fp_img **img) @@ -416,7 +425,19 @@ static void identify_stop_cb(struct fp_dev *dev, void *user_data) *stopped = TRUE; } -/** \ingroup dev +/** + * fp_identify_finger_img: + * @dev: the device to perform the scan. + * @print_gallery: NULL-terminated array of pointers to the prints to + * identify against. Each one must have been previously enrolled with a device + * compatible to the device selected to perform the scan. + * @match_offset: output location to store the array index of the matched + * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was + * returned. + * @img: location to store the scan image. accepts %NULL for no image + * storage. If an image is returned, it must be freed with fp_img_free() after + * use. + * Performs a new scan and attempts to identify the scanned finger against * a collection of previously enrolled fingerprints. * If the device is an imaging device, it can also return the image from @@ -435,17 +456,7 @@ static void identify_stop_cb(struct fp_dev *dev, void *user_data) * Not all devices support identification. -ENOTSUP will be returned when * this is the case. * - * \param dev the device to perform the scan. - * \param print_gallery NULL-terminated array of pointers to the prints to - * identify against. Each one must have been previously enrolled with a device - * compatible to the device selected to perform the scan. - * \param match_offset output location to store the array index of the matched - * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was - * returned. - * \param img location to store the scan image. accepts NULL for no image - * storage. If an image is returned, it must be freed with fp_img_free() after - * use. - * \return negative code on error, otherwise a code from #fp_verify_result + * Returns: negative code on error, otherwise a code from #fp_verify_result */ API_EXPORTED int fp_identify_finger_img(struct fp_dev *dev, struct fp_print_data **print_gallery, size_t *match_offset, @@ -533,23 +544,26 @@ static void capture_stop_cb(struct fp_dev *dev, void *user_data) fp_dbg(""); *stopped = TRUE; } -/** \ingroup dev - * Captures an \ref img "image" from a device. The returned image is the raw - * image provided by the device, you may wish to \ref img_std "standardize" it. +/** + * fp_dev_img_capture: + * @dev: the device + * @unconditional: whether to unconditionally capture an image, or to only capture when a finger is detected + * @img: a location to return the captured image. Must be freed with + * fp_img_free() after use. * - * If set, the unconditional flag indicates that the device should + * Captures a #fp_img "image" from a device. The returned image is the raw + * image provided by the device, you may wish to [standardize](libfprint-Image-operations.html#img_std) it. + * + * If set, the @unconditional flag indicates that the device should * capture an image unconditionally, regardless of whether a finger is there * or not. If unset, this function will block until a finger is detected on * the sensor. * - * \param dev the device - * \param unconditional whether to unconditionally capture an image, or to only capture when a finger is detected - * \param img a location to return the captured image. Must be freed with - * fp_img_free() after use. - * \return 0 on success, non-zero on error. -ENOTSUP indicates that either the - * unconditional flag was set but the device does not support this, or that the + * See fp_dev_supports_imaging(). + * + * Returns: 0 on success, non-zero on error. -ENOTSUP indicates that either the + * @unconditional flag was set but the device does not support this, or that the * device does not support imaging. - * \sa fp_dev_supports_imaging() */ API_EXPORTED int fp_dev_img_capture(struct fp_dev *dev, int unconditional, struct fp_img **img) diff --git a/meson.build b/meson.build index f30732a1..a9abc3f2 100644 --- a/meson.build +++ b/meson.build @@ -101,9 +101,12 @@ endif libfprint_conf.set('API_EXPORTED', '__attribute__((visibility("default")))') configure_file(output: 'config.h', configuration: libfprint_conf) -subdir('doc') subdir('libfprint') subdir('examples') +if get_option('doc') + gnome = import('gnome') + subdir('doc') +endif pkgconfig = import('pkgconfig') pkgconfig.generate( diff --git a/meson_options.txt b/meson_options.txt index 709e0eac..ee442c3c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -22,3 +22,7 @@ option('debug_log', description: 'Debug message logging', type: 'boolean', value: false) +option('doc', + description: 'Whether to build the API documentation', + type: 'boolean', + value: true) From f59bf389d92fed713f019e3cf0d989bdab9a748f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 18 May 2018 01:16:30 +0200 Subject: [PATCH 056/141] INSTALL: Update for Meson --- INSTALL | 238 ++------------------------------------------------------ 1 file changed, 5 insertions(+), 233 deletions(-) diff --git a/INSTALL b/INSTALL index 5458714e..99b92f81 100644 --- a/INSTALL +++ b/INSTALL @@ -1,234 +1,6 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. +libfprint uses the Meson build system. See +http://mesonbuild.com/Quick-guide.html for details on how to +compile libfprint. +The "meson configure" command will give you a list of available +command-line options. From b3fe4a1e912a6c53243a3fd994f9cf01178a9523 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 18 May 2018 05:51:58 +0200 Subject: [PATCH 057/141] docs: Update API documentation Fixes to layout, dead links, typography, and more. Thanks to Benjamin Berg for the thorough review --- doc/advanced-topics.xml | 6 +++--- doc/getting-started.xml | 6 +++--- doc/intro.xml | 2 +- doc/libfprint-docs.xml | 4 ++-- libfprint/core.c | 16 ++++++++-------- libfprint/data.c | 2 +- libfprint/poll.c | 2 +- libfprint/sync.c | 12 ++++++------ 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/doc/advanced-topics.xml b/doc/advanced-topics.xml index bc674573..958d2d53 100644 --- a/doc/advanced-topics.xml +++ b/doc/advanced-topics.xml @@ -60,7 +60,7 @@ In summary, libfprint represents fingerprints in several internal structures and each representation will offer you a way of determining the - \ref driver_id "driver ID" and \ref devtype "devtype" of the print in + driver ID and devtype of the print in question. Prints are only compatible if the driver ID and devtypes match. libfprint does offer you some "is this print compatible?" helper functions, so you don't have to worry about these details too much. @@ -73,7 +73,7 @@ Each driver is assigned a unique ID by the project maintainer. These assignments are - + documented on the wiki and will never change. @@ -93,7 +93,7 @@ Device types - Internally, the \ref drv "driver" behind a device assigns a 32-bit + Internally, the driver behind a device assigns a 32-bit devtype identifier to the device. This cannot be used as a unique ID for a specific device as many devices under the same range may share the same devtype. The devtype may even be 0 in all cases. diff --git a/doc/getting-started.xml b/doc/getting-started.xml index 5c2d2080..8ed8592b 100644 --- a/doc/getting-started.xml +++ b/doc/getting-started.xml @@ -6,19 +6,19 @@ Getting Started - libfprint includes several simple functional examples under the examples/ + libfprint includes several simple functional examples under the examples/ directory in the libfprint source distribution. Those are good starting points. Usually the first thing you want to do is determine which fingerprint - devices are present. This is done through \ref dscv_dev "device discovery". + devices are present. This is done through device discovery. Once you have found a device you would like to operate, you should open it. - Refer to \ref dev "device operations". This section also details enrollment, + Refer to device operations. This section also details enrollment, image capture, and verification. diff --git a/doc/intro.xml b/doc/intro.xml index cfd91008..5b9e5ece 100644 --- a/doc/intro.xml +++ b/doc/intro.xml @@ -14,7 +14,7 @@ This documentation is aimed at application developers who wish to integrate fingerprint-related functionality into their software. libfprint has been - designed so that you only have to do this once - by integrating your + designed so that you only have to do this once – by integrating your software with libfprint, you'll be supporting all the fingerprint readers that we have got our hands on. As such, the API is rather general (and therefore hopefully easy to comprehend!), and does its best to hide the diff --git a/doc/libfprint-docs.xml b/doc/libfprint-docs.xml index 8a0ff38b..fd674ec4 100644 --- a/doc/libfprint-docs.xml +++ b/doc/libfprint-docs.xml @@ -31,8 +31,8 @@ - + + diff --git a/libfprint/core.c b/libfprint/core.c index e22b3bb5..c2867a09 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -446,7 +446,7 @@ API_EXPORTED void fp_dscv_devs_free(struct fp_dscv_dev **devs) * fp_dscv_dev_get_driver: * @dev: the discovered device * - * Gets the #fp_driver "driver" for a discovered device. + * Gets the #fp_driver for a discovered device. * * Returns: the driver backing the device */ @@ -486,7 +486,7 @@ enum fp_print_data_type fpi_driver_get_data_type(struct fp_driver *drv) * @dev: the discovered device * @print: the print for compatibility checking * - * Determines if a specific #fp_print_data "stored print" appears to be + * Determines if a specific #fp_print_data stored print appears to be * compatible with a discovered device. * * Returns: 1 if the print is compatible with the device, 0 otherwise @@ -504,7 +504,7 @@ API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, * @dev: the discovered device * @print: the discovered print for compatibility checking * - * Determines if a specific #fp_dscv_print "discovered print" appears to be + * Determines if a specific #fp_dscv_print discovered print appears to be * compatible with a discovered device. * * Returns: 1 if the print is compatible with the device, 0 otherwise @@ -522,7 +522,7 @@ API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev, * @print: the print under inspection * * Searches a list of discovered devices for a device that appears to be - * compatible with a #fp_print_data "stored print". + * compatible with a #fp_print_data stored print. * * Returns: the first discovered device that appears to support the print, or * %NULL if no apparently compatible devices could be found @@ -545,7 +545,7 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev * * @print: the print under inspection * * Searches a list of discovered devices for a device that appears to be - * compatible with a #fp_dscv_print "discovered print". + * compatible with a #fp_dscv_print discovered print. * * Returns: the first discovered device that appears to support the print, or * %NULL if no apparently compatible devices could be found @@ -566,7 +566,7 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev * * fp_dev_get_driver: * @dev: the device * - * Get the #fp_driver "driver" for a fingerprint device. + * Get the #fp_driver for a fingerprint device. * * Returns: the driver controlling the device */ @@ -624,7 +624,7 @@ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev, * @dev: the device * @print: the discovered print * - * Determines if a #fp_dscv_print "discovered print" appears to be compatible + * Determines if a #fp_dscv_print discovered print appears to be compatible * with a certain device. * * Returns: 1 if the print is compatible with the device, 0 if not @@ -702,7 +702,7 @@ static struct fp_img_dev *dev_to_img_dev(struct fp_dev *dev) * Determines if a device has imaging capabilities. If a device has imaging * capabilities you are able to perform imaging operations such as retrieving * scan images using fp_dev_img_capture(). However, not all devices are - * imaging devices - some do all processing in hardware. This function will + * imaging devices – some do all processing in hardware. This function will * indicate which class a device in question falls into. * * Returns: 1 if the device is an imaging device, 0 if the device does not diff --git a/libfprint/data.c b/libfprint/data.c index 92fd7be6..a0ac620f 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -501,7 +501,7 @@ API_EXPORTED int fp_print_data_delete(struct fp_dev *dev, * be freed with fp_print_data_free() after use. * Attempts to load a stored print based on a #fp_dscv_print - * "discovered print" record. + * discovered print record. * * A return code of -ENOENT indicates that the file referred to by the * discovered print could not be found. Other error codes (both positive and diff --git a/libfprint/poll.c b/libfprint/poll.c index aad81d16..fca0f7fc 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -303,7 +303,7 @@ API_EXPORTED int fp_get_next_timeout(struct timeval *tv) * * Retrieve a list of file descriptors that should be polled for events * interesting to libfprint. This function is only for users who wish to - * combine libfprint's file descriptor set with other event sources - more + * combine libfprint's file descriptor set with other event sources – more * simplistic users will be able to call fp_handle_events() or a variant * directly. * diff --git a/libfprint/sync.c b/libfprint/sync.c index ad1a7946..87c8cb9e 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -42,7 +42,7 @@ static void sync_open_cb(struct fp_dev *dev, int status, void *user_data) * @ddev: the discovered device to open * * Opens and initialises a device. This is the function you call in order - * to convert a #fp_dscv_dev "discovered device" into an actual device handle + * to convert a #fp_dscv_dev discovered device into an actual device handle * that you can perform operations with. * * Returns: (transfer none): the opened device handle, or %NULL on error @@ -154,19 +154,19 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data) * into this function will retry the current stage again. The current stage may * need to be retried several times. * - * The fp_enroll_result#FP_ENROLL_FAIL code may be returned from any enroll + * The %FP_ENROLL_FAIL code may be returned from any enroll * stage. This code indicates that even though the scans themselves have been * acceptable, data processing applied to these scans produces incomprehensible * results. In other words, the user may have been scanning a different finger * for each stage or something like that. Like negative error codes, this * return code indicates that the enrollment process has been aborted. * - * The fp_enroll_result#FP_ENROLL_PASS code will only ever be returned for + * The %FP_ENROLL_PASS code will only ever be returned for * non-final stages. This return code indicates that the scan was acceptable * and the next call into this function will advance onto the next enroll * stage. * - * The fp_enroll_result#FP_ENROLL_COMPLETE code will only ever be returned + * The %FP_ENROLL_COMPLETE code will only ever be returned * from the final enroll stage. It indicates that enrollment completed * successfully, and that print_data has been assigned to point to the * resultant enrollment data. The print_data parameter will not be modified @@ -446,7 +446,7 @@ static void identify_stop_cb(struct fp_dev *dev, void *user_data) * provide images. * * This function returns codes from #fp_verify_result. The return code - * fp_verify_result#FP_VERIFY_MATCH indicates that the scanned fingerprint + * %FP_VERIFY_MATCH indicates that the scanned fingerprint * does appear in the print gallery, and the match_offset output parameter * will indicate the index into the print gallery array of the matched print. * @@ -551,7 +551,7 @@ static void capture_stop_cb(struct fp_dev *dev, void *user_data) * @img: a location to return the captured image. Must be freed with * fp_img_free() after use. * - * Captures a #fp_img "image" from a device. The returned image is the raw + * Captures a #fp_img from a device. The returned image is the raw * image provided by the device, you may wish to [standardize](libfprint-Image-operations.html#img_std) it. * * If set, the @unconditional flag indicates that the device should From c5e0e41ce7248ce21528c4aa9b7ed794cc3a1497 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 15:48:13 +0200 Subject: [PATCH 058/141] docs: Add documentation for opaque structures --- libfprint/fprint.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 46017aca..67e28705 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -30,36 +30,48 @@ extern "C" { /** * fp_dscv_dev: * + * #fp_dscv_dev is an opaque structure type. You must access it using the + * functions below. */ struct fp_dscv_dev; /** * fp_dscv_print: * + * #fp_dscv_print is an opaque structure type. You must access it using the + * functions below. */ struct fp_dscv_print; /** * fp_dev: * + * #fp_dev is an opaque structure type. You must access it using the + * functions below. */ struct fp_dev; /** * fp_driver: * + * #fp_driver is an opaque structure type. You must access it using the + * functions below. */ struct fp_driver; /** * fp_print_data: * + * #fp_print_data is an opaque structure type. You must access it using the + * functions below. */ struct fp_print_data; /** * fp_img: * + * #fp_img is an opaque structure type. You must access it using the + * functions below. */ struct fp_img; From 83a0a7681be2bc329ae3a2b6cd8055f24ffe578c Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 15:50:20 +0200 Subject: [PATCH 059/141] img: Make fpi_img_detect_minutiae() static It's unused outside img.c, so mark it as static. --- libfprint/fp_internal.h | 1 - libfprint/img.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 68bf7a34..1b7c4a4f 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -398,7 +398,6 @@ struct fp_img *fpi_img_new(size_t length); struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *dev); struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize); gboolean fpi_img_is_sane(struct fp_img *img); -int fpi_img_detect_minutiae(struct fp_img *img); int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, struct fp_print_data **ret); int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, diff --git a/libfprint/img.c b/libfprint/img.c index 09cd2300..10511f8c 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -286,7 +286,7 @@ static void minutiae_to_xyt(struct fp_minutiae *minutiae, int bwidth, xyt->nrows = nmin; } -int fpi_img_detect_minutiae(struct fp_img *img) +static int fpi_img_detect_minutiae(struct fp_img *img) { struct fp_minutiae *minutiae; int r; From 78b8602cf63b5302502e40742c39c2dc77886cbe Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 15:52:52 +0200 Subject: [PATCH 060/141] lib: Make fp_minutia an opaque structure Nothing uses the elements of the structure, so make it opaque. --- libfprint/fp_internal.h | 15 +++++++++++++++ libfprint/fprint.h | 18 +++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 1b7c4a4f..52ea50e8 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -368,6 +368,21 @@ gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1, enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2, enum fp_print_data_type type2); +struct fp_minutia { + int x; + int y; + int ex; + int ey; + int direction; + double reliability; + int type; + int appearing; + int feature_id; + int *nbrs; + int *ridge_counts; + int num_nbrs; +}; + struct fp_minutiae { int alloc; int num; diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 67e28705..51cb79c4 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -347,22 +347,10 @@ uint32_t fp_print_data_get_devtype(struct fp_print_data *data); /** * fp_minutia: * - * FIXME + * #fp_minutia is an opaque structure type. You must access it using the + * functions below. */ -struct fp_minutia { - int x; - int y; - int ex; - int ey; - int direction; - double reliability; - int type; - int appearing; - int feature_id; - int *nbrs; - int *ridge_counts; - int num_nbrs; -}; +struct fp_minutia; int fp_img_get_height(struct fp_img *img); int fp_img_get_width(struct fp_img *img); From 9d67ce484d256e26430b6e6c56be36a77a5f0a40 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 16:56:14 +0200 Subject: [PATCH 061/141] lib: Make inline functions real functions Otherwise they will not be parsed by gtk-doc and documented. --- doc/libfprint-sections.txt | 1 + libfprint/core.c | 11 ++++++ libfprint/fprint.h | 80 ++++---------------------------------- libfprint/sync.c | 62 +++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 73 deletions(-) diff --git a/doc/libfprint-sections.txt b/doc/libfprint-sections.txt index fbf13e58..6be10c8c 100644 --- a/doc/libfprint-sections.txt +++ b/doc/libfprint-sections.txt @@ -22,6 +22,7 @@ fp_discover_devs fp_dscv_devs_free fp_dscv_dev_get_driver fp_dscv_dev_get_devtype +fp_dscv_dev_get_driver_id fp_dscv_dev_supports_print_data fp_dscv_dev_supports_dscv_print fp_dscv_dev_for_print_data diff --git a/libfprint/core.c b/libfprint/core.c index c2867a09..7adc86cb 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -455,6 +455,17 @@ API_EXPORTED struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev) return dev->drv; } +/** + * fp_dscv_dev_get_driver_id: + * @dev: a discovered fingerprint device + * + * Returns: the ID for the underlying driver for that device + */ +API_EXPORTED uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev) +{ + return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)); +} + /** * fp_dscv_dev_get_devtype: * @dev: the discovered device diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 51cb79c4..d9ca3dca 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -131,6 +131,7 @@ enum fp_scan_type fp_driver_get_scan_type(struct fp_driver *drv); struct fp_dscv_dev **fp_discover_devs(void); void fp_dscv_devs_free(struct fp_dscv_dev **devs); struct fp_driver *fp_dscv_dev_get_driver(struct fp_dscv_dev *dev); +uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev); uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev); int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, struct fp_print_data *print); @@ -141,17 +142,6 @@ struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs, struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs, struct fp_dscv_print *print); -/** - * fp_dscv_dev_get_driver_id: - * @dev: a discovered fingerprint device - * - * Returns: the ID for the underlying driver for that device - */ -static inline uint16_t fp_dscv_dev_get_driver_id(struct fp_dscv_dev *dev) -{ - return fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)); -} - /* Print discovery */ struct fp_dscv_print **fp_discover_prints(void); void fp_dscv_prints_free(struct fp_dscv_print **prints); @@ -225,25 +215,8 @@ enum fp_enroll_result { int fp_enroll_finger_img(struct fp_dev *dev, struct fp_print_data **print_data, struct fp_img **img); - -/** - * fp_enroll_finger: - * @dev: the device - * @print_data: a location to return the resultant enrollment data from - * the final stage. Must be freed with fp_print_data_free() after use. - * - * Performs an enroll stage. See [Enrolling](libfprint-Devices-operations.html#enrolling) - * for an explanation of enroll stages. This function is just a shortcut to - * calling fp_enroll_finger_img() with a %NULL image parameter. Be sure to read - * the description of fp_enroll_finger_img() in order to understand its behaviour. - * - * Returns: negative code on error, otherwise a code from #fp_enroll_result - */ -static inline int fp_enroll_finger(struct fp_dev *dev, - struct fp_print_data **print_data) -{ - return fp_enroll_finger_img(dev, print_data, NULL); -} +int fp_enroll_finger(struct fp_dev *dev, + struct fp_print_data **print_data); /** * fp_verify_result: @@ -279,54 +252,15 @@ enum fp_verify_result { int fp_verify_finger_img(struct fp_dev *dev, struct fp_print_data *enrolled_print, struct fp_img **img); - -/** - * fp_verify_finger: - * @dev: the device to perform the scan. - * @enrolled_print: the print to verify against. Must have been previously - * enrolled with a device compatible to the device selected to perform the scan. - * - * Performs a new scan and verify it against a previously enrolled print. This - * function is just a shortcut to calling fp_verify_finger_img() with a NULL - * image output parameter. - * - * Returns: negative code on error, otherwise a code from #fp_verify_result - * \sa fp_verify_finger_img() - */ -static inline int fp_verify_finger(struct fp_dev *dev, - struct fp_print_data *enrolled_print) -{ - return fp_verify_finger_img(dev, enrolled_print, NULL); -} +int fp_verify_finger(struct fp_dev *dev, + struct fp_print_data *enrolled_print); int fp_dev_supports_identification(struct fp_dev *dev); int fp_identify_finger_img(struct fp_dev *dev, struct fp_print_data **print_gallery, size_t *match_offset, struct fp_img **img); - -/** - * fp_identify_finger: - * @dev: the device to perform the scan. - * @print_gallery: %NULL-terminated array of pointers to the prints to - * identify against. Each one must have been previously enrolled with a device - * compatible to the device selected to perform the scan. - * @match_offset: output location to store the array index of the matched - * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was - * returned. - - * Performs a new scan and attempts to identify the scanned finger against a - * collection of previously enrolled fingerprints. This function is just a - * shortcut to calling fp_identify_finger_img() with a %NULL image output - * parameter. - * - * Returns: negative code on error, otherwise a code from #fp_verify_result - * \sa fp_identify_finger_img() - */ -static inline int fp_identify_finger(struct fp_dev *dev, - struct fp_print_data **print_gallery, size_t *match_offset) -{ - return fp_identify_finger_img(dev, print_gallery, match_offset, NULL); -} +int fp_identify_finger(struct fp_dev *dev, + struct fp_print_data **print_gallery, size_t *match_offset); /* Data handling */ int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, diff --git a/libfprint/sync.c b/libfprint/sync.c index 87c8cb9e..af26272a 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -287,6 +287,25 @@ err: return r; } +/** + * fp_enroll_finger: + * @dev: the device + * @print_data: a location to return the resultant enrollment data from + * the final stage. Must be freed with fp_print_data_free() after use. + * + * Performs an enroll stage. See [Enrolling](libfprint-Devices-operations.html#enrolling) + * for an explanation of enroll stages. This function is just a shortcut to + * calling fp_enroll_finger_img() with a %NULL image parameter. Be sure to read + * the description of fp_enroll_finger_img() in order to understand its behaviour. + * + * Returns: negative code on error, otherwise a code from #fp_enroll_result + */ +API_EXPORTED int fp_enroll_finger(struct fp_dev *dev, + struct fp_print_data **print_data) +{ + return fp_enroll_finger_img(dev, print_data, NULL); +} + struct sync_verify_data { gboolean populated; int result; @@ -401,6 +420,25 @@ err: return r; } +/** + * fp_verify_finger: + * @dev: the device to perform the scan. + * @enrolled_print: the print to verify against. Must have been previously + * enrolled with a device compatible to the device selected to perform the scan. + * + * Performs a new scan and verify it against a previously enrolled print. This + * function is just a shortcut to calling fp_verify_finger_img() with a NULL + * image output parameter. + * + * Returns: negative code on error, otherwise a code from #fp_verify_result + * \sa fp_verify_finger_img() + */ +API_EXPORTED int fp_verify_finger(struct fp_dev *dev, + struct fp_print_data *enrolled_print) +{ + return fp_verify_finger_img(dev, enrolled_print, NULL); +} + struct sync_identify_data { gboolean populated; int result; @@ -523,6 +561,30 @@ err: return r; } +/** + * fp_identify_finger: + * @dev: the device to perform the scan. + * @print_gallery: %NULL-terminated array of pointers to the prints to + * identify against. Each one must have been previously enrolled with a device + * compatible to the device selected to perform the scan. + * @match_offset: output location to store the array index of the matched + * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was + * returned. + + * Performs a new scan and attempts to identify the scanned finger against a + * collection of previously enrolled fingerprints. This function is just a + * shortcut to calling fp_identify_finger_img() with a %NULL image output + * parameter. + * + * Returns: negative code on error, otherwise a code from #fp_verify_result + * \sa fp_identify_finger_img() + */ +API_EXPORTED int fp_identify_finger(struct fp_dev *dev, + struct fp_print_data **print_gallery, size_t *match_offset) +{ + return fp_identify_finger_img(dev, print_gallery, match_offset, NULL); +} + struct sync_capture_data { gboolean populated; int result; From b44e417bcae0fa920343dc9b876a9434b3789ba4 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 17:00:45 +0200 Subject: [PATCH 062/141] docs: Fix '\sa' doxygen references --- libfprint/sync.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libfprint/sync.c b/libfprint/sync.c index af26272a..0c439537 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -430,8 +430,9 @@ err: * function is just a shortcut to calling fp_verify_finger_img() with a NULL * image output parameter. * + * See also fp_verify_finger_img(). + * * Returns: negative code on error, otherwise a code from #fp_verify_result - * \sa fp_verify_finger_img() */ API_EXPORTED int fp_verify_finger(struct fp_dev *dev, struct fp_print_data *enrolled_print) @@ -576,8 +577,9 @@ err: * shortcut to calling fp_identify_finger_img() with a %NULL image output * parameter. * + * See also fp_identify_finger_img(). + * * Returns: negative code on error, otherwise a code from #fp_verify_result - * \sa fp_identify_finger_img() */ API_EXPORTED int fp_identify_finger(struct fp_dev *dev, struct fp_print_data **print_gallery, size_t *match_offset) From 317d7bc988c1d13a4c89e05ddc6280511bce179c Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 17:06:22 +0200 Subject: [PATCH 063/141] lib: Simplify fp_*_stop_cb callback definitions They're all the same, so merge them into a single fp_operation_stop_cb. https://bugs.freedesktop.org/show_bug.cgi?id=106551 --- libfprint/async.c | 10 +++++----- libfprint/fp_internal.h | 10 +++++----- libfprint/fprint.h | 17 +++++++---------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/libfprint/async.c b/libfprint/async.c index 2337a579..c1f2aaae 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -102,7 +102,7 @@ void fpi_drvcb_close_complete(struct fp_dev *dev) * @user_data */ API_EXPORTED void fp_async_dev_close(struct fp_dev *dev, - fp_dev_close_cb callback, void *user_data) + fp_operation_stop_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; @@ -212,7 +212,7 @@ void fpi_drvcb_enroll_stopped(struct fp_dev *dev) * Returns: */ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, - fp_enroll_stop_cb callback, void *user_data) + fp_operation_stop_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; int r; @@ -326,7 +326,7 @@ void fpi_drvcb_verify_stopped(struct fp_dev *dev) * Returns: */ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, - fp_verify_stop_cb callback, void *user_data) + fp_operation_stop_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; gboolean iterating = (dev->state == DEV_STATE_VERIFYING); @@ -434,7 +434,7 @@ void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result, * Returns: */ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev, - fp_identify_stop_cb callback, void *user_data) + fp_operation_stop_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; gboolean iterating = (dev->state == DEV_STATE_IDENTIFYING); @@ -561,7 +561,7 @@ void fpi_drvcb_capture_stopped(struct fp_dev *dev) * Returns: */ API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev, - fp_capture_stop_cb callback, void *user_data) + fp_operation_stop_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; int r; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 52ea50e8..694294c1 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -119,23 +119,23 @@ struct fp_dev { /* FIXME: convert this to generic state operational data mechanism? */ fp_dev_open_cb open_cb; void *open_cb_data; - fp_dev_close_cb close_cb; + fp_operation_stop_cb close_cb; void *close_cb_data; fp_enroll_stage_cb enroll_stage_cb; void *enroll_stage_cb_data; - fp_enroll_stop_cb enroll_stop_cb; + fp_operation_stop_cb enroll_stop_cb; void *enroll_stop_cb_data; fp_verify_cb verify_cb; void *verify_cb_data; - fp_verify_stop_cb verify_stop_cb; + fp_operation_stop_cb verify_stop_cb; void *verify_stop_cb_data; fp_identify_cb identify_cb; void *identify_cb_data; - fp_identify_stop_cb identify_stop_cb; + fp_operation_stop_cb identify_stop_cb; void *identify_stop_cb_data; fp_capture_cb capture_cb; void *capture_cb_data; - fp_capture_stop_cb capture_stop_cb; + fp_operation_stop_cb capture_stop_cb; void *capture_stop_cb_data; /* FIXME: better place to put this? */ diff --git a/libfprint/fprint.h b/libfprint/fprint.h index d9ca3dca..ad54c4f6 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -323,12 +323,13 @@ void fp_set_debug(int level); /* Asynchronous I/O */ +typedef void (*fp_operation_stop_cb)(struct fp_dev *dev, void *user_data); + typedef void (*fp_dev_open_cb)(struct fp_dev *dev, int status, void *user_data); int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback, void *user_data); -typedef void (*fp_dev_close_cb)(struct fp_dev *dev, void *user_data); -void fp_async_dev_close(struct fp_dev *dev, fp_dev_close_cb callback, +void fp_async_dev_close(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); typedef void (*fp_enroll_stage_cb)(struct fp_dev *dev, int result, @@ -336,8 +337,7 @@ typedef void (*fp_enroll_stage_cb)(struct fp_dev *dev, int result, int fp_async_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback, void *user_data); -typedef void (*fp_enroll_stop_cb)(struct fp_dev *dev, void *user_data); -int fp_async_enroll_stop(struct fp_dev *dev, fp_enroll_stop_cb callback, +int fp_async_enroll_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); typedef void (*fp_verify_cb)(struct fp_dev *dev, int result, @@ -345,8 +345,7 @@ typedef void (*fp_verify_cb)(struct fp_dev *dev, int result, int fp_async_verify_start(struct fp_dev *dev, struct fp_print_data *data, fp_verify_cb callback, void *user_data); -typedef void (*fp_verify_stop_cb)(struct fp_dev *dev, void *user_data); -int fp_async_verify_stop(struct fp_dev *dev, fp_verify_stop_cb callback, +int fp_async_verify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); typedef void (*fp_identify_cb)(struct fp_dev *dev, int result, @@ -354,16 +353,14 @@ typedef void (*fp_identify_cb)(struct fp_dev *dev, int result, int fp_async_identify_start(struct fp_dev *dev, struct fp_print_data **gallery, fp_identify_cb callback, void *user_data); -typedef void (*fp_identify_stop_cb)(struct fp_dev *dev, void *user_data); -int fp_async_identify_stop(struct fp_dev *dev, fp_identify_stop_cb callback, +int fp_async_identify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); typedef void (*fp_capture_cb)(struct fp_dev *dev, int result, struct fp_img *img, void *user_data); int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_capture_cb callback, void *user_data); -typedef void (*fp_capture_stop_cb)(struct fp_dev *dev, void *user_data); -int fp_async_capture_stop(struct fp_dev *dev, fp_capture_stop_cb callback, void *user_data); +int fp_async_capture_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); #ifdef __cplusplus } From be68bacc94dc200a6d924c5b2383e1d8e0093b0f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 17:18:37 +0200 Subject: [PATCH 064/141] lib: Merge two other async callback types Merge fp_capture_cb and fp_verify_cb. https://bugs.freedesktop.org/show_bug.cgi?id=106551 --- libfprint/async.c | 4 ++-- libfprint/fp_internal.h | 4 ++-- libfprint/fprint.h | 10 ++++------ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libfprint/async.c b/libfprint/async.c index c1f2aaae..07c20c30 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -250,7 +250,7 @@ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, * Returns: */ API_EXPORTED int fp_async_verify_start(struct fp_dev *dev, - struct fp_print_data *data, fp_verify_cb callback, void *user_data) + struct fp_print_data *data, fp_img_operation_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; int r; @@ -486,7 +486,7 @@ void fpi_drvcb_identify_stopped(struct fp_dev *dev) * Returns: */ API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional, - fp_capture_cb callback, void *user_data) + fp_img_operation_cb callback, void *user_data) { struct fp_driver *drv = dev->drv; int r; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 694294c1..5e3522bf 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -125,7 +125,7 @@ struct fp_dev { void *enroll_stage_cb_data; fp_operation_stop_cb enroll_stop_cb; void *enroll_stop_cb_data; - fp_verify_cb verify_cb; + fp_img_operation_cb verify_cb; void *verify_cb_data; fp_operation_stop_cb verify_stop_cb; void *verify_stop_cb_data; @@ -133,7 +133,7 @@ struct fp_dev { void *identify_cb_data; fp_operation_stop_cb identify_stop_cb; void *identify_stop_cb_data; - fp_capture_cb capture_cb; + fp_img_operation_cb capture_cb; void *capture_cb_data; fp_operation_stop_cb capture_stop_cb; void *capture_stop_cb_data; diff --git a/libfprint/fprint.h b/libfprint/fprint.h index ad54c4f6..20888d63 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -324,6 +324,8 @@ void fp_set_debug(int level); /* Asynchronous I/O */ typedef void (*fp_operation_stop_cb)(struct fp_dev *dev, void *user_data); +typedef void (*fp_img_operation_cb)(struct fp_dev *dev, int result, + struct fp_img *img, void *user_data); typedef void (*fp_dev_open_cb)(struct fp_dev *dev, int status, void *user_data); int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback, @@ -340,10 +342,8 @@ int fp_async_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback, int fp_async_enroll_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); -typedef void (*fp_verify_cb)(struct fp_dev *dev, int result, - struct fp_img *img, void *user_data); int fp_async_verify_start(struct fp_dev *dev, struct fp_print_data *data, - fp_verify_cb callback, void *user_data); + fp_img_operation_cb callback, void *user_data); int fp_async_verify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); @@ -356,9 +356,7 @@ int fp_async_identify_start(struct fp_dev *dev, struct fp_print_data **gallery, int fp_async_identify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); -typedef void (*fp_capture_cb)(struct fp_dev *dev, int result, - struct fp_img *img, void *user_data); -int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_capture_cb callback, void *user_data); +int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_img_operation_cb callback, void *user_data); int fp_async_capture_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); From 06c72d54bedd94b12b9999d764d4ce6668c7b19b Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 22 May 2018 18:44:10 +0200 Subject: [PATCH 065/141] poll: Add missing API docs for polling functions --- doc/libfprint-sections.txt | 2 ++ libfprint/fprint.h | 21 +++++++++++++++++++++ libfprint/poll.c | 6 ++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/libfprint-sections.txt b/doc/libfprint-sections.txt index 6be10c8c..5e3df1ff 100644 --- a/doc/libfprint-sections.txt +++ b/doc/libfprint-sections.txt @@ -11,6 +11,8 @@ fp_handle_events_timeout fp_handle_events fp_get_next_timeout fp_get_pollfds +fp_pollfd_added_cb +fp_pollfd_removed_cb fp_set_pollfd_notifiers diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 20888d63..198d462f 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -299,7 +299,11 @@ void fp_img_free(struct fp_img *img); /** * fp_pollfd: + * @fd: a file descriptor + * @events: Event flags to poll for from `` * + * A structure representing a file descriptor and the events to poll + * for, as returned by fp_get_pollfds(). */ struct fp_pollfd { int fd; @@ -311,7 +315,24 @@ int fp_handle_events(void); size_t fp_get_pollfds(struct fp_pollfd **pollfds); int fp_get_next_timeout(struct timeval *tv); +/** + * fp_pollfd_added_cb: + * @fd: the new file descriptor + * @events: events to monitor for, see `` for the possible values + * + * Type definition for a function that will be called when a new + * event source is added. The @events argument is a flag as defined in + * `` such as `POLLIN`, or `POLLOUT`. See fp_set_pollfd_notifiers(). + */ typedef void (*fp_pollfd_added_cb)(int fd, short events); + +/** + * fp_pollfd_removed_cb: + * @fd: the file descriptor to stop monitoring + * + * Type definition for a function that will be called when an + * event source is removed. See fp_set_pollfd_notifiers(). + */ typedef void (*fp_pollfd_removed_cb)(int fd); void fp_set_pollfd_notifiers(fp_pollfd_added_cb added_cb, fp_pollfd_removed_cb removed_cb); diff --git a/libfprint/poll.c b/libfprint/poll.c index fca0f7fc..a3722c64 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -340,9 +340,11 @@ API_EXPORTED size_t fp_get_pollfds(struct fp_pollfd **pollfds) /** * fp_set_pollfd_notifiers: - * @added_cb: - * @removed_cb: + * @added_cb: a #fp_pollfd_added_cb callback or %NULL + * @removed_cb: a #fp_pollfd_removed_cb callback or %NULL * + * This sets the callback functions to call for every new or removed + * file descriptor used as an event source. */ API_EXPORTED void fp_set_pollfd_notifiers(fp_pollfd_added_cb added_cb, fp_pollfd_removed_cb removed_cb) From 612e9e11de9966fed8d7101cc83a829ef0ece835 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 13:32:48 +0200 Subject: [PATCH 066/141] docs: Document async function callbacks --- doc/libfprint-sections.txt | 6 +++++ libfprint/fprint.h | 55 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/doc/libfprint-sections.txt b/doc/libfprint-sections.txt index 5e3df1ff..77cb0c38 100644 --- a/doc/libfprint-sections.txt +++ b/doc/libfprint-sections.txt @@ -58,6 +58,12 @@ fp_dev_supports_dscv_print fp_dev_get_img_width fp_dev_get_img_height +fp_operation_stop_cb +fp_img_operation_cb +fp_dev_open_cb +fp_enroll_stage_cb +fp_identify_cb + fp_dev_open fp_async_dev_open diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 198d462f..fd7d6336 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -344,19 +344,62 @@ void fp_set_debug(int level); /* Asynchronous I/O */ +/** + * fp_operation_stop_cb: + * @dev: the #fp_dev device + * @user_data: user data passed to the callback + * + * Type definition for a function that will be called when fp_async_dev_close(), + * fp_async_verify_stop(), fp_async_identify_stop() or fp_async_capture_stop() + * finishes. + */ typedef void (*fp_operation_stop_cb)(struct fp_dev *dev, void *user_data); + +/** + * fp_img_operation_cb: + * @dev: the #fp_dev device + * @result: an #fp_verify_result for fp_async_verify_start(), or an #fp_capture_result + * for fp_async_capture_start(), or a negative value on error + * @img: the captured #fp_img if capture or verification was successful + * @user_data: user data passed to the callback + * + * Type definition for a function that will be called when fp_async_verify_start() + * or fp_async_capture_start() finished. + */ typedef void (*fp_img_operation_cb)(struct fp_dev *dev, int result, struct fp_img *img, void *user_data); +/** + * fp_dev_open_cb: + * @dev: the #fp_dev device + * @status: 0 on success, or a negative value on error + * @user_data: user data passed to the callback + * + * Type definition for a function that will be called when fp_async_dev_open + * finishes. + */ typedef void (*fp_dev_open_cb)(struct fp_dev *dev, int status, void *user_data); + int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback, void *user_data); void fp_async_dev_close(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); +/** + * fp_enroll_stage_cb: + * @dev: the #fp_dev device + * @result: a #fp_enroll_result on success, or a negative value on failure + * @print: the enrollment data from the final stage + * @img: an #fp_img to free with fp_img_free() + * @user_data: user data passed to the callback + * + * Type definition for a function that will be called when + * fp_async_enroll_start() finishes. + */ typedef void (*fp_enroll_stage_cb)(struct fp_dev *dev, int result, struct fp_print_data *print, struct fp_img *img, void *user_data); + int fp_async_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback, void *user_data); @@ -369,6 +412,18 @@ int fp_async_verify_start(struct fp_dev *dev, struct fp_print_data *data, int fp_async_verify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data); +/** + * fp_identify_cb: + * @dev: the #fp_dev device + * @result: a #fp_verify_result on success, or a negative value on error. + * @match_offset: the array index of the matched gallery print (if any was found). + * Only valid if %FP_VERIFY_MATCH was returned. + * @img: the scan image, it must be freed with fp_img_free() after use. + * @user_data: user data passed to the callback + * + * Type definition for a function that will be called when fp_async_identify_start() + * finishes. + */ typedef void (*fp_identify_cb)(struct fp_dev *dev, int result, size_t match_offset, struct fp_img *img, void *user_data); int fp_async_identify_start(struct fp_dev *dev, struct fp_print_data **gallery, From 768a74c4bfc3dfb33d3eb5d21d34a5622f48051e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 13:33:20 +0200 Subject: [PATCH 067/141] docs: Remove transfer information from fp_dev_open() There's no GObject usage in the public API. --- libfprint/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/sync.c b/libfprint/sync.c index 0c439537..bc553e16 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -45,7 +45,7 @@ static void sync_open_cb(struct fp_dev *dev, int status, void *user_data) * to convert a #fp_dscv_dev discovered device into an actual device handle * that you can perform operations with. * - * Returns: (transfer none): the opened device handle, or %NULL on error + * Returns: the opened device handle, or %NULL on error */ API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev) { From 614e2286c2983c82c5a2b5c4763c9e410a3a282e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 13:34:01 +0200 Subject: [PATCH 068/141] docs: Fix typo in fp_enroll_finger_img() API docs Missing ":" after argument name. --- libfprint/sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/sync.c b/libfprint/sync.c index bc553e16..32b78f07 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -128,7 +128,7 @@ static void enroll_stop_cb(struct fp_dev *dev, void *user_data) /** * fp_enroll_finger_img: * @dev: the device - * @print_data a location to return the resultant enrollment data from + * @print_data: a location to return the resultant enrollment data from * the final stage. Must be freed with fp_print_data_free() after use. * @img: location to store the scan image. accepts %NULL for no image * storage. If an image is returned, it must be freed with fp_img_free() after From e9bfd943fce0056e41787de267e1d9dd1e2f0513 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 13:35:36 +0200 Subject: [PATCH 069/141] docs: Mark a few FP_VERIFY_MATCH as constant Add "%" prefix to mark it as a constant in the docs. --- libfprint/sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/sync.c b/libfprint/sync.c index 32b78f07..81b80738 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -471,7 +471,7 @@ static void identify_stop_cb(struct fp_dev *dev, void *user_data) * identify against. Each one must have been previously enrolled with a device * compatible to the device selected to perform the scan. * @match_offset: output location to store the array index of the matched - * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was + * gallery print (if any was found). Only valid if %FP_VERIFY_MATCH was * returned. * @img: location to store the scan image. accepts %NULL for no image * storage. If an image is returned, it must be freed with fp_img_free() after @@ -569,7 +569,7 @@ err: * identify against. Each one must have been previously enrolled with a device * compatible to the device selected to perform the scan. * @match_offset: output location to store the array index of the matched - * gallery print (if any was found). Only valid if FP_VERIFY_MATCH was + * gallery print (if any was found). Only valid if %FP_VERIFY_MATCH was * returned. * Performs a new scan and attempts to identify the scanned finger against a From 63e5d564414113f6b97d8bcb0082972655c63bf3 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 15:40:31 +0200 Subject: [PATCH 070/141] build: Always allow switching log level at runtime There are no parts of libfprint that are so resource intensive that we'd want to disable logging. This avoids (hopefully rare) cases where compiled versions of libfprint are distributed with logging completely disabled, and thus can't be debugged. --- libfprint/fp_internal.h | 4 ---- meson.build | 3 --- meson_options.txt | 4 ---- 3 files changed, 11 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 5e3522bf..e8f06f04 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -48,11 +48,7 @@ void fpi_log(enum fpi_log_level, const char *component, const char *function, #define FP_COMPONENT NULL #endif -#ifdef ENABLE_LOGGING #define _fpi_log(level, fmt...) fpi_log(level, FP_COMPONENT, __FUNCTION__, fmt) -#else -#define _fpi_log(level, fmt...) -#endif #ifdef ENABLE_DEBUG_LOGGING #define fp_dbg(fmt...) _fpi_log(FPRINT_LOG_LEVEL_DEBUG, fmt) diff --git a/meson.build b/meson.build index a9abc3f2..62791db6 100644 --- a/meson.build +++ b/meson.build @@ -91,9 +91,6 @@ if get_option('x11-examples') endif # Message logging -if get_option('log') - libfprint_conf.set('ENABLE_LOGGING', '1') -endif if get_option('debug_log') libfprint_conf.set('ENABLE_DEBUG_LOGGING', '1') endif diff --git a/meson_options.txt b/meson_options.txt index ee442c3c..c0a73917 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,10 +14,6 @@ option('x11-examples', description: 'Whether to build X11 example applications', type: 'boolean', value: true) -option('log', - description: 'Message logging', - type: 'boolean', - value: true) option('debug_log', description: 'Debug message logging', type: 'boolean', From 8e6e23b8d0c6cd58555073db820b74f1c57bc33e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 16:18:11 +0200 Subject: [PATCH 071/141] build: Always enable debugging logging We shouldn't need to specifically enable debug logging to get useful data out of a compiled libfprint either, so always enable debugging output. It will still be switched off at runtime, by default. --- libfprint/core.c | 2 -- libfprint/data.c | 2 -- libfprint/fp_internal.h | 5 ----- meson.build | 5 ----- meson_options.txt | 4 ---- 5 files changed, 18 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index 7adc86cb..5deb3a6e 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -123,14 +123,12 @@ void fpi_log(enum fpi_log_level level, const char *component, FILE *stream = stdout; const char *prefix; -#ifndef ENABLE_DEBUG_LOGGING if (!log_level) return; if (level == FPRINT_LOG_LEVEL_WARNING && log_level < 2) return; if (level == FPRINT_LOG_LEVEL_INFO && log_level < 3) return; -#endif switch (level) { case FPRINT_LOG_LEVEL_INFO: diff --git a/libfprint/data.c b/libfprint/data.c index a0ac620f..7e47db23 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -76,7 +76,6 @@ void fpi_data_exit(void) ((finger) >= LEFT_THUMB && (finger) <= RIGHT_LITTLE) /* for debug messages only */ -#ifdef ENABLE_DEBUG_LOGGING static const char *finger_num_to_str(enum fp_finger finger) { const char *names[] = { @@ -95,7 +94,6 @@ static const char *finger_num_to_str(enum fp_finger finger) return "UNKNOWN"; return names[finger]; } -#endif static struct fp_print_data *print_data_new(uint16_t driver_id, uint32_t devtype, enum fp_print_data_type type) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index e8f06f04..fdaa408d 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -50,12 +50,7 @@ void fpi_log(enum fpi_log_level, const char *component, const char *function, #define _fpi_log(level, fmt...) fpi_log(level, FP_COMPONENT, __FUNCTION__, fmt) -#ifdef ENABLE_DEBUG_LOGGING #define fp_dbg(fmt...) _fpi_log(FPRINT_LOG_LEVEL_DEBUG, fmt) -#else -#define fp_dbg(fmt...) -#endif - #define fp_info(fmt...) _fpi_log(FPRINT_LOG_LEVEL_INFO, fmt) #define fp_warn(fmt...) _fpi_log(FPRINT_LOG_LEVEL_WARNING, fmt) #define fp_err(fmt...) _fpi_log(FPRINT_LOG_LEVEL_ERROR, fmt) diff --git a/meson.build b/meson.build index 62791db6..93603b6b 100644 --- a/meson.build +++ b/meson.build @@ -90,11 +90,6 @@ if get_option('x11-examples') endif endif -# Message logging -if get_option('debug_log') - libfprint_conf.set('ENABLE_DEBUG_LOGGING', '1') -endif - libfprint_conf.set('API_EXPORTED', '__attribute__((visibility("default")))') configure_file(output: 'config.h', configuration: libfprint_conf) diff --git a/meson_options.txt b/meson_options.txt index c0a73917..f847bff0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,10 +14,6 @@ option('x11-examples', description: 'Whether to build X11 example applications', type: 'boolean', value: true) -option('debug_log', - description: 'Debug message logging', - type: 'boolean', - value: false) option('doc', description: 'Whether to build the API documentation', type: 'boolean', From c376c6fb02a01a2bc8415f15ccd7d8d9f12fd4c1 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 19:03:25 +0200 Subject: [PATCH 072/141] lib: Fix type mismatch warnings in debug output --- libfprint/assembling.c | 4 ++-- libfprint/data.c | 2 +- libfprint/drivers/aesx660.c | 8 ++++---- libfprint/drivers/upeksonly.c | 4 ++-- libfprint/drivers/upektc.c | 2 +- libfprint/drivers/upektc_img.c | 4 ++-- libfprint/drivers/upekts.c | 6 +++--- libfprint/poll.c | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index 1052f99d..d34cf377 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -357,7 +357,7 @@ struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx, unsigned char *output = g_malloc0(ctx->line_width * ctx->max_height); struct fp_img *img; - fp_dbg("%llu", g_get_real_time()); + fp_dbg("%"G_GINT64_FORMAT, g_get_real_time()); row1 = lines; for (i = 0; (i < lines_len - 1) && row1; i += 2) { @@ -388,7 +388,7 @@ struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx, median_filter(offsets, (lines_len / 2) - 1, ctx->median_filter_size); - fp_dbg("offsets_filtered: %llu", g_get_real_time()); + fp_dbg("offsets_filtered: %"G_GINT64_FORMAT, g_get_real_time()); for (i = 0; i <= (lines_len / 2) - 1; i++) fp_dbg("%d", offsets[i]); row1 = lines; diff --git a/libfprint/data.c b/libfprint/data.c index 7e47db23..78f552c9 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -224,7 +224,7 @@ static struct fp_print_data *fpi_print_data_from_fp2_data(unsigned char *buf, raw_item = (struct fpi_print_data_item_fp2 *)raw_buf; item_len = GUINT32_FROM_LE(raw_item->length); - fp_dbg("item len %d, total_data_len %d", item_len, total_data_len); + fp_dbg("item len %d, total_data_len %d", (int) item_len, (int) total_data_len); if (total_data_len < item_len) { fp_err("corrupted fingerprint data"); break; diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 278fe810..9743b88d 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -341,7 +341,7 @@ static void capture_read_stripe_data_cb(struct libusb_transfer *transfer) goto out; } - fp_dbg("Got %d bytes of data", actual_len); + fp_dbg("Got %lu bytes of data", actual_len); do { copied = min(aesdev->buffer_max - aesdev->buffer_size, actual_len); memcpy(aesdev->buffer + aesdev->buffer_size, @@ -350,13 +350,13 @@ static void capture_read_stripe_data_cb(struct libusb_transfer *transfer) actual_len -= copied; data += copied; aesdev->buffer_size += copied; - fp_dbg("Copied %.4x bytes into internal buffer", + fp_dbg("Copied %.4lx bytes into internal buffer", copied); if (aesdev->buffer_size == aesdev->buffer_max) { if (aesdev->buffer_max == AESX660_HEADER_SIZE) { aesdev->buffer_max = aesdev->buffer[AESX660_RESPONSE_SIZE_LSB_OFFSET] + (aesdev->buffer[AESX660_RESPONSE_SIZE_MSB_OFFSET] << 8) + AESX660_HEADER_SIZE; - fp_dbg("Got frame, type %.2x size %.4x", + fp_dbg("Got frame, type %.2x size %.4lx", aesdev->buffer[AESX660_RESPONSE_TYPE_OFFSET], aesdev->buffer_max); continue; @@ -402,7 +402,7 @@ static void capture_run_state(struct fpi_ssm *ssm) capture_read_stripe_data_cb); break; case CAPTURE_SET_IDLE: - fp_dbg("Got %d frames\n", aesdev->strips_len); + fp_dbg("Got %lu frames\n", aesdev->strips_len); aesX660_send_cmd(ssm, set_idle_cmd, sizeof(set_idle_cmd), capture_set_idle_cmd_cb); break; diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index e4dce7c8..73e8aec7 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -246,7 +246,7 @@ static void handoff_img(struct fp_img_dev *dev) sdev->rows = g_slist_reverse(sdev->rows); - fp_dbg("%d rows", sdev->num_rows); + fp_dbg("%lu rows", sdev->num_rows); img = fpi_assemble_lines(&assembling_ctx, sdev->rows, sdev->num_rows); g_slist_free_full(sdev->rows, g_free); @@ -312,7 +312,7 @@ static void row_complete(struct fp_img_dev *dev) */ if (sdev->num_blank > FINGER_REMOVED_THRESHOLD) { sdev->finger_state = FINGER_REMOVED; - fp_dbg("detected finger removal. Blank rows: %d, Full rows: %d", sdev->num_blank, sdev->num_rows); + fp_dbg("detected finger removal. Blank rows: %d, Full rows: %lu", sdev->num_blank, sdev->num_rows); handoff_img(dev); return; } diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index f3d9b8ab..9d45091f 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -462,7 +462,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) upekdev->sum_threshold = UPEKET_SUM_THRESHOLD; break; default: - fp_err("Device variant %d is not known\n", driver_data); + fp_err("Device variant %lu is not known\n", driver_data); g_free(upekdev); dev->priv = NULL; return -ENODEV; diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 622b73e8..843bcffe 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -266,7 +266,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) response_size = ((data[5] & 0x0f) << 8) + data[6]; response_size += 9; /* 7 bytes for header, 2 for CRC */ if (response_size > transfer->actual_length) { - fp_dbg("response_size is %d, actual_length is %d\n", + fp_dbg("response_size is %lu, actual_length is %d\n", response_size, transfer->actual_length); fp_dbg("Waiting for rest of transfer"); BUG_ON(upekdev->response_rest); @@ -331,7 +331,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) upektc_img_process_image_frame(upekdev->image_bits + upekdev->image_size, data); BUG_ON(upekdev->image_size != IMAGE_SIZE); - fp_dbg("Image size is %d\n", upekdev->image_size); + fp_dbg("Image size is %lu\n", upekdev->image_size); img = fpi_img_new(IMAGE_SIZE); img->flags = FP_IMG_PARTIAL; memcpy(img->data, upekdev->image_bits, IMAGE_SIZE); diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index b2971276..4e572b98 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -1011,7 +1011,7 @@ static void e_handle_resp00(struct fp_dev *dev, unsigned char *data, int result = 0; if (data_len != 14) { - fp_err("received 3001 poll response of %d bytes?", data_len); + fp_err("received 3001 poll response of %lu bytes?", data_len); fpi_drvcb_enroll_stage_completed(dev, -EPROTO, NULL, NULL); return; } @@ -1083,7 +1083,7 @@ static void e_handle_resp02(struct fp_dev *dev, unsigned char *data, int result = -EPROTO; if (data_len < sizeof(scan_comp)) { - fp_err("fingerprint data too short (%d bytes)", data_len); + fp_err("fingerprint data too short (%lu bytes)", data_len); } else if (memcmp(data, scan_comp, sizeof(scan_comp)) != 0) { fp_err("unrecognised data prefix %x %x %x %x %x", data[0], data[1], data[2], data[3], data[4]); @@ -1288,7 +1288,7 @@ static void v_handle_resp00(struct fp_dev *dev, unsigned char *data, int r = 0; if (data_len != 14) { - fp_err("received 3001 poll response of %d bytes?", data_len); + fp_err("received 3001 poll response of %lu bytes?", data_len); r = -EPROTO; goto out; } diff --git a/libfprint/poll.c b/libfprint/poll.c index a3722c64..cdae4f69 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -163,7 +163,7 @@ static int get_next_timeout_expiry(struct timeval *out, timerclear(out); } else { timersub(&next_timeout->expiry, &tv, out); - fp_dbg("next timeout in %d.%06ds", out->tv_sec, out->tv_usec); + fp_dbg("next timeout in %ld.%06lds", out->tv_sec, out->tv_usec); } return 1; From 363a1b33715e93ad10fe518cf9ed5b0c6a6905d7 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 18:26:22 +0200 Subject: [PATCH 073/141] lib: Replace empty fp_dbg() calls GLib won't like them, so use G_DEBUG_HERE() instead. --- libfprint/async.c | 30 +++++++++++++-------------- libfprint/core.c | 4 ++-- libfprint/data.c | 2 +- libfprint/drivers/aes1610.c | 6 +++--- libfprint/drivers/aes2501.c | 10 ++++----- libfprint/drivers/aes2550.c | 6 +++--- libfprint/drivers/aesx660.c | 4 ++-- libfprint/drivers/elan.c | 38 +++++++++++++++++------------------ libfprint/drivers/upeksonly.c | 4 ++-- libfprint/drivers/upektc.c | 6 +++--- libfprint/drivers/uru4000.c | 2 +- libfprint/drivers/vcom5s.c | 2 +- libfprint/drivers/vfs101.c | 6 +++--- libfprint/imgdev.c | 4 ++-- libfprint/poll.c | 4 ++-- libfprint/sync.c | 16 +++++++-------- 16 files changed, 72 insertions(+), 72 deletions(-) diff --git a/libfprint/async.c b/libfprint/async.c index 07c20c30..6718bac4 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -52,7 +52,7 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb call libusb_device_handle *udevh; int r; - fp_dbg(""); + G_DEBUG_HERE(); r = libusb_open(ddev->udev, &udevh); if (r < 0) { fp_err("usb_open failed, error %d", r); @@ -86,7 +86,7 @@ API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb call /* Drivers call this when device deinitialisation has completed */ void fpi_drvcb_close_complete(struct fp_dev *dev) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_DEINITIALIZING); dev->state = DEV_STATE_DEINITIALIZED; libusb_close(dev->udev); @@ -196,7 +196,7 @@ void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result, /* Drivers call this when enrollment has stopped */ void fpi_drvcb_enroll_stopped(struct fp_dev *dev) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_ENROLL_STOPPING); dev->state = DEV_STATE_INITIALIZED; if (dev->enroll_stop_cb) @@ -217,7 +217,7 @@ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, struct fp_driver *drv = dev->drv; int r; - fp_dbg(""); + G_DEBUG_HERE(); if (!drv->enroll_start) return -ENOTSUP; @@ -255,7 +255,7 @@ API_EXPORTED int fp_async_verify_start(struct fp_dev *dev, struct fp_driver *drv = dev->drv; int r; - fp_dbg(""); + G_DEBUG_HERE(); if (!drv->verify_start) return -ENOTSUP; @@ -276,7 +276,7 @@ API_EXPORTED int fp_async_verify_start(struct fp_dev *dev, /* Drivers call this when verification has started */ void fpi_drvcb_verify_started(struct fp_dev *dev, int status) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_VERIFY_STARTING); if (status) { if (status > 0) { @@ -310,7 +310,7 @@ void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result, /* Drivers call this when verification has stopped */ void fpi_drvcb_verify_stopped(struct fp_dev *dev) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_VERIFY_STOPPING); dev->state = DEV_STATE_INITIALIZED; if (dev->verify_stop_cb) @@ -332,7 +332,7 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, gboolean iterating = (dev->state == DEV_STATE_VERIFYING); int r; - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_ERROR && dev->state != DEV_STATE_VERIFYING && dev->state != DEV_STATE_VERIFY_DONE); @@ -373,7 +373,7 @@ API_EXPORTED int fp_async_identify_start(struct fp_dev *dev, struct fp_driver *drv = dev->drv; int r; - fp_dbg(""); + G_DEBUG_HERE(); if (!drv->identify_start) return -ENOTSUP; dev->state = DEV_STATE_IDENTIFY_STARTING; @@ -440,7 +440,7 @@ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev, gboolean iterating = (dev->state == DEV_STATE_IDENTIFYING); int r; - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_IDENTIFYING && dev->state != DEV_STATE_IDENTIFY_DONE); @@ -469,7 +469,7 @@ API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev, /* Drivers call this when identification has stopped */ void fpi_drvcb_identify_stopped(struct fp_dev *dev) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_IDENTIFY_STOPPING); dev->state = DEV_STATE_INITIALIZED; if (dev->identify_stop_cb) @@ -491,7 +491,7 @@ API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional, struct fp_driver *drv = dev->drv; int r; - fp_dbg(""); + G_DEBUG_HERE(); if (!drv->capture_start) return -ENOTSUP; @@ -512,7 +512,7 @@ API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional, /* Drivers call this when capture has started */ void fpi_drvcb_capture_started(struct fp_dev *dev, int status) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_CAPTURE_STARTING); if (status) { if (status > 0) { @@ -545,7 +545,7 @@ void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result, /* Drivers call this when capture has stopped */ void fpi_drvcb_capture_stopped(struct fp_dev *dev) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_CAPTURE_STOPPING); dev->state = DEV_STATE_INITIALIZED; if (dev->capture_stop_cb) @@ -566,7 +566,7 @@ API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev, struct fp_driver *drv = dev->drv; int r; - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_ERROR && dev->state != DEV_STATE_CAPTURING && dev->state != DEV_STATE_CAPTURE_DONE); diff --git a/libfprint/core.c b/libfprint/core.c index 5deb3a6e..e01c16ca 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -833,7 +833,7 @@ API_EXPORTED int fp_init(void) { char *dbg = getenv("LIBFPRINT_DEBUG"); int r; - fp_dbg(""); + G_DEBUG_HERE(); r = libusb_init(&fpi_usb_ctx); if (r < 0) @@ -861,7 +861,7 @@ API_EXPORTED int fp_init(void) */ API_EXPORTED void fp_exit(void) { - fp_dbg(""); + G_DEBUG_HERE(); if (opened_devices) { GSList *copy = g_slist_copy(opened_devices); diff --git a/libfprint/data.c b/libfprint/data.c index 78f552c9..2fef5690 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -147,7 +147,7 @@ API_EXPORTED size_t fp_print_data_get_data(struct fp_print_data *data, GSList *list_item; unsigned char *buf; - fp_dbg(""); + G_DEBUG_HERE(); list_item = data->prints; while (list_item) { diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 50bc4834..40797db5 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -701,7 +701,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct aes1610_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); if (aesdev->deactivating) complete_deactivation(dev); else if (ssm->error) @@ -722,7 +722,7 @@ static void start_capture(struct fp_img_dev *dev) } ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); - fp_dbg(""); + G_DEBUG_HERE(); ssm->priv = dev; fpi_ssm_start(ssm, capture_sm_complete); } @@ -791,7 +791,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { struct aes1610_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); /* FIXME: if we're in the middle of a scan, we should cancel the scan. * maybe we can do this with a master reset, unconditionally? */ diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index f6e3edf4..a78a93d7 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -155,7 +155,7 @@ static void read_regs(struct fp_img_dev *dev, aes2501_read_regs_cb callback, struct aes_regwrite *regwrite = g_malloc(sizeof(*regwrite)); struct aes2501_read_regs *rdata = g_malloc(sizeof(*rdata)); - fp_dbg(""); + G_DEBUG_HERE(); regwrite->reg = AES2501_REG_CTRL2; regwrite->value = AES2501_CTRL2_READ_REGS; rdata->dev = dev; @@ -354,7 +354,7 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, static void start_finger_detection(struct fp_img_dev *dev) { struct aes2501_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); if (aesdev->deactivating) { complete_deactivation(dev); @@ -583,7 +583,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct aes2501_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); if (aesdev->deactivating) complete_deactivation(dev); else if (ssm->error) @@ -607,7 +607,7 @@ static void start_capture(struct fp_img_dev *dev) /* Reset gain */ strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); - fp_dbg(""); + G_DEBUG_HERE(); ssm->priv = dev; fpi_ssm_start(ssm, capture_sm_complete); } @@ -831,7 +831,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { struct aes2501_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); /* FIXME: if we're in the middle of a scan, we should cancel the scan. * maybe we can do this with a master reset, unconditionally? */ diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 387967ee..bc8ffc1b 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -159,7 +159,7 @@ static void start_finger_detection(struct fp_img_dev *dev) int r; struct aes2550_dev *aesdev = dev->priv; struct libusb_transfer *transfer; - fp_dbg(""); + G_DEBUG_HERE(); if (aesdev->deactivating) { complete_deactivation(dev); @@ -421,7 +421,7 @@ static void start_capture(struct fp_img_dev *dev) aesdev->heartbeat_cnt = 0; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); - fp_dbg(""); + G_DEBUG_HERE(); ssm->priv = dev; fpi_ssm_start(ssm, capture_sm_complete); } @@ -606,7 +606,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { struct aes2550_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); aesdev->deactivating = FALSE; g_slist_free(aesdev->strips); diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 9743b88d..98f6c759 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -437,7 +437,7 @@ static void start_capture(struct fp_img_dev *dev) } ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); - fp_dbg(""); + G_DEBUG_HERE(); ssm->priv = dev; fpi_ssm_start(ssm, capture_sm_complete); } @@ -623,7 +623,7 @@ void aesX660_dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { struct aesX660_dev *aesdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); aesdev->deactivating = FALSE; g_slist_free(aesdev->strips); diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index 976ce079..ccfd524e 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -62,7 +62,7 @@ struct elan_dev { static void elan_dev_reset(struct elan_dev *elandev) { - fp_dbg(""); + G_DEBUG_HERE(); BUG_ON(elandev->cur_transfer); @@ -88,7 +88,7 @@ static void elan_save_frame(struct fp_img_dev *dev) unsigned short *frame = g_malloc(elandev->frame_width * elandev->frame_height * 2); - fp_dbg(""); + G_DEBUG_HERE(); /* Raw images are vertical and perpendicular to swipe direction of a * normalized image, which means we need to make them horizontal before @@ -116,7 +116,7 @@ static void elan_process_frame(unsigned short *raw_frame, GSList ** frames) struct fpi_frame *frame = g_malloc(frame_size + sizeof(struct fpi_frame)); - fp_dbg(""); + G_DEBUG_HERE(); unsigned short min = 0xffff, max = 0; for (int i = 0; i < frame_size; i++) { @@ -147,7 +147,7 @@ static void elan_submit_image(struct fp_img_dev *dev) GSList *frames = NULL; struct fp_img *img; - fp_dbg(""); + G_DEBUG_HERE(); for (int i = 0; i < ELAN_SKIP_LAST_FRAMES; i++) elandev->frames = g_slist_next(elandev->frames); @@ -170,7 +170,7 @@ static void elan_cmd_done(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elandev->cmd_idx += 1; if (elandev->cmd_idx < elandev->cmds_len) @@ -185,7 +185,7 @@ static void elan_cmd_cb(struct libusb_transfer *transfer) struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elandev->cur_transfer = NULL; @@ -228,7 +228,7 @@ static void elan_cmd_read(struct fpi_ssm *ssm) struct elan_dev *elandev = dev->priv; int response_len = elandev->cmds[elandev->cmd_idx].response_len; - fp_dbg(""); + G_DEBUG_HERE(); if (elandev->cmds[elandev->cmd_idx].cmd == read_cmds[0].cmd) /* raw data has 2-byte "pixels" and the frame is vertical */ @@ -260,7 +260,7 @@ static void elan_run_next_cmd(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); struct libusb_transfer *transfer = libusb_alloc_transfer(0); if (!transfer) { @@ -287,7 +287,7 @@ static void elan_run_cmds(struct fpi_ssm *ssm, const struct elan_cmd *cmds, struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elandev->cmds = cmds; elandev->cmds_len = cmds_len; @@ -323,7 +323,7 @@ static void elan_deactivate(struct fp_img_dev *dev) { struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elan_dev_reset(elandev); @@ -386,7 +386,7 @@ static void capture_complete(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); if (elandev->deactivating) elan_deactivate(dev); @@ -423,7 +423,7 @@ static void elan_capture(struct fp_img_dev *dev) { struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elan_dev_reset(elandev); struct fpi_ssm *ssm = @@ -466,7 +466,7 @@ static void calibrate_complete(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); if (elandev->deactivating) elan_deactivate(dev); @@ -483,7 +483,7 @@ static void elan_calibrate(struct fp_img_dev *dev) { struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elan_dev_reset(elandev); struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_calibrate_run_state, @@ -536,7 +536,7 @@ static void activate_complete(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); if (elandev->deactivating) elan_deactivate(dev); @@ -551,7 +551,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elan_dev_reset(elandev); struct fpi_ssm *ssm = @@ -567,7 +567,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) struct elan_dev *elandev; int r; - fp_dbg(""); + G_DEBUG_HERE(); r = libusb_claim_interface(dev->udev, 0); if (r < 0) { @@ -584,7 +584,7 @@ static void dev_deinit(struct fp_img_dev *dev) { struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elan_dev_reset(elandev); g_free(elandev); @@ -596,7 +596,7 @@ static void dev_deactivate(struct fp_img_dev *dev) { struct elan_dev *elandev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); elandev->deactivating = TRUE; diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 73e8aec7..63c051e0 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -730,7 +730,7 @@ static void sm_await_intr(struct fpi_ssm *ssm) return; } - fp_dbg(""); + G_DEBUG_HERE(); data = g_malloc(4); libusb_fill_interrupt_transfer(transfer, dev->udev, 0x83, data, 4, sm_await_intr_cb, ssm, 0); @@ -1224,7 +1224,7 @@ static void deactivate_done(struct fp_img_dev *dev) { struct sonly_dev *sdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); free_img_transfers(sdev); g_free(sdev->rowbuf); sdev->rowbuf = NULL; diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 9d45091f..e4f0edc9 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -256,7 +256,7 @@ static void start_finger_detection(struct fp_img_dev *dev) int r; struct upektc_dev *upekdev = dev->priv; struct libusb_transfer *transfer; - fp_dbg(""); + G_DEBUG_HERE(); if (upekdev->deactivating) { complete_deactivation(dev); @@ -401,7 +401,7 @@ static void start_capture(struct fp_img_dev *dev) } ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); - fp_dbg(""); + G_DEBUG_HERE(); ssm->priv = dev; fpi_ssm_start(ssm, capture_sm_complete); } @@ -427,7 +427,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { struct upektc_dev *upekdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); upekdev->deactivating = FALSE; fpi_imgdev_deactivate_complete(dev); diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index ae32a6b2..286f3d97 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -366,7 +366,7 @@ static void sm_do_challenge_response(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; int r; - fp_dbg(""); + G_DEBUG_HERE(); r = read_regs(dev, REG_CHALLENGE, CR_LENGTH, challenge_cb, ssm); if (r < 0) fpi_ssm_mark_aborted(ssm, r); diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 1f127a8c..528dd475 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -256,7 +256,7 @@ static void sm_do_capture(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct v5s_dev *vdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); vdev->capture_img = fpi_img_new_for_imgdev(dev); vdev->capture_iteration = 0; capture_iterate(ssm); diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 3ee13e3b..625a411e 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -589,7 +589,7 @@ static void vfs_abort_print(struct fpi_ssm *ssm) { unsigned char data[0x06] = { 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00 }; - fp_dbg(""); + G_DEBUG_HERE(); /* Run swap sequential state machine */ m_swap (ssm, data, 0x06); @@ -622,7 +622,7 @@ static void vfs_get_finger_state(struct fpi_ssm *ssm) { unsigned char data[0x06] = { 0x00, 0x00, 0x00, 0x00, 0x16, 0x00 }; - fp_dbg(""); + G_DEBUG_HERE(); /* Run swap sequential state machine */ m_swap (ssm, data, 0x06); @@ -634,7 +634,7 @@ static void vfs_img_load(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; struct vfs101_dev *vdev = dev->priv; - fp_dbg(""); + G_DEBUG_HERE(); /* Reset buffer length */ vdev->length = 0; diff --git a/libfprint/imgdev.c b/libfprint/imgdev.c index 4408c230..030109b9 100644 --- a/libfprint/imgdev.c +++ b/libfprint/imgdev.c @@ -231,7 +231,7 @@ void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img) { struct fp_print_data *print; int r; - fp_dbg(""); + G_DEBUG_HERE(); if (imgdev->action_state != IMG_ACQUIRE_STATE_AWAIT_IMAGE) { fp_dbg("ignoring due to current state %d", imgdev->action_state); @@ -360,7 +360,7 @@ void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status) void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev) { - fp_dbg(""); + G_DEBUG_HERE(); switch (imgdev->action) { case IMG_ACTION_ENROLL: diff --git a/libfprint/poll.c b/libfprint/poll.c index cdae4f69..7557bb0e 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -126,7 +126,7 @@ struct fpi_timeout *fpi_timeout_add(unsigned int msec, fpi_timeout_fn callback, void fpi_timeout_cancel(struct fpi_timeout *timeout) { - fp_dbg(""); + G_DEBUG_HERE(); active_timers = g_slist_remove(active_timers, timeout); g_free(timeout); } @@ -172,7 +172,7 @@ static int get_next_timeout_expiry(struct timeval *out, /* handle a timeout that has expired */ static void handle_timeout(struct fpi_timeout *timeout) { - fp_dbg(""); + G_DEBUG_HERE(); timeout->callback(timeout->data); active_timers = g_slist_remove(active_timers, timeout); g_free(timeout); diff --git a/libfprint/sync.c b/libfprint/sync.c index 81b80738..c324e0be 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -53,7 +53,7 @@ API_EXPORTED struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev) struct sync_open_data *odata = g_malloc0(sizeof(*odata)); int r; - fp_dbg(""); + G_DEBUG_HERE(); r = fp_async_dev_open(ddev, sync_open_cb, odata); if (r) goto out; @@ -74,7 +74,7 @@ out: static void sync_close_cb(struct fp_dev *dev, void *user_data) { - fp_dbg(""); + G_DEBUG_HERE(); gboolean *closed = user_data; *closed = TRUE; } @@ -93,7 +93,7 @@ API_EXPORTED void fp_dev_close(struct fp_dev *dev) if (!dev) return; - fp_dbg(""); + G_DEBUG_HERE(); fp_async_dev_close(dev, sync_close_cb, &closed); while (!closed) if (fp_handle_events() < 0) @@ -121,7 +121,7 @@ static void sync_enroll_cb(struct fp_dev *dev, int result, static void enroll_stop_cb(struct fp_dev *dev, void *user_data) { gboolean *stopped = user_data; - fp_dbg(""); + G_DEBUG_HERE(); *stopped = TRUE; } @@ -189,7 +189,7 @@ API_EXPORTED int fp_enroll_finger_img(struct fp_dev *dev, gboolean stopped = FALSE; struct sync_enroll_data *edata = NULL; int r; - fp_dbg(""); + G_DEBUG_HERE(); /* FIXME __enroll_stage is ugly, can we replace it by some function that * says whether we're enrolling or not, and then put __enroll_stage into @@ -324,7 +324,7 @@ static void sync_verify_cb(struct fp_dev *dev, int result, struct fp_img *img, static void verify_stop_cb(struct fp_dev *dev, void *user_data) { gboolean *stopped = user_data; - fp_dbg(""); + G_DEBUG_HERE(); *stopped = TRUE; } @@ -460,7 +460,7 @@ static void sync_identify_cb(struct fp_dev *dev, int result, static void identify_stop_cb(struct fp_dev *dev, void *user_data) { gboolean *stopped = user_data; - fp_dbg(""); + G_DEBUG_HERE(); *stopped = TRUE; } @@ -605,7 +605,7 @@ static void sync_capture_cb(struct fp_dev *dev, int result, struct fp_img *img, static void capture_stop_cb(struct fp_dev *dev, void *user_data) { gboolean *stopped = user_data; - fp_dbg(""); + G_DEBUG_HERE(); *stopped = TRUE; } /** From 32fcfde86b3d57305c29b545aa084d28c7c76fe9 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 17:48:55 +0200 Subject: [PATCH 074/141] lib: Use GLib and libusb directly for debug output Use GLib internally to output debug information, and tell about libusb's LIBUSB_DEBUG envvar for libusb debug. fp_set_debug() is now a no-op. https://bugs.freedesktop.org/show_bug.cgi?id=106552 --- libfprint/aeslib.c | 3 +- libfprint/assembling.c | 3 +- libfprint/async.c | 4 +- libfprint/core.c | 106 ++++++--------------------------- libfprint/drivers/aes1610.c | 3 +- libfprint/drivers/aes1660.c | 3 +- libfprint/drivers/aes2501.c | 3 +- libfprint/drivers/aes2550.c | 3 +- libfprint/drivers/aes2660.c | 4 +- libfprint/drivers/aes3500.c | 3 +- libfprint/drivers/aes3k.c | 3 +- libfprint/drivers/aes4000.c | 3 +- libfprint/drivers/aesx660.c | 3 +- libfprint/drivers/elan.c | 3 +- libfprint/drivers/etes603.c | 6 +- libfprint/drivers/fdu2000.c | 7 ++- libfprint/drivers/upeksonly.c | 4 +- libfprint/drivers/upektc.c | 3 +- libfprint/drivers/upektc_img.c | 3 +- libfprint/drivers/upekts.c | 4 +- libfprint/drivers/uru4000.c | 4 +- libfprint/drivers/vcom5s.c | 4 +- libfprint/drivers/vfs0050.c | 3 +- libfprint/drivers/vfs101.c | 8 +-- libfprint/drivers/vfs301.c | 4 +- libfprint/drv.c | 4 +- libfprint/fp_internal.h | 31 ++++------ libfprint/poll.c | 4 +- libfprint/sync.c | 4 +- meson.build | 1 + 30 files changed, 90 insertions(+), 151 deletions(-) diff --git a/libfprint/aeslib.c b/libfprint/aeslib.c index 978454d8..61811ade 100644 --- a/libfprint/aeslib.c +++ b/libfprint/aeslib.c @@ -19,13 +19,14 @@ #define FP_COMPONENT "aeslib" +#include "fp_internal.h" + #include #include #include #include -#include "fp_internal.h" #include "assembling.h" #include "aeslib.h" diff --git a/libfprint/assembling.c b/libfprint/assembling.c index d34cf377..2c4ccc68 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -21,13 +21,14 @@ #define FP_COMPONENT "assembling" +#include "fp_internal.h" + #include #include #include #include -#include "fp_internal.h" #include "assembling.h" static unsigned int calc_error(struct fpi_frame_asmbl_ctx *ctx, diff --git a/libfprint/async.c b/libfprint/async.c index 6718bac4..f469a36f 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -19,12 +19,12 @@ #define FP_COMPONENT "async" +#include "fp_internal.h" + #include #include #include -#include "fp_internal.h" - /* Drivers call this when device initialisation has completed */ void fpi_drvcb_open_complete(struct fp_dev *dev, int status) { diff --git a/libfprint/core.c b/libfprint/core.c index e01c16ca..06fb24ab 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -27,9 +27,6 @@ #include "fp_internal.h" -static int log_level = 0; -static int log_level_fixed = 0; - libusb_context *fpi_usb_ctx = NULL; GSList *opened_devices = NULL; @@ -116,52 +113,6 @@ GSList *opened_devices = NULL; static GSList *registered_drivers = NULL; -void fpi_log(enum fpi_log_level level, const char *component, - const char *function, const char *format, ...) -{ - va_list args; - FILE *stream = stdout; - const char *prefix; - - if (!log_level) - return; - if (level == FPRINT_LOG_LEVEL_WARNING && log_level < 2) - return; - if (level == FPRINT_LOG_LEVEL_INFO && log_level < 3) - return; - - switch (level) { - case FPRINT_LOG_LEVEL_INFO: - prefix = "info"; - break; - case FPRINT_LOG_LEVEL_WARNING: - stream = stderr; - prefix = "warning"; - break; - case FPRINT_LOG_LEVEL_ERROR: - stream = stderr; - prefix = "error"; - break; - case FPRINT_LOG_LEVEL_DEBUG: - stream = stderr; - prefix = "debug"; - break; - default: - stream = stderr; - prefix = "unknown"; - break; - } - - fprintf(stream, "%s:%s [%s] ", component ? component : "fp", prefix, - function); - - va_start (args, format); - vfprintf(stream, format, args); - va_end (args); - - fprintf(stream, "\n"); -} - static void register_driver(struct fp_driver *drv) { if (drv->id == 0) { @@ -787,38 +738,11 @@ API_EXPORTED int fp_dev_get_img_height(struct fp_dev *dev) * fp_set_debug: * @level: the verbosity level * - * Set message verbosity. - * - Level 0: no messages ever printed by the library (default) - * - Level 1: error messages are printed to stderr - * - Level 2: warning and error messages are printed to stderr - * - Level 3: informational messages are printed to stdout, warning and error - * messages are printed to stderr - * - * The default level is 0, which means no messages are ever printed. If you - * choose to increase the message verbosity level, ensure that your - * application does not close the stdout/stderr file descriptors. - * - * You are advised to set level 3. libfprint is conservative with its message - * logging and most of the time, will only log messages that explain error - * conditions and other oddities. This will help you debug your software. - * - * If the LIBFPRINT_DEBUG environment variable was set when libfprint was - * initialized, this function does nothing: the message verbosity is fixed - * to the value in the environment variable. - * - * If libfprint was compiled without any message logging, this function does - * nothing: you'll never get any messages. - * - * If libfprint was compiled with verbose debug message logging, this function - * does nothing: you'll always get messages from all levels. + * This call does nothing, see fp_init() for details. */ API_EXPORTED void fp_set_debug(int level) { - if (log_level_fixed) - return; - - log_level = level; - libusb_set_debug(fpi_usb_ctx, level); + /* Nothing */ } /** @@ -827,11 +751,27 @@ API_EXPORTED void fp_set_debug(int level) * Initialise libfprint. This function must be called before you attempt to * use the library in any way. * + * To enable debug output of libfprint specifically, use GLib's `G_MESSAGES_DEBUG` + * environment variable as explained in [Running and debugging GLib Applications](https://developer.gnome.org/glib/stable/glib-running.html#G_MESSAGES_DEBUG). + * + * The log domains used in libfprint are either `libfprint` or `libfprint-FP_COMPONENT` + * where `FP_COMPONENT` is defined in the source code for each driver, or component + * of the library. Starting with `all` and trimming down is advised. + * + * To enable debugging of libusb, for USB-based fingerprint reader drivers, use + * libusb's `LIBUSB_DEBUG` environment variable as explained in the + * [libusb-1.0 API Reference](http://libusb.sourceforge.net/api-1.0/#msglog). + * + * Example: + * + * ``` + * LIBUSB_DEBUG=4 G_MESSAGES_DEBUG=all my-libfprint-application + * ``` + * * Returns: 0 on success, non-zero on error. */ API_EXPORTED int fp_init(void) { - char *dbg = getenv("LIBFPRINT_DEBUG"); int r; G_DEBUG_HERE(); @@ -839,14 +779,6 @@ API_EXPORTED int fp_init(void) if (r < 0) return r; - if (dbg) { - log_level = atoi(dbg); - if (log_level) { - log_level_fixed = 1; - libusb_set_debug(fpi_usb_ctx, log_level); - } - } - register_drivers(); fpi_poll_init(); return 0; diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 40797db5..b47396b6 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -25,6 +25,8 @@ #define FP_COMPONENT "aes1610" +#include "fp_internal.h" + #include #include @@ -32,7 +34,6 @@ #include #include -#include #include "driver_ids.h" diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index 32bea4eb..ad28b06d 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -19,6 +19,8 @@ #define FP_COMPONENT "aes1660" +#include "fp_internal.h" + #include #include @@ -26,7 +28,6 @@ #include -#include #include #include diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index a78a93d7..c1bbc98d 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -23,6 +23,8 @@ #define FP_COMPONENT "aes2501" +#include "fp_internal.h" + #include #include @@ -30,7 +32,6 @@ #include #include -#include #include "aes2501.h" #include "driver_ids.h" diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index bc8ffc1b..0516bbc1 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -23,6 +23,8 @@ #define FP_COMPONENT "aes2550" +#include "fp_internal.h" + #include #include @@ -30,7 +32,6 @@ #include #include -#include #include "aes2550.h" #include "driver_ids.h" diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index efe9670a..bfc457de 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -19,6 +19,8 @@ #define FP_COMPONENT "aes2660" +#include "fp_internal.h" + #include #include @@ -26,8 +28,6 @@ #include -#include - #include #include diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c index f229a1ac..44286709 100644 --- a/libfprint/drivers/aes3500.c +++ b/libfprint/drivers/aes3500.c @@ -29,13 +29,14 @@ #define FP_COMPONENT "aes3500" +#include "fp_internal.h" + #include #include #include #include -#include #include "aes3k.h" #include "driver_ids.h" diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c index ba969010..f50d2b4c 100644 --- a/libfprint/drivers/aes3k.c +++ b/libfprint/drivers/aes3k.c @@ -36,13 +36,14 @@ #define FP_COMPONENT "aes3k" +#include "fp_internal.h" + #include #include #include #include -#include #include "aes3k.h" diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index d4f90b79..6118f334 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -26,13 +26,14 @@ #define FP_COMPONENT "aes4000" +#include "fp_internal.h" + #include #include #include #include -#include #include "aes3k.h" #include "driver_ids.h" diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 98f6c759..ab679462 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -23,6 +23,8 @@ #define FP_COMPONENT "aesX660" +#include "fp_internal.h" + #include #include @@ -32,7 +34,6 @@ #include #include -#include #include "aesx660.h" diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index ccfd524e..e528ecb3 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -20,10 +20,11 @@ #define FP_COMPONENT "elan" +#include "fp_internal.h" + #include #include #include -#include #include #include "elan.h" diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 97957579..60f81b23 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -33,6 +33,10 @@ * */ +#define FP_COMPONENT "etes603" + +#include "fp_internal.h" + #include #include #include @@ -41,8 +45,6 @@ #include #include -#define FP_COMPONENT "etes603" -#include #include "driver_ids.h" /* libusb defines */ diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c index e14b860e..b95ff62f 100644 --- a/libfprint/drivers/fdu2000.c +++ b/libfprint/drivers/fdu2000.c @@ -17,15 +17,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define FP_COMPONENT "fdu2000" + +#include "fp_internal.h" + #include #include #include #include -#define FP_COMPONENT "fdu2000" -#include - #include "driver_ids.h" #ifndef HAVE_MEMMEM diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 63c051e0..4d228d97 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -25,14 +25,14 @@ #define FP_COMPONENT "upeksonly" +#include "fp_internal.h" + #include #include #include #include -#include - #include #include "upeksonly.h" diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index e4f0edc9..107f93db 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -20,10 +20,11 @@ #define FP_COMPONENT "upektc" +#include "fp_internal.h" + #include #include #include -#include #include "upektc.h" #include "driver_ids.h" diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 843bcffe..c193c077 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -19,13 +19,14 @@ #define FP_COMPONENT "upektc_img" +#include "fp_internal.h" + #include #include #include #include -#include #include "upektc_img.h" #include "driver_ids.h" diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index 4e572b98..d0704042 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -27,14 +27,14 @@ #define FP_COMPONENT "upekts" +#include "fp_internal.h" + #include #include #include #include -#include - #include "driver_ids.h" #define EP_IN (1 | LIBUSB_ENDPOINT_IN) diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 286f3d97..600bb27c 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -20,6 +20,8 @@ #define FP_COMPONENT "uru4000" +#include "fp_internal.h" + #include #include #include @@ -28,8 +30,6 @@ #include #include -#include - #include "driver_ids.h" #define EP_INTR (1 | LIBUSB_ENDPOINT_IN) diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 528dd475..dfbdca77 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -19,6 +19,8 @@ #define FP_COMPONENT "vcom5s" +#include "fp_internal.h" + /* TODO: * calibration? * image size: windows gets 300x300 through vpas enrollment util? @@ -32,8 +34,6 @@ #include #include -#include - #include "driver_ids.h" #define CTRL_IN 0xc0 diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index 31d793cd..45adaa49 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -19,9 +19,10 @@ #define FP_COMPONENT "vfs0050" +#include "fp_internal.h" + #include #include -#include #include #include "driver_ids.h" diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 625a411e..afc72d9d 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -17,14 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define FP_COMPONENT "vfs101" + +#include "fp_internal.h" + #include #include #include -#define FP_COMPONENT "vfs101" - -#include - #include "driver_ids.h" /* Input-Output usb endpoint */ diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 833c05b0..1b8a7db2 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -21,6 +21,8 @@ #define FP_COMPONENT "vfs301" +#include "fp_internal.h" + #include #include #include @@ -32,8 +34,6 @@ #include "vfs301_proto.h" #include -#include - #include "driver_ids.h" /************************** GENERIC STUFF *************************************/ diff --git a/libfprint/drv.c b/libfprint/drv.c index a7ba846c..719417d9 100644 --- a/libfprint/drv.c +++ b/libfprint/drv.c @@ -19,11 +19,11 @@ #define FP_COMPONENT "drv" +#include "fp_internal.h" + #include #include -#include "fp_internal.h" - /* SSM: sequential state machine * Asynchronous driver design encourages some kind of state machine behind it. * In most cases, the state machine is entirely linear - you only go to the diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index fdaa408d..3cf56294 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -21,8 +21,13 @@ #define __FPRINT_INTERNAL_H__ #include -#include +#ifdef FP_COMPONENT +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "libfprint-"FP_COMPONENT +#endif + +#include #include #include @@ -34,26 +39,10 @@ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) -enum fpi_log_level { - FPRINT_LOG_LEVEL_DEBUG, - FPRINT_LOG_LEVEL_INFO, - FPRINT_LOG_LEVEL_WARNING, - FPRINT_LOG_LEVEL_ERROR, -}; - -void fpi_log(enum fpi_log_level, const char *component, const char *function, - const char *format, ...); - -#ifndef FP_COMPONENT -#define FP_COMPONENT NULL -#endif - -#define _fpi_log(level, fmt...) fpi_log(level, FP_COMPONENT, __FUNCTION__, fmt) - -#define fp_dbg(fmt...) _fpi_log(FPRINT_LOG_LEVEL_DEBUG, fmt) -#define fp_info(fmt...) _fpi_log(FPRINT_LOG_LEVEL_INFO, fmt) -#define fp_warn(fmt...) _fpi_log(FPRINT_LOG_LEVEL_WARNING, fmt) -#define fp_err(fmt...) _fpi_log(FPRINT_LOG_LEVEL_ERROR, fmt) +#define fp_dbg g_debug +#define fp_info g_debug +#define fp_warn g_warning +#define fp_err g_error #ifndef NDEBUG #define BUG_ON(condition) \ diff --git a/libfprint/poll.c b/libfprint/poll.c index 7557bb0e..c8201036 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -19,6 +19,8 @@ #define FP_COMPONENT "poll" +#include "fp_internal.h" + #include #include #include @@ -27,8 +29,6 @@ #include #include -#include "fp_internal.h" - /** * SECTION:events * @title: Initialisation and events handling diff --git a/libfprint/sync.c b/libfprint/sync.c index c324e0be..c194f5ca 100644 --- a/libfprint/sync.c +++ b/libfprint/sync.c @@ -19,11 +19,11 @@ #define FP_COMPONENT "sync" +#include "fp_internal.h" + #include #include -#include "fp_internal.h" - struct sync_open_data { struct fp_dev *dev; int status; diff --git a/meson.build b/meson.build index 93603b6b..c11b3fde 100644 --- a/meson.build +++ b/meson.build @@ -9,6 +9,7 @@ project('libfprint', [ 'c', 'cpp' ], meson_version: '>= 0.45.0') add_project_arguments([ '-D_GNU_SOURCE' ], language: 'c') +add_project_arguments([ '-DG_LOG_DOMAIN="libfprint"' ], language: 'c') libfprint_conf = configuration_data() From ff09456cf5adaead2d3993a7e1476e56a23ff7bb Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 23 May 2018 19:14:33 +0200 Subject: [PATCH 075/141] lib: Use g_assert* to implement BUG() and BUG_ON() assertions --- libfprint/fp_internal.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 3cf56294..9eb73891 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -44,14 +44,8 @@ #define fp_warn g_warning #define fp_err g_error -#ifndef NDEBUG -#define BUG_ON(condition) \ - if ((condition)) fp_err("BUG at %s:%d", __FILE__, __LINE__) -#else -#define BUG_ON(condition) -#endif - -#define BUG() BUG_ON(1) +#define BUG_ON(condition) g_assert(condition) +#define BUG() g_assert_not_reached() enum fp_dev_state { DEV_STATE_INITIAL = 0, From fc92f62136ded3d2f61a878f50099e1c60aa165b Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 12:16:18 +0200 Subject: [PATCH 076/141] build: Remove the need to modify sources for new drivers Instead of having to modify both fp_internal.h to list each driver definition structure, and core.c to add those drivers to arrays we can loop over, generate both of those using meson. --- libfprint/core.c | 68 +---------------------------------------- libfprint/empty_file | 1 + libfprint/fp_internal.h | 61 +----------------------------------- libfprint/meson.build | 17 ++++++++++- meson.build | 16 ++++++++++ 5 files changed, 35 insertions(+), 128 deletions(-) create mode 100644 libfprint/empty_file diff --git a/libfprint/core.c b/libfprint/core.c index 06fb24ab..b65cfb6b 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -123,73 +123,7 @@ static void register_driver(struct fp_driver *drv) fp_dbg("registered driver %s", drv->name); } -static struct fp_driver * const primitive_drivers[] = { -#ifdef ENABLE_UPEKTS - &upekts_driver, -#endif -}; - -static struct fp_img_driver * const img_drivers[] = { -#ifdef ENABLE_AES3500 - &aes3500_driver, -#endif -#ifdef ENABLE_AES4000 - &aes4000_driver, -#endif -#ifdef ENABLE_AES2501 - &aes2501_driver, -#endif -#ifdef ENABLE_AES2550 - &aes2550_driver, -#endif -#ifdef ENABLE_URU4000 - &uru4000_driver, -#endif -#ifdef ENABLE_VCOM5S - &vcom5s_driver, -#endif -#ifdef ENABLE_UPEKSONLY - &upeksonly_driver, -#endif - -#ifdef ENABLE_AES1610 - &aes1610_driver, -#endif -#ifdef ENABLE_AES1660 - &aes1660_driver, -#endif -#ifdef ENABLE_AES2660 - &aes2660_driver, -#endif -#ifdef ENABLE_VFS101 - &vfs101_driver, -#endif -#ifdef ENABLE_VFS301 - &vfs301_driver, -#endif -#ifdef ENABLE_VFS5011 - &vfs5011_driver, -#endif -#ifdef ENABLE_UPEKTC - &upektc_driver, -#endif -#ifdef ENABLE_UPEKTC_IMG - &upektc_img_driver, -#endif -#ifdef ENABLE_ETES603 - &etes603_driver, -#endif -#ifdef ENABLE_VFS0050 - &vfs0050_driver, -#endif -#ifdef ENABLE_ELAN - &elan_driver, -#endif -/*#ifdef ENABLE_FDU2000 - &fdu2000_driver, -#endif - */ -}; +#include "drivers_arrays.h" static void register_drivers(void) { diff --git a/libfprint/empty_file b/libfprint/empty_file new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/libfprint/empty_file @@ -0,0 +1 @@ + diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 9eb73891..9c36917d 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -222,66 +222,7 @@ struct fp_img_driver { void (*deactivate)(struct fp_img_dev *dev); }; -#ifdef ENABLE_UPEKTS -extern struct fp_driver upekts_driver; -#endif -#ifdef ENABLE_UPEKTC -extern struct fp_img_driver upektc_driver; -#endif -#ifdef ENABLE_UPEKSONLY -extern struct fp_img_driver upeksonly_driver; -#endif -#ifdef ENABLE_URU4000 -extern struct fp_img_driver uru4000_driver; -#endif -#ifdef ENABLE_AES1610 -extern struct fp_img_driver aes1610_driver; -#endif -#ifdef ENABLE_AES1660 -extern struct fp_img_driver aes1660_driver; -#endif -#ifdef ENABLE_AES2501 -extern struct fp_img_driver aes2501_driver; -#endif -#ifdef ENABLE_AES2550 -extern struct fp_img_driver aes2550_driver; -#endif -#ifdef ENABLE_AES2660 -extern struct fp_img_driver aes2660_driver; -#endif -#ifdef ENABLE_AES3500 -extern struct fp_img_driver aes3500_driver; -#endif -#ifdef ENABLE_AES4000 -extern struct fp_img_driver aes4000_driver; -#endif -#ifdef ENABLE_FDU2000 -extern struct fp_img_driver fdu2000_driver; -#endif -#ifdef ENABLE_VCOM5S -extern struct fp_img_driver vcom5s_driver; -#endif -#ifdef ENABLE_VFS101 -extern struct fp_img_driver vfs101_driver; -#endif -#ifdef ENABLE_VFS301 -extern struct fp_img_driver vfs301_driver; -#endif -#ifdef ENABLE_VFS5011 -extern struct fp_img_driver vfs5011_driver; -#endif -#ifdef ENABLE_UPEKTC_IMG -extern struct fp_img_driver upektc_img_driver; -#endif -#ifdef ENABLE_ETES603 -extern struct fp_img_driver etes603_driver; -#endif -#ifdef ENABLE_VFS0050 -extern struct fp_img_driver vfs0050_driver; -#endif -#ifdef ENABLE_ELAN -extern struct fp_img_driver elan_driver; -#endif +#include "drivers_definitions.h" extern libusb_context *fpi_usb_ctx; extern GSList *opened_devices; diff --git a/libfprint/meson.build b/libfprint/meson.build index 6bb919f2..ffea1e24 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -128,7 +128,6 @@ foreach driver: drivers if driver == 'elan' drivers_sources += [ 'drivers/elan.c', 'drivers/elan.h' ] endif - drivers_cflags += [ '-DENABLE_' + driver.to_upper() + '=1' ] endforeach if aeslib @@ -146,6 +145,22 @@ if imaging_dep.found() other_sources += [ 'pixman.c' ] endif +libfprint_sources += configure_file(input: 'empty_file', + output: 'drivers_definitions.h', + capture: true, + command: [ + '/bin/echo', + drivers_struct_list + ]) + +libfprint_sources += configure_file(input: 'empty_file', + output: 'drivers_arrays.h', + capture: true, + command: [ + '/bin/echo', + drivers_primitive_array + '\n\n' + drivers_img_array + ]) + deps = [ mathlib_dep, glib_dep, libusb_dep, nss_dep, imaging_dep ] libfprint = library('fprint', libfprint_sources + drivers_sources + nbis_sources + other_sources, diff --git a/meson.build b/meson.build index c11b3fde..ca705dd5 100644 --- a/meson.build +++ b/meson.build @@ -46,6 +46,7 @@ mathlib_dep = cc.find_library('m', required: false) # Drivers drivers = get_option('drivers').split(',') all_drivers = [ 'upekts', 'upektc', 'upeksonly', 'vcom5s', 'uru4000', 'aes1610', 'aes1660', 'aes2501', 'aes2550', 'aes2660', 'aes3500', 'aes4000', 'vfs101', 'vfs301', 'vfs5011', 'upektc_img', 'etes603', 'vfs0050', 'elan' ] +primitive_drivers = [ 'upekts' ] if drivers == [ 'all' ] drivers = all_drivers @@ -71,6 +72,21 @@ foreach driver: drivers endif endforeach +# Export the drivers' structures to the core code +drivers_struct_list = '' +drivers_img_array = 'static struct fp_img_driver * const img_drivers[] = {\n' +drivers_primitive_array = 'static struct fp_driver * const primitive_drivers[] = {\n' +foreach driver: drivers + if primitive_drivers.contains(driver) + drivers_struct_list += 'extern struct fp_driver ' + driver + '_driver;\n' + drivers_primitive_array += ' &' + driver + '_driver,\n' + else + drivers_struct_list += 'extern struct fp_img_driver ' + driver + '_driver;\n' + drivers_img_array += ' &' + driver + '_driver,\n' + endif +endforeach +drivers_img_array += '};' +drivers_primitive_array += '};' root_inc = include_directories('.') From 901a6f7fedc84a97e797fa53e5e25bca28c0409b Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 12:41:35 +0200 Subject: [PATCH 077/141] lib: Add macro for deprecated functions --- libfprint/fprint.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfprint/fprint.h b/libfprint/fprint.h index fd7d6336..76682edf 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -27,6 +27,8 @@ extern "C" { #include #include +#define LIBFPRINT_DEPRECATED __attribute__((__deprecated__)) + /** * fp_dscv_dev: * From eb8f7ba3b2938f8e98100ac645b2baf52fecb0a1 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 12:42:18 +0200 Subject: [PATCH 078/141] lib: Mark fp_set_debug() as deprecated As per the documentation. --- libfprint/fprint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 76682edf..d5bb3e53 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -342,7 +342,7 @@ void fp_set_pollfd_notifiers(fp_pollfd_added_cb added_cb, /* Library */ int fp_init(void); void fp_exit(void); -void fp_set_debug(int level); +void fp_set_debug(int level) LIBFPRINT_DEPRECATED; /* Asynchronous I/O */ From 15afe43cf0e6a73170f77d378e194cd87ca9b162 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 12:42:47 +0200 Subject: [PATCH 079/141] examples: Replace deprecated fp_set_debug() --- examples/enroll.c | 4 +++- examples/img_capture.c | 4 +++- examples/img_capture_continuous.c | 4 +++- examples/verify.c | 4 +++- examples/verify_live.c | 4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/examples/enroll.c b/examples/enroll.c index f2ba9bec..4eea39ad 100644 --- a/examples/enroll.c +++ b/examples/enroll.c @@ -110,12 +110,14 @@ int main(void) "Ctrl+C\n"); getchar(); + setenv ("G_MESSAGES_DEBUG", "all", 0); + setenv ("LIBUSB_DEBUG", "3", 0); + r = fp_init(); if (r < 0) { fprintf(stderr, "Failed to initialize libfprint\n"); exit(1); } - fp_set_debug(3); discovered_devs = fp_discover_devs(); if (!discovered_devs) { diff --git a/examples/img_capture.c b/examples/img_capture.c index ba256df8..c65c73d0 100644 --- a/examples/img_capture.c +++ b/examples/img_capture.c @@ -42,12 +42,14 @@ int main(void) struct fp_dev *dev; struct fp_img *img = NULL; + setenv ("G_MESSAGES_DEBUG", "all", 0); + setenv ("LIBUSB_DEBUG", "3", 0); + r = fp_init(); if (r < 0) { fprintf(stderr, "Failed to initialize libfprint\n"); exit(1); } - fp_set_debug(3); discovered_devs = fp_discover_devs(); if (!discovered_devs) { diff --git a/examples/img_capture_continuous.c b/examples/img_capture_continuous.c index 94459b13..7dcb5222 100644 --- a/examples/img_capture_continuous.c +++ b/examples/img_capture_continuous.c @@ -141,12 +141,14 @@ int main(void) int img_height; int standardize = 0; + setenv ("G_MESSAGES_DEBUG", "all", 0); + setenv ("LIBUSB_DEBUG", "3", 0); + r = fp_init(); if (r < 0) { fprintf(stderr, "Failed to initialize libfprint\n"); exit(1); } - fp_set_debug(3); discovered_devs = fp_discover_devs(); if (!discovered_devs) { diff --git a/examples/verify.c b/examples/verify.c index 60a2ccb6..26566edd 100644 --- a/examples/verify.c +++ b/examples/verify.c @@ -86,12 +86,14 @@ int main(void) struct fp_dev *dev; struct fp_print_data *data; + setenv ("G_MESSAGES_DEBUG", "all", 0); + setenv ("LIBUSB_DEBUG", "3", 0); + r = fp_init(); if (r < 0) { fprintf(stderr, "Failed to initialize libfprint\n"); exit(1); } - fp_set_debug(3); discovered_devs = fp_discover_devs(); if (!discovered_devs) { diff --git a/examples/verify_live.c b/examples/verify_live.c index 27acb3ba..82ec2abc 100644 --- a/examples/verify_live.c +++ b/examples/verify_live.c @@ -129,12 +129,14 @@ int main(void) struct fp_dev *dev; struct fp_print_data *data; + setenv ("G_MESSAGES_DEBUG", "all", 0); + setenv ("LIBUSB_DEBUG", "3", 0); + r = fp_init(); if (r < 0) { fprintf(stderr, "Failed to initialize libfprint\n"); exit(1); } - fp_set_debug(3); discovered_devs = fp_discover_devs(); if (!discovered_devs) { From 1f0079a274561ec30dae1a884e70236625c90f9d Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 13:21:40 +0200 Subject: [PATCH 080/141] data: Mark all the fp_dscv_print functions as deprecated As this is pretty much copy/pasted in fprintd, and should instead be implemented by whatever system actually stores the data, rather than in a generic but not quite "fits-all-purpose" way. https://bugs.freedesktop.org/show_bug.cgi?id=106550 --- libfprint/core.c | 8 ++++++++ libfprint/data.c | 20 +++++++++++++++++++- libfprint/fprint.h | 22 +++++++++++----------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index b65cfb6b..56e36385 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -402,6 +402,8 @@ API_EXPORTED int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, * compatible with a discovered device. * * Returns: 1 if the print is compatible with the device, 0 otherwise + * + * Deprecated: Do not use. */ API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev, struct fp_dscv_print *print) @@ -420,6 +422,8 @@ API_EXPORTED int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev, * * Returns: the first discovered device that appears to support the print, or * %NULL if no apparently compatible devices could be found + * + * Deprecated: Do not use. */ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs, struct fp_print_data *print) @@ -443,6 +447,8 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev * * * Returns: the first discovered device that appears to support the print, or * %NULL if no apparently compatible devices could be found + * + * Deprecated: Do not use. */ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs, struct fp_dscv_print *print) @@ -522,6 +528,8 @@ API_EXPORTED int fp_dev_supports_print_data(struct fp_dev *dev, * with a certain device. * * Returns: 1 if the print is compatible with the device, 0 if not + * + * Deprecated: Do not use. */ API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev, struct fp_dscv_print *print) diff --git a/libfprint/data.c b/libfprint/data.c index 2fef5690..62a5fea5 100644 --- a/libfprint/data.c +++ b/libfprint/data.c @@ -506,6 +506,8 @@ API_EXPORTED int fp_print_data_delete(struct fp_dev *dev, * negative) are possible for obscure error conditions (e.g. corruption). * * Returns: 0 on success, non-zero on error. + * + * Deprecated: Do not use. */ API_EXPORTED int fp_print_data_from_dscv_print(struct fp_dscv_print *print, struct fp_print_data **data) @@ -557,7 +559,7 @@ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data) /** * SECTION:dscv_print - * @title: Print discovery + * @title: Print discovery (deprecated) * * The [stored print](libfprint-Stored-prints.html) documentation detailed a simple API * for storing per-device prints for a single user, namely @@ -588,6 +590,10 @@ API_EXPORTED uint32_t fp_print_data_get_devtype(struct fp_print_data *data) * circumstances it may turn out that the print is corrupt or not for the * device that it appeared to be. Also, it is possible that the print may have * been deleted by the time you come to load it. + * + * Note that this portion of the library is deprecated. All that it offers is + * already implementable using publicly available functions, and its usage is + * unnecessarily restrictive in terms of how it stores data. */ static GSList *scan_dev_store_dir(char *devpath, uint16_t driver_id, @@ -679,6 +685,8 @@ static GSList *scan_driver_store_dir(char *drvpath, uint16_t driver_id, * * Returns: a %NULL-terminated list of discovered prints, must be freed with * fp_dscv_prints_free() after use. + * + * Deprecated: Do not use. */ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void) { @@ -743,6 +751,8 @@ API_EXPORTED struct fp_dscv_print **fp_discover_prints(void) * Frees a list of discovered prints. This function also frees the discovered * prints themselves, so make sure you do not use any discovered prints * after calling this function. + * + * Deprecated: Do not use. */ API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints) { @@ -769,6 +779,8 @@ API_EXPORTED void fp_dscv_prints_free(struct fp_dscv_print **prints) * usable with a device controlled by that driver. * * Returns: the driver ID of the driver compatible with the print + * + * Deprecated: Do not use. */ API_EXPORTED uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print) { @@ -784,6 +796,8 @@ API_EXPORTED uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print) * with the print. * * Returns: the devtype of the device range compatible with the print + * + * Deprecated: Do not use. */ API_EXPORTED uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print) { @@ -797,6 +811,8 @@ API_EXPORTED uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print) * Gets the finger code for a discovered print. * * Returns: a finger code from #fp_finger + * + * Deprecated: Do not use. */ API_EXPORTED enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print) { @@ -813,6 +829,8 @@ API_EXPORTED enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print * fail for obvious reasons. * * Returns: 0 on success, negative on error + * + * Deprecated: Do not use. */ API_EXPORTED int fp_dscv_print_delete(struct fp_dscv_print *print) { diff --git a/libfprint/fprint.h b/libfprint/fprint.h index d5bb3e53..c927690b 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -138,19 +138,19 @@ uint32_t fp_dscv_dev_get_devtype(struct fp_dscv_dev *dev); int fp_dscv_dev_supports_print_data(struct fp_dscv_dev *dev, struct fp_print_data *print); int fp_dscv_dev_supports_dscv_print(struct fp_dscv_dev *dev, - struct fp_dscv_print *print); + struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; struct fp_dscv_dev *fp_dscv_dev_for_print_data(struct fp_dscv_dev **devs, - struct fp_print_data *print); + struct fp_print_data *print) LIBFPRINT_DEPRECATED; struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev **devs, - struct fp_dscv_print *print); + struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; /* Print discovery */ -struct fp_dscv_print **fp_discover_prints(void); -void fp_dscv_prints_free(struct fp_dscv_print **prints); -uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print); -uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print); -enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print); -int fp_dscv_print_delete(struct fp_dscv_print *print); +struct fp_dscv_print **fp_discover_prints(void) LIBFPRINT_DEPRECATED; +void fp_dscv_prints_free(struct fp_dscv_print **prints) LIBFPRINT_DEPRECATED; +uint16_t fp_dscv_print_get_driver_id(struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; +uint32_t fp_dscv_print_get_devtype(struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; +enum fp_finger fp_dscv_print_get_finger(struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; +int fp_dscv_print_delete(struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; /* Device handling */ struct fp_dev *fp_dev_open(struct fp_dscv_dev *ddev); @@ -159,7 +159,7 @@ struct fp_driver *fp_dev_get_driver(struct fp_dev *dev); int fp_dev_get_nr_enroll_stages(struct fp_dev *dev); uint32_t fp_dev_get_devtype(struct fp_dev *dev); int fp_dev_supports_print_data(struct fp_dev *dev, struct fp_print_data *data); -int fp_dev_supports_dscv_print(struct fp_dev *dev, struct fp_dscv_print *print); +int fp_dev_supports_dscv_print(struct fp_dev *dev, struct fp_dscv_print *print) LIBFPRINT_DEPRECATED; /** * fp_capture_result: @@ -268,7 +268,7 @@ int fp_identify_finger(struct fp_dev *dev, int fp_print_data_load(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data); int fp_print_data_from_dscv_print(struct fp_dscv_print *print, - struct fp_print_data **data); + 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); void fp_print_data_free(struct fp_print_data *data); From 53c09405b25f04768ad5bcd306cb4ddb1f504490 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 16:57:14 +0200 Subject: [PATCH 081/141] etes603: Use GLib's g_assert() Instead of requiring assert.h to be included. --- libfprint/drivers/etes603.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 60f81b23..2bf5cdd1 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -301,7 +301,7 @@ static void msg_get_regs(struct etes603_dev *dev, int n_args, ... ) va_list ap; int i; - assert(n_args > 0 && n_args <= REG_MAX); + g_assert(n_args > 0 && n_args <= REG_MAX); msg_header_prepare(msg); msg->cmd = CMD_READ_REG; @@ -350,7 +350,7 @@ static void msg_set_regs(struct etes603_dev *dev, int n_args, ...) va_list ap; int i; - assert(n_args != 0 && n_args % 2 == 0 && n_args <= REG_MAX * 2); + g_assert(n_args != 0 && n_args % 2 == 0 && n_args <= REG_MAX * 2); msg_header_prepare(msg); msg->cmd = CMD_WRITE_REG; @@ -1005,7 +1005,7 @@ static void m_tunevrb_state(struct fpi_ssm *ssm) switch (ssm->cur_state) { case TUNEVRB_INIT: fp_dbg("Tuning of VRT/VRB"); - assert(dev->dcoffset); + g_assert(dev->dcoffset); /* VRT(reg E1)=0x0A and VRB(reg E2)=0x10 are starting values */ dev->vrt = 0x0A; dev->vrb = 0x10; @@ -1412,7 +1412,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) struct etes603_dev *dev = idev->priv; struct fpi_ssm *ssm; - assert(dev); + g_assert(dev); if (state != IMGDEV_STATE_AWAIT_FINGER_ON) { fp_err("The driver is in an unexpected state: %d.", state); From 501020921e3992877070f4624f4dfed3158ece6a Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 17:00:17 +0200 Subject: [PATCH 082/141] vfs301_proto: Use GLib helpers No need to roll out own min() implementation, or use the bare assert(). --- libfprint/drivers/vfs301_proto.c | 45 +++++++++++++++----------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/libfprint/drivers/vfs301_proto.c b/libfprint/drivers/vfs301_proto.c index 238752c5..f96f411a 100644 --- a/libfprint/drivers/vfs301_proto.c +++ b/libfprint/drivers/vfs301_proto.c @@ -28,18 +28,15 @@ * - describe some interesting structures better */ #include -#include #include #include -#include +#include #include +#include #include #include "vfs301_proto.h" #include "vfs301_proto_fragments.h" -#include - -#define min(a, b) (((a) < (b)) ? (a) : (b)) /************************** USB STUFF *****************************************/ @@ -51,7 +48,7 @@ static void usb_print_packet(int dir, int rv, const unsigned char *data, int len #ifdef PRINT_VERBOSE int i; - for (i = 0; i < min(length, 128); i++) { + for (i = 0; i < MIN(length, 128); i++) { fprintf(stderr, "%.2X ", data[i]); if (i % 8 == 7) fprintf(stderr, " "); @@ -68,7 +65,7 @@ static int usb_recv( vfs301_dev_t *dev, struct libusb_device_handle *devh, unsigned char endpoint, int max_bytes) { - assert(max_bytes <= sizeof(dev->recv_buf)); + g_assert(max_bytes <= sizeof(dev->recv_buf)); int r = libusb_bulk_transfer( devh, endpoint, @@ -99,7 +96,7 @@ static int usb_send( usb_print_packet(1, r, data, length); #endif - assert(r == 0); + g_assert(r == 0); if (r < 0) return r; @@ -131,7 +128,7 @@ static void vfs301_proto_generate_0B(int subtype, unsigned char *data, int *len) len++; break; default: - assert(!"unsupported"); + g_assert_not_reached(); break; } } @@ -147,8 +144,8 @@ static void translate_str(const char **srcL, unsigned char *data, int *len) while (*srcL != NULL) { src = *srcL; while (*src != '\0') { - assert(*src != '\0'); - assert(*(src +1) != '\0'); + g_assert(*src != '\0'); + g_assert(*(src +1) != '\0'); *data = (unsigned char)((HEX_TO_INT(*src) << 4) | (HEX_TO_INT(*(src + 1)))); data++; @@ -193,7 +190,7 @@ static void vfs301_proto_generate(int type, int subtype, unsigned char *data, in vfs301_02D0_06, vfs301_02D0_07, }; - assert((int)subtype <= (int)(sizeof(dataLs) / sizeof(dataLs[0]))); + g_assert((int)subtype <= (int)(sizeof(dataLs) / sizeof(dataLs[0]))); translate_str(dataLs[subtype - 1], data, len); } break; @@ -214,10 +211,10 @@ static void vfs301_proto_generate(int type, int subtype, unsigned char *data, in translate_str(vfs301_next_scan_template, data, len); unsigned char *field = data + *len - (sizeof(S4_TAIL) - 1) / 2 - 4; - assert(*field == 0xDE); - assert(*(field + 1) == 0xAD); - assert(*(field + 2) == 0xDE); - assert(*(field + 3) == 0xAD); + g_assert(*field == 0xDE); + g_assert(*(field + 1) == 0xAD); + g_assert(*(field + 2) == 0xDE); + g_assert(*(field + 3) == 0xAD); *field = (unsigned char)((subtype >> 8) & 0xFF); *(field + 1) = (unsigned char)(subtype & 0xFF); @@ -225,15 +222,15 @@ static void vfs301_proto_generate(int type, int subtype, unsigned char *data, in *(field + 3) = *(field + 1); break; default: - assert(0); + g_assert(0); break; } break; case 0x06: - assert(!"Not generated"); + g_assert_not_reached(); break; default: - assert(!"Unknown message type"); + g_assert_not_reached(); break; } } @@ -296,7 +293,7 @@ void vfs301_extract_image( int last_line; int i; - assert(vfs->scanline_count >= 1); + g_assert(vfs->scanline_count >= 1); *output_height = 1; memcpy(output, scanlines, VFS301_FP_OUTPUT_WIDTH); @@ -344,7 +341,7 @@ static int img_process_data( } dev->scanline_buf = realloc(dev->scanline_buf, dev->scanline_count * VFS301_FP_OUTPUT_WIDTH); - assert(dev->scanline_buf != NULL); + g_assert(dev->scanline_buf != NULL); for (cur_line = dev->scanline_buf + last_img_height * VFS301_FP_OUTPUT_WIDTH, i = 0; i < no_lines; @@ -391,7 +388,7 @@ static int vfs301_proto_process_data(int first_block, vfs301_dev_t *dev) int len = dev->recv_len; if (first_block) { - assert(len >= VFS301_FP_FRAME_SIZE); + g_assert(len >= VFS301_FP_FRAME_SIZE); /* Skip bytes until start_sequence is found */ for (i = 0; i < VFS301_FP_FRAME_SIZE; i++, buf++, len--) { @@ -417,14 +414,14 @@ int vfs301_proto_peek_event( const char got_event[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00}; USB_SEND(0x17, -1); - assert(USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 7) == 0); + g_assert(USB_RECV(VFS301_RECEIVE_ENDPOINT_CTRL, 7) == 0); if (memcmp(dev->recv_buf, no_event, sizeof(no_event)) == 0) { return 0; } else if (memcmp(dev->recv_buf, got_event, sizeof(no_event)) == 0) { return 1; } else { - assert(!"unexpected reply to wait"); + g_assert_not_reached(); } } From 994061af44a7c297714fbb84f0a7e1c03d4dbd9e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 24 May 2018 17:02:15 +0200 Subject: [PATCH 083/141] drivers: Simplify headers Remove all the headers already included through "fp_internal.h" such as and , include "assembling.h" and "driver_ids.h" there as well to avoid doing it in (almost) every driver. --- libfprint/drivers/aes1610.c | 11 +---------- libfprint/drivers/aes1660.c | 14 +------------- libfprint/drivers/aes2501.c | 11 +---------- libfprint/drivers/aes2550.c | 11 +---------- libfprint/drivers/aes2660.c | 13 +------------ libfprint/drivers/aes3500.c | 10 +--------- libfprint/drivers/aes3k.c | 9 +-------- libfprint/drivers/aes4000.c | 10 +--------- libfprint/drivers/aesx660.c | 12 +----------- libfprint/drivers/elan.c | 7 ------- libfprint/drivers/etes603.c | 9 --------- libfprint/drivers/fdu2000.c | 8 -------- libfprint/drivers/upeksonly.c | 10 ---------- libfprint/drivers/upektc.c | 6 ------ libfprint/drivers/upektc_img.c | 10 +--------- libfprint/drivers/upekts.c | 8 -------- libfprint/drivers/uru4000.c | 9 +-------- libfprint/drivers/vcom5s.c | 8 -------- libfprint/drivers/vfs0050.c | 6 ------ libfprint/drivers/vfs101.c | 6 ------ libfprint/drivers/vfs301.c | 16 ++-------------- libfprint/drivers/vfs5011.c | 9 +-------- libfprint/fp_internal.h | 5 ++++- 23 files changed, 18 insertions(+), 200 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index b47396b6..9ee193f6 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -26,16 +26,7 @@ #define FP_COMPONENT "aes1610" #include "fp_internal.h" - -#include -#include - -#include - -#include -#include - -#include "driver_ids.h" +#include "aeslib.h" static void start_capture(struct fp_img_dev *dev); static void complete_deactivation(struct fp_img_dev *dev); diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index ad28b06d..a4d0853b 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -20,21 +20,9 @@ #define FP_COMPONENT "aes1660" #include "fp_internal.h" - -#include - -#include -#include - -#include - - -#include -#include - +#include "aeslib.h" #include "aesx660.h" #include "aes1660.h" -#include "driver_ids.h" #define FRAME_WIDTH 128 #define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index c1bbc98d..36a8ab5a 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -24,17 +24,8 @@ #define FP_COMPONENT "aes2501" #include "fp_internal.h" - -#include -#include - -#include - -#include -#include - +#include "aeslib.h" #include "aes2501.h" -#include "driver_ids.h" static void start_capture(struct fp_img_dev *dev); static void complete_deactivation(struct fp_img_dev *dev); diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 0516bbc1..da2134ca 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -24,17 +24,8 @@ #define FP_COMPONENT "aes2550" #include "fp_internal.h" - -#include -#include - -#include - -#include -#include - #include "aes2550.h" -#include "driver_ids.h" +#include "aeslib.h" static void start_capture(struct fp_img_dev *dev); static void complete_deactivation(struct fp_img_dev *dev); diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index bfc457de..1fe9334d 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -20,20 +20,9 @@ #define FP_COMPONENT "aes2660" #include "fp_internal.h" - -#include - -#include -#include - -#include - -#include -#include - +#include "aeslib.h" #include "aesx660.h" #include "aes2660.h" -#include "driver_ids.h" #define FRAME_WIDTH 192 #define IMAGE_WIDTH (FRAME_WIDTH + (FRAME_WIDTH / 2)) diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c index 44286709..ca30b30e 100644 --- a/libfprint/drivers/aes3500.c +++ b/libfprint/drivers/aes3500.c @@ -30,16 +30,8 @@ #define FP_COMPONENT "aes3500" #include "fp_internal.h" - -#include - -#include -#include - -#include - +#include "aeslib.h" #include "aes3k.h" -#include "driver_ids.h" #define DATA_BUFLEN 0x2089 diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c index f50d2b4c..620e8d67 100644 --- a/libfprint/drivers/aes3k.c +++ b/libfprint/drivers/aes3k.c @@ -37,14 +37,7 @@ #define FP_COMPONENT "aes3k" #include "fp_internal.h" - -#include - -#include -#include - -#include - +#include "aeslib.h" #include "aes3k.h" #define CTRL_TIMEOUT 1000 diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index 6118f334..9b6b2771 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -27,16 +27,8 @@ #define FP_COMPONENT "aes4000" #include "fp_internal.h" - -#include - -#include -#include - -#include - +#include "aeslib.h" #include "aes3k.h" -#include "driver_ids.h" #define DATA_BUFLEN 0x1259 diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index ab679462..5a81403f 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -24,17 +24,7 @@ #define FP_COMPONENT "aesX660" #include "fp_internal.h" - -#include - -#include -#include - -#include - -#include -#include - +#include "aeslib.h" #include "aesx660.h" static void start_capture(struct fp_img_dev *dev); diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index e528ecb3..2b31289d 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -21,14 +21,7 @@ #define FP_COMPONENT "elan" #include "fp_internal.h" - -#include -#include -#include -#include - #include "elan.h" -#include "driver_ids.h" unsigned char elan_get_pixel(struct fpi_frame_asmbl_ctx *ctx, struct fpi_frame *frame, unsigned int x, diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 2bf5cdd1..776ad9a7 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -36,15 +36,6 @@ #define FP_COMPONENT "etes603" #include "fp_internal.h" - -#include -#include -#include -#include -#include -#include -#include - #include "driver_ids.h" /* libusb defines */ diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c index b95ff62f..015e4e4f 100644 --- a/libfprint/drivers/fdu2000.c +++ b/libfprint/drivers/fdu2000.c @@ -21,14 +21,6 @@ #include "fp_internal.h" -#include -#include -#include - -#include - -#include "driver_ids.h" - #ifndef HAVE_MEMMEM gpointer memmem(const gpointer haystack, size_t haystack_len, const gpointer needle, size_t needle_len) { diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 4d228d97..6e18e230 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -26,17 +26,7 @@ #define FP_COMPONENT "upeksonly" #include "fp_internal.h" - -#include -#include - -#include -#include - -#include - #include "upeksonly.h" -#include "driver_ids.h" #define CTRL_TIMEOUT 1000 #define NUM_BULK_TRANSFERS 24 diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 107f93db..d8ccf5b4 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -21,13 +21,7 @@ #define FP_COMPONENT "upektc" #include "fp_internal.h" - -#include -#include -#include - #include "upektc.h" -#include "driver_ids.h" #define UPEKTC_EP_IN (2 | LIBUSB_ENDPOINT_IN) #define UPEKTC_EP_OUT (3 | LIBUSB_ENDPOINT_OUT) diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index c193c077..f637156b 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -20,16 +20,8 @@ #define FP_COMPONENT "upektc_img" #include "fp_internal.h" - -#include -#include - -#include - -#include - +#include "aeslib.h" #include "upektc_img.h" -#include "driver_ids.h" static void start_capture(struct fp_img_dev *dev); static void start_deactivation(struct fp_img_dev *dev); diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index d0704042..3078d9da 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -29,14 +29,6 @@ #include "fp_internal.h" -#include -#include - -#include -#include - -#include "driver_ids.h" - #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) #define TIMEOUT 5000 diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 600bb27c..3c002182 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -20,17 +20,10 @@ #define FP_COMPONENT "uru4000" -#include "fp_internal.h" - -#include -#include -#include - #include #include -#include -#include "driver_ids.h" +#include "fp_internal.h" #define EP_INTR (1 | LIBUSB_ENDPOINT_IN) #define EP_DATA (2 | LIBUSB_ENDPOINT_IN) diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index dfbdca77..eda67c94 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -28,14 +28,6 @@ * powerdown? does windows do anything special on exit? */ -#include -#include - -#include -#include - -#include "driver_ids.h" - #define CTRL_IN 0xc0 #define CTRL_OUT 0x40 #define CTRL_TIMEOUT 1000 diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index 45adaa49..003b1b3e 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -20,12 +20,6 @@ #define FP_COMPONENT "vfs0050" #include "fp_internal.h" - -#include -#include -#include -#include "driver_ids.h" - #include "vfs0050.h" /* USB functions */ diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index afc72d9d..98807ee5 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -21,12 +21,6 @@ #include "fp_internal.h" -#include -#include -#include - -#include "driver_ids.h" - /* Input-Output usb endpoint */ #define EP_IN(n) (n | LIBUSB_ENDPOINT_IN) #define EP_OUT(n) (n | LIBUSB_ENDPOINT_OUT) diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 1b8a7db2..1c1b8d4c 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -22,19 +22,7 @@ #define FP_COMPONENT "vfs301" #include "fp_internal.h" - -#include -#include -#include -#include -#include -#include -#include - #include "vfs301_proto.h" -#include - -#include "driver_ids.h" /************************** GENERIC STUFF *************************************/ @@ -152,7 +140,7 @@ static void m_loop_state(struct fpi_ssm *ssm) case M_READ_PRINT_POLL: { int rv = vfs301_proto_process_event_poll(dev->udev, vdev); - assert(rv != VFS301_FAILURE); + g_assert(rv != VFS301_FAILURE); if (rv == VFS301_ONGOING) fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT); else @@ -185,7 +173,7 @@ static void m_init_state(struct fpi_ssm *ssm) struct fp_img_dev *dev = ssm->priv; vfs301_dev_t *vdev = dev->priv; - assert(ssm->cur_state == 0); + g_assert(ssm->cur_state == 0); vfs301_proto_init(dev->udev, vdev); diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index facb32c8..ce19fa3a 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -18,14 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include -#include -#include -#include -#include "driver_ids.h" - +#include "fp_internal.h" #include "vfs5011_proto.h" /* =================== sync/async USB transfer sequence ==================== */ diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 9c36917d..15c7cbd1 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -28,10 +28,13 @@ #endif #include +#include #include #include -#include +#include "fprint.h" +#include "assembling.h" +#include "drivers/driver_ids.h" #define array_n_elements(array) (sizeof(array) / sizeof(array[0])) From f433a4d67cdb4d1b9b997e7f24190a7001a1d950 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 27 Apr 2018 13:47:53 +0200 Subject: [PATCH 084/141] upekts: Fix compilation warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libfprint/drivers/upekts.c: In function ‘alloc_send_cmd_transfer’: libfprint/drivers/upekts.c:161:2: warning: ‘strncpy’ output truncated before terminating nul copying 4 bytes from a string of the same length [-Wstringop-truncation] strncpy(buf, "Ciao", 4); ^~~~~~~~~~~~~~~~~~~~~~~ Replace with memcpy() to only copy the 4 bytes we need. https://bugs.freedesktop.org/show_bug.cgi?id=106281 --- libfprint/drivers/upekts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index 3078d9da..6f74d750 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -133,6 +133,7 @@ static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev, { struct libusb_transfer *transfer = libusb_alloc_transfer(0); uint16_t crc; + const char *ciao = "Ciao"; /* 9 bytes extra for: 4 byte 'Ciao', 1 byte A, 1 byte B | lenHI, * 1 byte lenLO, 2 byte CRC */ @@ -150,7 +151,7 @@ static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev, buf = g_malloc(urblen); /* Write header */ - strncpy(buf, "Ciao", 4); + memcpy(buf, ciao, strlen(ciao)); len = GUINT16_TO_LE(len); buf[4] = seq_a; buf[5] = seq_b | ((len & 0xf00) >> 8); From ff5de4ff0303469ecf52556ea788ca00446cec36 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 26 Apr 2018 17:07:05 +0200 Subject: [PATCH 085/141] lib: Replace open-coded array_n_elements() Replace it with glib's version, which already exists. https://bugs.freedesktop.org/show_bug.cgi?id=106280 --- libfprint/fp_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 15c7cbd1..6d8849b8 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -36,7 +36,7 @@ #include "assembling.h" #include "drivers/driver_ids.h" -#define array_n_elements(array) (sizeof(array) / sizeof(array[0])) +#define array_n_elements(array) G_N_ELEMENTS(array) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ From bc30a3d2e5644e9e22a84f91451c87dd4f785395 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 11 Mar 2018 22:37:55 +0100 Subject: [PATCH 086/141] aes2501: Fix state machine never using "init_3" state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes this warning by the same token: drivers/aes2501.c:671:34: warning: ‘init_3’ defined but not used [-Wunused-const-variable=] https://bugs.freedesktop.org/show_bug.cgi?id=105429 --- libfprint/drivers/aes2501.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 36a8ab5a..27429b93 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -776,7 +776,7 @@ static void activate_run_state(struct fpi_ssm *ssm) read_regs(dev, activate_read_regs_cb, ssm); break; case WRITE_INIT_3: - aes_write_regv(dev, init_4, G_N_ELEMENTS(init_4), + aes_write_regv(dev, init_3, G_N_ELEMENTS(init_3), activate_init3_cb, ssm); break; case WRITE_INIT_4: From 391f77ce5e2bfdf5e252e560cab1446a7300e61b Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Sun, 11 Mar 2018 13:40:39 -0700 Subject: [PATCH 087/141] aes1610: Fix compilation warning in aes1610 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: drivers/aes1610.c:736:34: warning: ‘stop_reader’ defined but not used [-Wunused-const-variable=] https://bugs.freedesktop.org/show_bug.cgi?id=105429 --- libfprint/drivers/aes1610.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 9ee193f6..bf17c715 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -725,10 +725,11 @@ static const struct aes_regwrite init[] = { { 0x82, 0x00 } }; +/* static const struct aes_regwrite stop_reader[] = { { 0xFF, 0x00 } }; - +*/ enum activate_states { WRITE_INIT, From 55b83062d040bd9e52ba9a2f11d363601072f7b5 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 25 May 2018 13:30:35 +0200 Subject: [PATCH 088/141] img: Fix fd leaks Spotted by maddin200@aol.com https://bugs.freedesktop.org/show_bug.cgi?id=90197 --- libfprint/img.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfprint/img.c b/libfprint/img.c index 10511f8c..d0ca6fb9 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -166,12 +166,14 @@ API_EXPORTED int fp_img_save_to_file(struct fp_img *img, char *path) r = fprintf(fd, "P5 %d %d 255\n", img->width, img->height); if (r < 0) { + fclose(fd); fp_err("pgm header write failed, error %d", r); return r; } r = fwrite(img->data, 1, write_size, fd); if (r < write_size) { + fclose(fd); fp_err("short write (%d)", r); return -EIO; } From 1ac815e4575739d518b130df23fd332e51950c49 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 25 May 2018 13:40:33 +0200 Subject: [PATCH 089/141] examples: Fix integer overflow warnings --- examples/img_capture_continuous.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/img_capture_continuous.c b/examples/img_capture_continuous.c index 7dcb5222..f5b5f028 100644 --- a/examples/img_capture_continuous.c +++ b/examples/img_capture_continuous.c @@ -53,7 +53,7 @@ static int connection = -1; static void grey2yuy2 (unsigned char *grey, char *YUV, int num) { int i, j; int y0, y1, u0, u1, v0, v1; - int gval; + uint64_t gval; for (i = 0, j = 0; i < num; i += 2, j += 4) { From bc3959d1e0fbe0361dfd45a5b4ed6db7e32e7147 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 25 May 2018 13:45:13 +0200 Subject: [PATCH 090/141] lib: Fix internal deprecation warning Remove deprecation warning that comes from an internal function, it serves no purpose, and the function itself is deprecated. Follow-up from commit 1f0079a274561ec30dae1a884e70236625c90f9d. --- libfprint/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libfprint/core.c b/libfprint/core.c index 56e36385..280fe65a 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -456,9 +456,13 @@ API_EXPORTED struct fp_dscv_dev *fp_dscv_dev_for_dscv_print(struct fp_dscv_dev * struct fp_dscv_dev *ddev; int i; - for (i = 0; (ddev = devs[i]); i++) + for (i = 0; (ddev = devs[i]); i++) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" if (fp_dscv_dev_supports_dscv_print(ddev, print)) return ddev; +#pragma GCC diagnostic pop + } return NULL; } From 2481cbe4ab1ca7885ace41850cc909d13211b0ac Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 25 May 2018 15:58:10 +0200 Subject: [PATCH 091/141] poll: Add some details about how mainloop integration works --- libfprint/poll.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libfprint/poll.c b/libfprint/poll.c index c8201036..8a007bc9 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -55,8 +55,12 @@ * fp_handle_events_timeout() instead. If you wish to do a non-blocking * iteration, call fp_handle_events_timeout() with a zero timeout. * - * FIXME: document how application is supposed to know when to call these - * functions. + * How to integrate events handling depends on your main loop implementation. + * The sister fprintd project includes an implementation of main loop handling + * that integrates into GLib's main loop. The + * [libusb documentation](http://libusb.sourceforge.net/api-1.0/group__poll.html#details) + * also includes more details about how to integrate libfprint events into + * your main loop. */ /* this is a singly-linked list of pending timers, sorted with the timer that From 9cca50165053084a151d7e69a7e82db98d46ed24 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 25 May 2018 16:11:37 +0200 Subject: [PATCH 092/141] lib: Fix new BUG_ON() implementation A thinko reversed the meaning of the BUG_ON() condition. This fixes the inverted implementation in commit ff09456cf5adaead2d3993a7e1476e56a23ff7bb. --- libfprint/fp_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 6d8849b8..446c7d1d 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -47,7 +47,7 @@ #define fp_warn g_warning #define fp_err g_error -#define BUG_ON(condition) g_assert(condition) +#define BUG_ON(condition) g_assert(!condition) #define BUG() g_assert_not_reached() enum fp_dev_state { From 0e351db91ab67130631f109f07f1ce7346f70ad7 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 25 May 2018 17:00:40 +0200 Subject: [PATCH 093/141] lib: Fix new BUG_ON() implementation again This time, the macro didn't wrap the condition, resulting in calls like BUG_ON(size > 100) being expanded to g_assert(!size > 100), when what we wanted was BUG_ON(!(size > 100)). See 9cca50165053084a151d7e69a7e82db98d46ed24, ff09456cf5adaead2d3993a7e1476e56a23ff7bb, and egg on my face. --- libfprint/fp_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 446c7d1d..3992dd1a 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -47,7 +47,7 @@ #define fp_warn g_warning #define fp_err g_error -#define BUG_ON(condition) g_assert(!condition) +#define BUG_ON(condition) g_assert(!(condition)) #define BUG() g_assert_not_reached() enum fp_dev_state { From 1b20521e5c93642d4c2b269548d517c8adb80387 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 11:51:38 +0200 Subject: [PATCH 094/141] lib: Add drivers_api.h file This will hide library internals, for the purpose of making the drivers API documentable. --- libfprint/drivers_api.h | 430 ++++++++++++++++++++++++++++++++++++++++ libfprint/meson.build | 1 + 2 files changed, 431 insertions(+) create mode 100644 libfprint/drivers_api.h diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h new file mode 100644 index 00000000..89799b19 --- /dev/null +++ b/libfprint/drivers_api.h @@ -0,0 +1,430 @@ +/* + * Driver API definitions + * Copyright (C) 2007-2008 Daniel Drake + * Copyright (C) 2018 Bastien Nocera + * + * 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 __DRIVERS_API_H__ +#define __DRIVERS_API_H__ + +#include + +#ifdef FP_COMPONENT +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "libfprint-"FP_COMPONENT +#endif + +#include +#include +#include +#include + +#include "fprint.h" +#include "assembling.h" +#include "drivers/driver_ids.h" + +#define array_n_elements(array) G_N_ELEMENTS(array) + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +#define fp_dbg g_debug +#define fp_info g_debug +#define fp_warn g_warning +#define fp_err g_error + +#define BUG_ON(condition) g_assert(!(condition)) +#define BUG() g_assert_not_reached() + +enum fp_dev_state { + DEV_STATE_INITIAL = 0, + DEV_STATE_ERROR, + DEV_STATE_INITIALIZING, + DEV_STATE_INITIALIZED, + DEV_STATE_DEINITIALIZING, + DEV_STATE_DEINITIALIZED, + DEV_STATE_ENROLL_STARTING, + DEV_STATE_ENROLLING, + DEV_STATE_ENROLL_STOPPING, + DEV_STATE_VERIFY_STARTING, + DEV_STATE_VERIFYING, + DEV_STATE_VERIFY_DONE, + DEV_STATE_VERIFY_STOPPING, + DEV_STATE_IDENTIFY_STARTING, + DEV_STATE_IDENTIFYING, + DEV_STATE_IDENTIFY_DONE, + DEV_STATE_IDENTIFY_STOPPING, + DEV_STATE_CAPTURE_STARTING, + DEV_STATE_CAPTURING, + DEV_STATE_CAPTURE_DONE, + DEV_STATE_CAPTURE_STOPPING, +}; + +struct fp_driver **fprint_get_drivers (void); + +struct fp_dev { + struct fp_driver *drv; + libusb_device_handle *udev; + uint32_t devtype; + void *priv; + + int nr_enroll_stages; + + /* read-only to drivers */ + struct fp_print_data *verify_data; + + /* drivers should not mess with any of the below */ + enum fp_dev_state state; + int __enroll_stage; + int unconditional_capture; + + /* async I/O callbacks and data */ + /* FIXME: convert this to generic state operational data mechanism? */ + fp_dev_open_cb open_cb; + void *open_cb_data; + fp_operation_stop_cb close_cb; + void *close_cb_data; + fp_enroll_stage_cb enroll_stage_cb; + void *enroll_stage_cb_data; + fp_operation_stop_cb enroll_stop_cb; + void *enroll_stop_cb_data; + fp_img_operation_cb verify_cb; + void *verify_cb_data; + fp_operation_stop_cb verify_stop_cb; + void *verify_stop_cb_data; + fp_identify_cb identify_cb; + void *identify_cb_data; + fp_operation_stop_cb identify_stop_cb; + void *identify_stop_cb_data; + fp_img_operation_cb capture_cb; + void *capture_cb_data; + fp_operation_stop_cb capture_stop_cb; + void *capture_stop_cb_data; + + /* FIXME: better place to put this? */ + struct fp_print_data **identify_gallery; +}; + +enum fp_imgdev_state { + IMGDEV_STATE_INACTIVE, + IMGDEV_STATE_AWAIT_FINGER_ON, + IMGDEV_STATE_CAPTURE, + IMGDEV_STATE_AWAIT_FINGER_OFF, +}; + +enum fp_imgdev_action { + IMG_ACTION_NONE = 0, + IMG_ACTION_ENROLL, + IMG_ACTION_VERIFY, + IMG_ACTION_IDENTIFY, + IMG_ACTION_CAPTURE, +}; + +enum fp_imgdev_enroll_state { + IMG_ACQUIRE_STATE_NONE = 0, + IMG_ACQUIRE_STATE_ACTIVATING, + IMG_ACQUIRE_STATE_AWAIT_FINGER_ON, + IMG_ACQUIRE_STATE_AWAIT_IMAGE, + IMG_ACQUIRE_STATE_AWAIT_FINGER_OFF, + IMG_ACQUIRE_STATE_DONE, + IMG_ACQUIRE_STATE_DEACTIVATING, +}; + +enum fp_imgdev_verify_state { + IMG_VERIFY_STATE_NONE = 0, + IMG_VERIFY_STATE_ACTIVATING +}; + +struct fp_img_dev { + struct fp_dev *dev; + libusb_device_handle *udev; + enum fp_imgdev_action action; + int action_state; + + struct fp_print_data *acquire_data; + struct fp_print_data *enroll_data; + struct fp_img *acquire_img; + int enroll_stage; + int action_result; + + /* FIXME: better place to put this? */ + size_t identify_match_offset; + + void *priv; +}; + +int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev); +int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev); + +struct usb_id { + uint16_t vendor; + uint16_t product; + unsigned long driver_data; +}; + +enum fp_driver_type { + DRIVER_PRIMITIVE = 0, + DRIVER_IMAGING = 1, +}; + +struct fp_driver { + const uint16_t id; + const char *name; + const char *full_name; + const struct usb_id * const id_table; + enum fp_driver_type type; + enum fp_scan_type scan_type; + + void *priv; + + /* Device operations */ + int (*discover)(struct libusb_device_descriptor *dsc, uint32_t *devtype); + int (*open)(struct fp_dev *dev, unsigned long driver_data); + void (*close)(struct fp_dev *dev); + int (*enroll_start)(struct fp_dev *dev); + int (*enroll_stop)(struct fp_dev *dev); + int (*verify_start)(struct fp_dev *dev); + int (*verify_stop)(struct fp_dev *dev, gboolean iterating); + int (*identify_start)(struct fp_dev *dev); + int (*identify_stop)(struct fp_dev *dev, gboolean iterating); + int (*capture_start)(struct fp_dev *dev); + int (*capture_stop)(struct fp_dev *dev); +}; + +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) + +struct fp_img_driver { + struct fp_driver driver; + uint16_t flags; + int img_width; + int img_height; + int bz3_threshold; + + /* 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 (*change_state)(struct fp_img_dev *dev, enum fp_imgdev_state state); + void (*deactivate)(struct fp_img_dev *dev); +}; + +#include "drivers_definitions.h" + +extern libusb_context *fpi_usb_ctx; +extern GSList *opened_devices; + +void fpi_img_driver_setup(struct fp_img_driver *idriver); + +#define fpi_driver_to_img_driver(drv) \ + container_of((drv), struct fp_img_driver, driver) + +struct fp_dscv_dev { + struct libusb_device *udev; + struct fp_driver *drv; + unsigned long driver_data; + uint32_t devtype; +}; + +struct fp_dscv_print { + uint16_t driver_id; + uint32_t devtype; + enum fp_finger finger; + char *path; +}; + +enum fp_print_data_type { + PRINT_DATA_RAW = 0, /* memset-imposed default */ + PRINT_DATA_NBIS_MINUTIAE, +}; + +struct fp_print_data_item { + size_t length; + unsigned char data[0]; +}; + +struct fp_print_data { + uint16_t driver_id; + uint32_t devtype; + enum fp_print_data_type type; + GSList *prints; +}; + +struct fpi_print_data_fp2 { + char prefix[3]; + uint16_t driver_id; + uint32_t devtype; + unsigned char data_type; + unsigned char data[0]; +} __attribute__((__packed__)); + +struct fpi_print_data_item_fp2 { + uint32_t length; + unsigned char data[0]; +} __attribute__((__packed__)); + +void fpi_data_exit(void); +struct fp_print_data *fpi_print_data_new(struct fp_dev *dev); +struct fp_print_data_item *fpi_print_data_item_new(size_t length); +gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1, + enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2, + enum fp_print_data_type type2); + +struct fp_minutia { + int x; + int y; + int ex; + int ey; + int direction; + double reliability; + int type; + int appearing; + int feature_id; + int *nbrs; + int *ridge_counts; + int num_nbrs; +}; + +struct fp_minutiae { + int alloc; + int num; + struct fp_minutia **list; +}; + +/* bit values for fp_img.flags */ +#define FP_IMG_V_FLIPPED (1<<0) +#define FP_IMG_H_FLIPPED (1<<1) +#define FP_IMG_COLORS_INVERTED (1<<2) +#define FP_IMG_BINARIZED_FORM (1<<3) +#define FP_IMG_PARTIAL (1<<4) + +#define FP_IMG_STANDARDIZATION_FLAGS (FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED \ + | FP_IMG_COLORS_INVERTED) + +struct fp_img { + int width; + int height; + size_t length; + uint16_t flags; + struct fp_minutiae *minutiae; + unsigned char *binarized; + unsigned char data[0]; +}; + +struct fp_img *fpi_img_new(size_t length); +struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *dev); +struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize); +gboolean fpi_img_is_sane(struct fp_img *img); +int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, + struct fp_print_data **ret); +int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, + struct fp_print_data *new_print); +int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, + struct fp_print_data **gallery, int match_threshold, size_t *match_offset); +struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor); + +/* polling and timeouts */ + +void fpi_poll_init(void); +void fpi_poll_exit(void); + +typedef void (*fpi_timeout_fn)(void *data); + +struct fpi_timeout; +struct fpi_timeout *fpi_timeout_add(unsigned int msec, fpi_timeout_fn callback, + void *data); +void fpi_timeout_cancel(struct fpi_timeout *timeout); + +/* async drv <--> lib comms */ + +struct fpi_ssm; +typedef void (*ssm_completed_fn)(struct fpi_ssm *ssm); +typedef void (*ssm_handler_fn)(struct fpi_ssm *ssm); + +/* sequential state machine: state machine that iterates sequentially over + * a predefined series of states. can be aborted by either completion or + * abortion error conditions. */ +struct fpi_ssm { + struct fp_dev *dev; + struct fpi_ssm *parentsm; + void *priv; + int nr_states; + int cur_state; + gboolean completed; + int error; + ssm_completed_fn callback; + ssm_handler_fn handler; +}; + + +/* for library and drivers */ +struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, + int nr_states); +void fpi_ssm_free(struct fpi_ssm *machine); +void fpi_ssm_start(struct fpi_ssm *machine, ssm_completed_fn callback); +void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child); +int fpi_ssm_has_completed(struct fpi_ssm *machine); + +/* for drivers */ +void fpi_ssm_next_state(struct fpi_ssm *machine); +void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state); +void fpi_ssm_mark_completed(struct fpi_ssm *machine); +void fpi_ssm_mark_aborted(struct fpi_ssm *machine, int error); + +void fpi_drvcb_open_complete(struct fp_dev *dev, int status); +void fpi_drvcb_close_complete(struct fp_dev *dev); + +void fpi_drvcb_enroll_started(struct fp_dev *dev, int status); +void fpi_drvcb_enroll_stage_completed(struct fp_dev *dev, int result, + struct fp_print_data *data, struct fp_img *img); +void fpi_drvcb_enroll_stopped(struct fp_dev *dev); + +void fpi_drvcb_verify_started(struct fp_dev *dev, int status); +void fpi_drvcb_report_verify_result(struct fp_dev *dev, int result, + struct fp_img *img); +void fpi_drvcb_verify_stopped(struct fp_dev *dev); + +void fpi_drvcb_identify_started(struct fp_dev *dev, int status); +void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result, + size_t match_offset, struct fp_img *img); +void fpi_drvcb_identify_stopped(struct fp_dev *dev); + +void fpi_drvcb_capture_started(struct fp_dev *dev, int status); +void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result, + struct fp_img *img); +void fpi_drvcb_capture_stopped(struct fp_dev *dev); + +/* for image drivers */ +void fpi_imgdev_open_complete(struct fp_img_dev *imgdev, int status); +void fpi_imgdev_close_complete(struct fp_img_dev *imgdev); +void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status); +void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev); +void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, + gboolean present); +void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img); +void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result); +void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error); + +/* utils */ +int fpi_std_sq_dev(const unsigned char *buf, int size); +int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size); + +#endif + diff --git a/libfprint/meson.build b/libfprint/meson.build index ffea1e24..f8ea5ff5 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -1,5 +1,6 @@ libfprint_sources = [ 'fp_internal.h', + 'drivers_api.h', 'async.c', 'core.c', 'data.c', From 0930f2614c27572868de7bcd8b1f05109338cc00 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 11:53:30 +0200 Subject: [PATCH 095/141] lib: Use public header in helper files aeslib.h and assembling.h don't need access to internal data structures, so make them include the public fprint.h rather than the internal header fp_internal.h. --- libfprint/aeslib.h | 2 +- libfprint/assembling.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/aeslib.h b/libfprint/aeslib.h index 2dd6cea0..41cbe1ee 100644 --- a/libfprint/aeslib.h +++ b/libfprint/aeslib.h @@ -20,7 +20,7 @@ #ifndef __AESLIB_H__ #define __AESLIB_H__ -#include +#include struct aes_regwrite { unsigned char reg; diff --git a/libfprint/assembling.h b/libfprint/assembling.h index 3bcab2f7..5c1c9988 100644 --- a/libfprint/assembling.h +++ b/libfprint/assembling.h @@ -22,7 +22,7 @@ #ifndef __ASSEMBLING_H__ #define __ASSEMBLING_H__ -#include +#include struct fpi_frame { int delta_x; From 19dfb138a6ffc5da9d0a72bf08ec0c6cd57c54a9 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:07:45 +0200 Subject: [PATCH 096/141] drivers: Use new drivers_api.h in drivers --- libfprint/drivers/aes1610.c | 2 +- libfprint/drivers/aes1660.c | 2 +- libfprint/drivers/aes2501.c | 2 +- libfprint/drivers/aes2550.c | 2 +- libfprint/drivers/aes2660.c | 2 +- libfprint/drivers/aes3500.c | 2 +- libfprint/drivers/aes3k.c | 2 +- libfprint/drivers/aes4000.c | 2 +- libfprint/drivers/aesx660.c | 2 +- libfprint/drivers/elan.c | 2 +- libfprint/drivers/etes603.c | 2 +- libfprint/drivers/fdu2000.c | 2 +- libfprint/drivers/upeksonly.c | 2 +- libfprint/drivers/upektc.c | 2 +- libfprint/drivers/upektc_img.c | 2 +- libfprint/drivers/upekts.c | 2 +- libfprint/drivers/uru4000.c | 2 +- libfprint/drivers/vcom5s.c | 2 +- libfprint/drivers/vfs0050.c | 2 +- libfprint/drivers/vfs101.c | 2 +- libfprint/drivers/vfs301.c | 2 +- libfprint/drivers/vfs5011.c | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index bf17c715..0a521945 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -25,7 +25,7 @@ #define FP_COMPONENT "aes1610" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" static void start_capture(struct fp_img_dev *dev); diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index a4d0853b..e2aeeff1 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "aes1660" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aesx660.h" #include "aes1660.h" diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 27429b93..ab5eaa53 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -23,7 +23,7 @@ #define FP_COMPONENT "aes2501" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aes2501.h" diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index da2134ca..0e97f01d 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -23,7 +23,7 @@ #define FP_COMPONENT "aes2550" -#include "fp_internal.h" +#include "drivers_api.h" #include "aes2550.h" #include "aeslib.h" diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index 1fe9334d..7979d7a9 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "aes2660" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aesx660.h" #include "aes2660.h" diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c index ca30b30e..8a16ebf2 100644 --- a/libfprint/drivers/aes3500.c +++ b/libfprint/drivers/aes3500.c @@ -29,7 +29,7 @@ #define FP_COMPONENT "aes3500" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aes3k.h" diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c index 620e8d67..8f384fea 100644 --- a/libfprint/drivers/aes3k.c +++ b/libfprint/drivers/aes3k.c @@ -36,7 +36,7 @@ #define FP_COMPONENT "aes3k" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aes3k.h" diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index 9b6b2771..3a8beba1 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -26,7 +26,7 @@ #define FP_COMPONENT "aes4000" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aes3k.h" diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 5a81403f..0e26fb82 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -23,7 +23,7 @@ #define FP_COMPONENT "aesX660" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "aesx660.h" diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index 2b31289d..90df7e68 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -20,7 +20,7 @@ #define FP_COMPONENT "elan" -#include "fp_internal.h" +#include "drivers_api.h" #include "elan.h" unsigned char elan_get_pixel(struct fpi_frame_asmbl_ctx *ctx, diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 776ad9a7..22da109b 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -35,7 +35,7 @@ #define FP_COMPONENT "etes603" -#include "fp_internal.h" +#include "drivers_api.h" #include "driver_ids.h" /* libusb defines */ diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c index 015e4e4f..867cfed9 100644 --- a/libfprint/drivers/fdu2000.c +++ b/libfprint/drivers/fdu2000.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "fdu2000" -#include "fp_internal.h" +#include "drivers_api.h" #ifndef HAVE_MEMMEM gpointer diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 6e18e230..209f788f 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -25,7 +25,7 @@ #define FP_COMPONENT "upeksonly" -#include "fp_internal.h" +#include "drivers_api.h" #include "upeksonly.h" #define CTRL_TIMEOUT 1000 diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index d8ccf5b4..0d78fa61 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -20,7 +20,7 @@ #define FP_COMPONENT "upektc" -#include "fp_internal.h" +#include "drivers_api.h" #include "upektc.h" #define UPEKTC_EP_IN (2 | LIBUSB_ENDPOINT_IN) diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index f637156b..1ddb159c 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "upektc_img" -#include "fp_internal.h" +#include "drivers_api.h" #include "aeslib.h" #include "upektc_img.h" diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index 6f74d750..9dbfe12f 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -27,7 +27,7 @@ #define FP_COMPONENT "upekts" -#include "fp_internal.h" +#include "drivers_api.h" #define EP_IN (1 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 3c002182..dfa945db 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -23,7 +23,7 @@ #include #include -#include "fp_internal.h" +#include "drivers_api.h" #define EP_INTR (1 | LIBUSB_ENDPOINT_IN) #define EP_DATA (2 | LIBUSB_ENDPOINT_IN) diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index eda67c94..02e57e35 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "vcom5s" -#include "fp_internal.h" +#include "drivers_api.h" /* TODO: * calibration? diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index 003b1b3e..e6d3915e 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "vfs0050" -#include "fp_internal.h" +#include "drivers_api.h" #include "vfs0050.h" /* USB functions */ diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 98807ee5..7c39a649 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -19,7 +19,7 @@ #define FP_COMPONENT "vfs101" -#include "fp_internal.h" +#include "drivers_api.h" /* Input-Output usb endpoint */ #define EP_IN(n) (n | LIBUSB_ENDPOINT_IN) diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 1c1b8d4c..6be8a6ff 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -21,7 +21,7 @@ #define FP_COMPONENT "vfs301" -#include "fp_internal.h" +#include "drivers_api.h" #include "vfs301_proto.h" /************************** GENERIC STUFF *************************************/ diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index ce19fa3a..be66137b 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "fp_internal.h" +#include "drivers_api.h" #include "vfs5011_proto.h" /* =================== sync/async USB transfer sequence ==================== */ From 7e5661caffe804637d0bee0cc349676429529be6 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:14:04 +0200 Subject: [PATCH 097/141] lib: Don't include assembling.h in internal header It's not needed. --- libfprint/fp_internal.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 3992dd1a..51674097 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -33,7 +33,6 @@ #include #include "fprint.h" -#include "assembling.h" #include "drivers/driver_ids.h" #define array_n_elements(array) G_N_ELEMENTS(array) From 933fab6ed4ebc4c3f2b5680fc05c2e0cb6ccf1e2 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:15:23 +0200 Subject: [PATCH 098/141] lib: Remove array_n_elements() from internal header It's unused. --- libfprint/fp_internal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 51674097..6b74c4ac 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -35,8 +35,6 @@ #include "fprint.h" #include "drivers/driver_ids.h" -#define array_n_elements(array) G_N_ELEMENTS(array) - #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) From 17577175f8a27240858313b9fc3d7272d291b823 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:20:13 +0200 Subject: [PATCH 099/141] lib: Remove fpi_driver_to_img_driver() from drivers API It's only used internally to the library. --- libfprint/drivers_api.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index 89799b19..a5c89bd4 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -39,10 +39,6 @@ #define array_n_elements(array) G_N_ELEMENTS(array) -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - #define fp_dbg g_debug #define fp_info g_debug #define fp_warn g_warning @@ -233,9 +229,6 @@ extern GSList *opened_devices; void fpi_img_driver_setup(struct fp_img_driver *idriver); -#define fpi_driver_to_img_driver(drv) \ - container_of((drv), struct fp_img_driver, driver) - struct fp_dscv_dev { struct libusb_device *udev; struct fp_driver *drv; From 2e035a7f4594e9c43a8d5c4394b0f492e2980d04 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:40:22 +0200 Subject: [PATCH 100/141] lib: Make fpi_ssm opaque for drivers We shouldn't access fpi_ssm struct fields directly in drivers, so add accessor and setter functions for the common uses. --- libfprint/drivers/aes1610.c | 32 +++++++------ libfprint/drivers/aes2501.c | 31 +++++++------ libfprint/drivers/aes2550.c | 32 ++++++------- libfprint/drivers/aesx660.c | 44 +++++++++--------- libfprint/drivers/elan.c | 54 +++++++++++----------- libfprint/drivers/etes603.c | 84 +++++++++++++++++----------------- libfprint/drivers/upeksonly.c | 70 ++++++++++++++-------------- libfprint/drivers/upektc.c | 32 ++++++------- libfprint/drivers/upektc_img.c | 47 +++++++++---------- libfprint/drivers/upekts.c | 79 +++++++++++++++++--------------- libfprint/drivers/uru4000.c | 46 +++++++++---------- libfprint/drivers/vcom5s.c | 20 ++++---- libfprint/drivers/vfs0050.c | 52 ++++++++++----------- libfprint/drivers/vfs101.c | 42 ++++++++--------- libfprint/drivers/vfs301.c | 20 ++++---- libfprint/drivers/vfs5011.c | 46 +++++++++---------- libfprint/drivers_api.h | 18 +++----- libfprint/drv.c | 28 ++++++++++++ 18 files changed, 404 insertions(+), 373 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 0a521945..3801eb19 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -130,6 +130,7 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) { struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; + struct fp_dev *dev; int r; if (!transfer) { @@ -138,7 +139,8 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) } data = g_malloc(bytes); - libusb_fill_bulk_transfer(transfer, ssm->dev->udev, EP_IN, data, bytes, + dev = fpi_ssm_get_dev(ssm); + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, bytes, generic_ignore_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -556,7 +558,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) { unsigned char *stripdata; struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes1610_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; int sum, i; @@ -643,11 +645,11 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes1610_dev *aesdev = dev->priv; int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_WRITE_REQS: fp_dbg("write reqs"); aes_write_regv(dev, capture_reqs, G_N_ELEMENTS(capture_reqs), @@ -690,14 +692,14 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes1610_dev *aesdev = dev->priv; G_DEBUG_HERE(); if (aesdev->deactivating) complete_deactivation(dev); - else if (ssm->error) - fpi_imgdev_session_error(dev, ssm->error); + else if (fpi_ssm_get_error(ssm)) + fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm)); else start_finger_detection(dev); fpi_ssm_free(ssm); @@ -715,7 +717,7 @@ static void start_capture(struct fp_img_dev *dev) ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -738,11 +740,11 @@ enum activate_states { static void activate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); /* activation on aes1610 seems much more straightforward compared to aes2501 */ /* verify theres anything missing here */ - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case WRITE_INIT: fp_dbg("write init"); aes_write_regv(dev, init, G_N_ELEMENTS(init), generic_write_regv_cb, ssm); @@ -753,11 +755,11 @@ static void activate_run_state(struct fpi_ssm *ssm) /* jump to finger detection */ static void activate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - fp_dbg("status %d", ssm->error); - fpi_imgdev_activate_complete(dev, ssm->error); + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + fp_dbg("status %d", fpi_ssm_get_error(ssm)); + fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm)); - if (!ssm->error) + if (!fpi_ssm_get_error(ssm)) start_finger_detection(dev); fpi_ssm_free(ssm); } @@ -767,7 +769,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) struct aes1610_dev *aesdev = dev->priv; struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); aesdev->read_regs_retry_count = 0; fpi_ssm_start(ssm, activate_sm_complete); return 0; diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index ab5eaa53..84def287 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -209,6 +209,7 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) { struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); int r; if (!transfer) { @@ -217,7 +218,7 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) } data = g_malloc(bytes); - libusb_fill_bulk_transfer(transfer, ssm->dev->udev, EP_IN, data, bytes, + libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, bytes, generic_ignore_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -436,7 +437,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) { unsigned char *stripdata; struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2501_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; int sum; @@ -521,11 +522,11 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2501_dev *aesdev = dev->priv; int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_WRITE_REQS_1: aes_write_regv(dev, capture_reqs_1, G_N_ELEMENTS(capture_reqs_1), generic_write_regv_cb, ssm); @@ -572,14 +573,14 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2501_dev *aesdev = dev->priv; G_DEBUG_HERE(); if (aesdev->deactivating) complete_deactivation(dev); - else if (ssm->error) - fpi_imgdev_session_error(dev, ssm->error); + else if (fpi_ssm_get_error(ssm)) + fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm)); else start_finger_detection(dev); fpi_ssm_free(ssm); @@ -600,7 +601,7 @@ static void start_capture(struct fp_img_dev *dev) strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -738,7 +739,7 @@ static void activate_init3_cb(struct fp_img_dev *dev, int result, static void activate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); /* This state machine isn't as linear as it may appear. After doing init1 * and init2 register configuration writes, we have to poll a register @@ -759,7 +760,7 @@ static void activate_run_state(struct fpi_ssm *ssm) aes_write_regv(init_4); */ - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case WRITE_INIT_1: aes_write_regv(dev, init_1, G_N_ELEMENTS(init_1), generic_write_regv_cb, ssm); @@ -792,11 +793,11 @@ static void activate_run_state(struct fpi_ssm *ssm) static void activate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - fp_dbg("status %d", ssm->error); - fpi_imgdev_activate_complete(dev, ssm->error); + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + fp_dbg("status %d", fpi_ssm_get_error(ssm)); + fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm)); - if (!ssm->error) + if (!fpi_ssm_get_error(ssm)) start_finger_detection(dev); fpi_ssm_free(ssm); } @@ -806,7 +807,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) struct aes2501_dev *aesdev = dev->priv; struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); aesdev->read_regs_retry_count = 0; fpi_ssm_start(ssm, activate_sm_complete); return 0; diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index 0e97f01d..c6d25926 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -203,7 +203,7 @@ enum capture_states { static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data) { unsigned char *stripdata; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2550_dev *aesdev = dev->priv; struct fpi_frame *stripe; int len; @@ -245,7 +245,7 @@ static void capture_reqs_cb(struct libusb_transfer *transfer) static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2550_dev *aesdev = dev->priv; if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && @@ -273,7 +273,7 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2550_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; int r; @@ -325,10 +325,10 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_WRITE_REQS: { struct libusb_transfer *transfer = libusb_alloc_transfer(0); @@ -388,14 +388,14 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aes2550_dev *aesdev = dev->priv; fp_dbg("Capture completed"); if (aesdev->deactivating) complete_deactivation(dev); - else if (ssm->error) - fpi_imgdev_session_error(dev, ssm->error); + else if (fpi_ssm_get_error(ssm)) + fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm)); else start_finger_detection(dev); fpi_ssm_free(ssm); @@ -414,7 +414,7 @@ static void start_capture(struct fp_img_dev *dev) aesdev->heartbeat_cnt = 0; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -485,10 +485,10 @@ static void calibrate_read_data_cb(struct libusb_transfer *transfer) static void activate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case WRITE_INIT: { struct libusb_transfer *transfer = libusb_alloc_transfer(0); @@ -570,11 +570,11 @@ static void activate_run_state(struct fpi_ssm *ssm) static void activate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - fp_dbg("status %d", ssm->error); - fpi_imgdev_activate_complete(dev, ssm->error); + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + fp_dbg("status %d", fpi_ssm_get_error(ssm)); + fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm)); - if (!ssm->error) + if (!fpi_ssm_get_error(ssm)) start_finger_detection(dev); fpi_ssm_free(ssm); } @@ -583,7 +583,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_sm_complete); return 0; } diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 0e26fb82..95e88492 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -40,7 +40,7 @@ static void complete_deactivation(struct fp_img_dev *dev); static void aesX660_send_cmd_timeout(struct fpi_ssm *ssm, const unsigned char *cmd, size_t cmd_len, libusb_transfer_cb_fn callback, int timeout) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); int r; @@ -69,7 +69,7 @@ static void aesX660_send_cmd(struct fpi_ssm *ssm, const unsigned char *cmd, static void aesX660_read_response(struct fpi_ssm *ssm, size_t buf_len, libusb_transfer_cb_fn callback) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -144,7 +144,7 @@ enum finger_det_states { static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; @@ -197,9 +197,9 @@ static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer) static void finger_det_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; - int err = ssm->error; + int err = fpi_ssm_get_error(ssm); fp_dbg("Finger detection completed"); fpi_imgdev_report_finger_status(dev, TRUE); @@ -217,7 +217,7 @@ static void finger_det_sm_complete(struct fpi_ssm *ssm) static void finger_det_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case FINGER_DET_SEND_LED_CMD: aesX660_send_cmd(ssm, led_blink_cmd, sizeof(led_blink_cmd), aesX660_send_cmd_cb); @@ -248,7 +248,7 @@ static void start_finger_detection(struct fp_img_dev *dev) } ssm = fpi_ssm_new(dev->dev, finger_det_run_state, FINGER_DET_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, finger_det_sm_complete); } @@ -267,7 +267,7 @@ static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) { struct fpi_frame *stripe; unsigned char *stripdata; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */ @@ -295,7 +295,7 @@ static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && @@ -321,7 +321,7 @@ static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer) static void capture_read_stripe_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; int finger_missing = 0; @@ -373,10 +373,10 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_SEND_LED_CMD: aesX660_send_cmd(ssm, led_solid_cmd, sizeof(led_solid_cmd), aesX660_send_cmd_cb); @@ -402,9 +402,9 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; - int err = ssm->error; + int err = fpi_ssm_get_error(ssm); fp_dbg("Capture completed"); fpi_ssm_free(ssm); @@ -429,7 +429,7 @@ static void start_capture(struct fp_img_dev *dev) ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -449,7 +449,7 @@ enum activate_states { static void activate_read_id_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; @@ -500,7 +500,7 @@ out: static void activate_read_init_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; unsigned char *data = transfer->buffer; @@ -536,10 +536,10 @@ out: static void activate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct aesX660_dev *aesdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_SET_IDLE: aesdev->init_seq_idx = 0; fp_dbg("Activate: set idle\n"); @@ -582,8 +582,8 @@ static void activate_run_state(struct fpi_ssm *ssm) static void activate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - int err = ssm->error; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + int err = fpi_ssm_get_error(ssm); fp_dbg("status %d", err); fpi_imgdev_activate_complete(dev, err); fpi_ssm_free(ssm); @@ -596,7 +596,7 @@ int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_sm_complete); return 0; } diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index 90df7e68..640641c3 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -161,7 +161,7 @@ static void elan_submit_image(struct fp_img_dev *dev) static void elan_cmd_done(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); @@ -176,7 +176,7 @@ static void elan_cmd_done(struct fpi_ssm *ssm) static void elan_cmd_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); @@ -218,7 +218,7 @@ static void elan_cmd_cb(struct libusb_transfer *transfer) static void elan_cmd_read(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; int response_len = elandev->cmds[elandev->cmd_idx].response_len; @@ -251,7 +251,7 @@ static void elan_cmd_read(struct fpi_ssm *ssm) static void elan_run_next_cmd(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); @@ -278,7 +278,7 @@ static void elan_run_next_cmd(struct fpi_ssm *ssm) static void elan_run_cmds(struct fpi_ssm *ssm, const struct elan_cmd *cmds, size_t cmds_len, int cmd_timeout) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); @@ -298,7 +298,7 @@ enum deactivate_states { static void elan_deactivate_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEACTIVATE: elan_run_cmds(ssm, deactivate_cmds, deactivate_cmds_len, ELAN_CMD_TIMEOUT); @@ -308,7 +308,7 @@ static void elan_deactivate_run_state(struct fpi_ssm *ssm) static void deactivate_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); fpi_imgdev_deactivate_complete(dev); } @@ -323,7 +323,7 @@ static void elan_deactivate(struct fp_img_dev *dev) struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_deactivate_run_state, DEACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, deactivate_complete); } @@ -337,10 +337,10 @@ enum capture_states { static void elan_capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_START: elan_run_cmds(ssm, capture_start_cmds, capture_start_cmds_len, ELAN_CMD_TIMEOUT); @@ -377,7 +377,7 @@ static void elan_capture_async(void *data) static void capture_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); @@ -386,9 +386,9 @@ static void capture_complete(struct fpi_ssm *ssm) elan_deactivate(dev); /* either max frames captured or timed out waiting for the next frame */ - else if (!ssm->error - || (ssm->error == -ETIMEDOUT - && ssm->cur_state == CAPTURE_WAIT_FINGER)) + else if (!fpi_ssm_get_error(ssm) + || (fpi_ssm_get_error(ssm) == -ETIMEDOUT + && fpi_ssm_get_cur_state(ssm) == CAPTURE_WAIT_FINGER)) if (elandev->num_frames >= ELAN_MIN_FRAMES) { elan_submit_image(dev); fpi_imgdev_report_finger_status(dev, FALSE); @@ -422,7 +422,7 @@ static void elan_capture(struct fp_img_dev *dev) elan_dev_reset(elandev); struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_capture_run_state, CAPTURE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_complete); } @@ -438,7 +438,7 @@ enum calibrate_states { static void elan_calibrate_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CALIBRATE_START_1: case CALIBRATE_START_2: elan_run_cmds(ssm, calibrate_start_cmds, @@ -457,17 +457,17 @@ static void elan_calibrate_run_state(struct fpi_ssm *ssm) static void calibrate_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); if (elandev->deactivating) elan_deactivate(dev); - else if (ssm->error) - fpi_imgdev_session_error(dev, ssm->error); + else if (fpi_ssm_get_error(ssm)) + fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm)); else { - fpi_imgdev_activate_complete(dev, ssm->error); + fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm)); elan_capture(dev); } fpi_ssm_free(ssm); @@ -482,7 +482,7 @@ static void elan_calibrate(struct fp_img_dev *dev) elan_dev_reset(elandev); struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_calibrate_run_state, CALIBRATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, calibrate_complete); } @@ -497,10 +497,10 @@ enum activate_states { static void elan_activate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_GET_SENSOR_DIM: elan_run_cmds(ssm, get_sensor_dim_cmds, get_sensor_dim_cmds_len, ELAN_CMD_TIMEOUT); @@ -527,15 +527,15 @@ static void elan_activate_run_state(struct fpi_ssm *ssm) static void activate_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct elan_dev *elandev = dev->priv; G_DEBUG_HERE(); if (elandev->deactivating) elan_deactivate(dev); - else if (ssm->error) - fpi_imgdev_session_error(dev, ssm->error); + else if (fpi_ssm_get_error(ssm)) + fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm)); else elan_calibrate(dev); fpi_ssm_free(ssm); @@ -550,7 +550,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) elan_dev_reset(elandev); struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_complete); return 0; diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index 22da109b..de1f0bdc 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -670,7 +670,7 @@ static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb, static void async_tx_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -701,10 +701,10 @@ static void async_tx_cb(struct libusb_transfer *transfer) static void m_exit_state(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case EXIT_SET_REGS_REQ: msg_set_regs(dev, 4, REG_VCO_CONTROL, REG_VCO_IDLE, REG_MODE_CONTROL, REG_MODE_SLEEP); @@ -717,7 +717,7 @@ static void m_exit_state(struct fpi_ssm *ssm) fpi_ssm_mark_completed(ssm); break; default: - fp_err("Unknown state %d", ssm->cur_state); + fp_err("Unknown state %d", fpi_ssm_get_cur_state(ssm)); goto err; break; } @@ -729,9 +729,9 @@ err: static void m_exit_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - if (ssm->error) { + if (fpi_ssm_get_error(ssm)) { fp_err("Error switching the device to idle state"); } else { fp_dbg("The device is now in idle state"); @@ -745,13 +745,13 @@ static void m_exit_start(struct fp_img_dev *idev) struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, m_exit_state, EXIT_NUM_STATES); fp_dbg("Switching device to idle mode"); - ssm->priv = idev; + fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, m_exit_complete); } static void m_capture_state(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; if (dev->is_active == FALSE) { @@ -759,7 +759,7 @@ static void m_capture_state(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAP_FP_INIT_SET_REG10_REQ: /* Reset fingerprint */ fp_dbg("Capturing a fingerprint..."); @@ -820,7 +820,7 @@ static void m_capture_state(struct fpi_ssm *ssm) } break; default: - fp_err("Unknown state %d", ssm->cur_state); + fp_err("Unknown state %d", fpi_ssm_get_cur_state(ssm)); goto err; break; } @@ -832,14 +832,14 @@ err: static void m_capture_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; - if (ssm->error) { + if (fpi_ssm_get_error(ssm)) { if (idev->action_state != IMG_ACQUIRE_STATE_DEACTIVATING) { fp_err("Error while capturing fingerprint " - "(ssm->error=%d)", ssm->error); - fpi_imgdev_session_error(idev, ssm->error); + "(fpi_ssm_get_error(ssm)=%d)", fpi_ssm_get_error(ssm)); + fpi_imgdev_session_error(idev, fpi_ssm_get_error(ssm)); } } fpi_ssm_free(ssm); @@ -854,7 +854,7 @@ static void m_capture_complete(struct fpi_ssm *ssm) static void m_finger_state(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; if (dev->is_active == FALSE) { @@ -862,7 +862,7 @@ static void m_finger_state(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case FGR_FPA_INIT_SET_MODE_SLEEP_REQ: msg_set_mode_control(dev, REG_MODE_SLEEP); if (async_tx(idev, EP_OUT, async_tx_cb, ssm)) @@ -938,7 +938,7 @@ static void m_finger_state(struct fpi_ssm *ssm) } break; default: - fp_err("Unknown state %d", ssm->cur_state); + fp_err("Unknown state %d", fpi_ssm_get_cur_state(ssm)); goto err; break; } @@ -950,19 +950,19 @@ err: static void m_finger_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; - if (!ssm->error) { + if (!fpi_ssm_get_error(ssm)) { struct fpi_ssm *ssm_cap; ssm_cap = fpi_ssm_new(idev->dev, m_capture_state, CAP_NUM_STATES); - ssm_cap->priv = idev; + fpi_ssm_set_user_data(ssm_cap, idev); fpi_ssm_start(ssm_cap, m_capture_complete); } else { if (idev->action_state != IMG_ACQUIRE_STATE_DEACTIVATING) { fp_err("Error while capturing fingerprint " - "(ssm->error=%d)", ssm->error); + "(fpi_ssm_get_error(ssm)=%d)", fpi_ssm_get_error(ssm)); fpi_imgdev_session_error(idev, -4); } dev->is_active = FALSE; @@ -975,7 +975,7 @@ static void m_start_fingerdetect(struct fp_img_dev *idev) { struct fpi_ssm *ssmf; ssmf = fpi_ssm_new(idev->dev, m_finger_state, FGR_NUM_STATES); - ssmf->priv = idev; + fpi_ssm_set_user_data(ssmf, idev); fpi_ssm_start(ssmf, m_finger_complete); } @@ -984,7 +984,7 @@ static void m_start_fingerdetect(struct fp_img_dev *idev) */ static void m_tunevrb_state(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; float hist[5]; @@ -993,7 +993,7 @@ static void m_tunevrb_state(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case TUNEVRB_INIT: fp_dbg("Tuning of VRT/VRB"); g_assert(dev->dcoffset); @@ -1124,7 +1124,7 @@ static void m_tunevrb_state(struct fpi_ssm *ssm) fpi_ssm_mark_completed(ssm); break; default: - fp_err("Unknown state %d", ssm->cur_state); + fp_err("Unknown state %d", fpi_ssm_get_cur_state(ssm)); goto err; break; } @@ -1136,10 +1136,10 @@ err: static void m_tunevrb_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - fpi_imgdev_activate_complete(idev, ssm->error != 0); - if (!ssm->error) { + fpi_imgdev_activate_complete(idev, fpi_ssm_get_error(ssm) != 0); + if (!fpi_ssm_get_error(ssm)) { fp_dbg("Tuning is done. Starting finger detection."); m_start_fingerdetect(idev); } else { @@ -1158,7 +1158,7 @@ static void m_tunevrb_complete(struct fpi_ssm *ssm) */ static void m_tunedc_state(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; if (dev->is_active == FALSE) { @@ -1170,7 +1170,7 @@ static void m_tunedc_state(struct fpi_ssm *ssm) * captured traffic to make sure that the value is correct. */ /* The default gain should work but it may reach a DCOffset limit so in * this case we decrease the gain. */ - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case TUNEDC_INIT: /* reg_e0 = 0x23 is sensor normal/small gain */ dev->gain = GAIN_SMALL_INIT; @@ -1248,7 +1248,7 @@ static void m_tunedc_state(struct fpi_ssm *ssm) fpi_ssm_mark_completed(ssm); break; default: - fp_err("Unknown state %d", ssm->cur_state); + fp_err("Unknown state %d", fpi_ssm_get_cur_state(ssm)); goto err; break; } @@ -1261,12 +1261,12 @@ err: static void m_tunedc_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; - if (!ssm->error) { + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); + if (!fpi_ssm_get_error(ssm)) { struct fpi_ssm *ssm_tune; ssm_tune = fpi_ssm_new(idev->dev, m_tunevrb_state, TUNEVRB_NUM_STATES); - ssm_tune->priv = idev; + fpi_ssm_set_user_data(ssm_tune, idev); fpi_ssm_start(ssm_tune, m_tunevrb_complete); } else { struct etes603_dev *dev = idev->priv; @@ -1280,7 +1280,7 @@ static void m_tunedc_complete(struct fpi_ssm *ssm) static void m_init_state(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct etes603_dev *dev = idev->priv; if (dev->is_active == FALSE) { @@ -1288,7 +1288,7 @@ static void m_init_state(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case INIT_CHECK_INFO_REQ: msg_get_regs(dev, 4, REG_INFO0, REG_INFO1, REG_INFO2, REG_INFO3); @@ -1368,7 +1368,7 @@ static void m_init_state(struct fpi_ssm *ssm) fpi_ssm_mark_completed(ssm); break; default: - fp_err("Unknown state %d", ssm->cur_state); + fp_err("Unknown state %d", fpi_ssm_get_cur_state(ssm)); goto err; break; } @@ -1381,12 +1381,12 @@ err: static void m_init_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; - if (!ssm->error) { + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); + if (!fpi_ssm_get_error(ssm)) { struct fpi_ssm *ssm_tune; ssm_tune = fpi_ssm_new(idev->dev, m_tunedc_state, TUNEDC_NUM_STATES); - ssm_tune->priv = idev; + fpi_ssm_set_user_data(ssm_tune, idev); fpi_ssm_start(ssm_tune, m_tunedc_complete); } else { struct etes603_dev *dev = idev->priv; @@ -1417,7 +1417,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) if (dev->dcoffset == 0) { fp_dbg("Tuning device..."); ssm = fpi_ssm_new(idev->dev, m_init_state, INIT_NUM_STATES); - ssm->priv = idev; + fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, m_init_complete); } else { fp_dbg("Using previous tuning (DCOFFSET=0x%02X,VRT=0x%02X," @@ -1425,7 +1425,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) dev->vrb, dev->gain); fpi_imgdev_activate_complete(idev, 0); ssm = fpi_ssm_new(idev->dev, m_finger_state, FGR_NUM_STATES); - ssm->priv = idev; + fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, m_finger_complete); } return 0; diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 209f788f..85311856 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -579,6 +579,7 @@ static void sm_write_regs(struct fpi_ssm *ssm, { struct write_regs_data *wrdata = g_malloc(sizeof(*wrdata)); unsigned char *data; + struct fp_dev *dev; wrdata->transfer = libusb_alloc_transfer(0); if (!wrdata->transfer) { @@ -589,7 +590,8 @@ static void sm_write_regs(struct fpi_ssm *ssm, data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, 0x40, 0x0c, 0, 0, 1); - libusb_fill_control_transfer(wrdata->transfer, ssm->dev->udev, data, + dev = fpi_ssm_get_dev(ssm); + libusb_fill_control_transfer(wrdata->transfer, dev->udev, data, write_regs_cb, wrdata, CTRL_TIMEOUT); wrdata->transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; @@ -613,7 +615,7 @@ static void sm_write_reg_cb(struct libusb_transfer *transfer) static void sm_write_reg(struct fpi_ssm *ssm, uint8_t reg, uint8_t value) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -644,7 +646,7 @@ static void sm_write_reg(struct fpi_ssm *ssm, uint8_t reg, uint8_t value) static void sm_read_reg_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -660,7 +662,7 @@ static void sm_read_reg_cb(struct libusb_transfer *transfer) static void sm_read_reg(struct fpi_ssm *ssm, uint8_t reg) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -689,7 +691,7 @@ static void sm_read_reg(struct fpi_ssm *ssm, uint8_t reg) static void sm_await_intr_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -710,7 +712,7 @@ static void sm_await_intr_cb(struct libusb_transfer *transfer) static void sm_await_intr(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -759,10 +761,10 @@ enum awfsm_1000_states { static void awfsm_2016_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case AWFSM_2016_WRITEV_1: sm_write_regs(ssm, awfsm_2016_writev_1, G_N_ELEMENTS(awfsm_2016_writev_1)); break; @@ -806,7 +808,7 @@ static void awfsm_2016_run_state(struct fpi_ssm *ssm) static void awfsm_1000_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case AWFSM_1000_WRITEV_1: sm_write_regs(ssm, awfsm_1000_writev_1, G_N_ELEMENTS(awfsm_1000_writev_1)); break; @@ -847,7 +849,7 @@ enum capsm_1001_states { static void capsm_fire_bulk(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; int i; for (i = 0; i < NUM_BULK_TRANSFERS; i++) { @@ -877,10 +879,10 @@ static void capsm_fire_bulk(struct fpi_ssm *ssm) static void capsm_2016_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPSM_2016_INIT: sdev->rowbuf_offset = -1; sdev->num_rows = 0; @@ -909,10 +911,10 @@ static void capsm_2016_run_state(struct fpi_ssm *ssm) static void capsm_1000_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPSM_1000_INIT: sdev->rowbuf_offset = -1; sdev->num_rows = 0; @@ -935,10 +937,10 @@ static void capsm_1000_run_state(struct fpi_ssm *ssm) static void capsm_1001_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPSM_1001_INIT: sdev->rowbuf_offset = -1; sdev->num_rows = 0; @@ -990,7 +992,7 @@ enum deinitsm_1001_states { static void deinitsm_2016_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEINITSM_2016_WRITEV: sm_write_regs(ssm, deinitsm_2016_writev, G_N_ELEMENTS(deinitsm_2016_writev)); break; @@ -999,7 +1001,7 @@ static void deinitsm_2016_run_state(struct fpi_ssm *ssm) static void deinitsm_1000_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEINITSM_1000_WRITEV: sm_write_regs(ssm, deinitsm_1000_writev, G_N_ELEMENTS(deinitsm_1000_writev)); break; @@ -1008,7 +1010,7 @@ static void deinitsm_1000_run_state(struct fpi_ssm *ssm) static void deinitsm_1001_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEINITSM_1001_WRITEV: sm_write_regs(ssm, deinitsm_1001_writev, G_N_ELEMENTS(deinitsm_1001_writev)); break; @@ -1044,10 +1046,10 @@ enum initsm_1001_states { static void initsm_2016_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case INITSM_2016_WRITEV_1: sm_write_regs(ssm, initsm_2016_writev_1, G_N_ELEMENTS(initsm_2016_writev_1)); break; @@ -1074,7 +1076,7 @@ static void initsm_2016_run_state(struct fpi_ssm *ssm) static void initsm_1000_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case INITSM_1000_WRITEV_1: sm_write_regs(ssm, initsm_1000_writev_1, G_N_ELEMENTS(initsm_1000_writev_1)); break; @@ -1083,7 +1085,7 @@ static void initsm_1000_run_state(struct fpi_ssm *ssm) static void initsm_1001_run_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case INITSM_1001_WRITEV_1: sm_write_regs(ssm, initsm_1001_writev_1, G_N_ELEMENTS(initsm_1001_writev_1)); break; @@ -1116,10 +1118,10 @@ enum loopsm_states { static void loopsm_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case LOOPSM_RUN_AWFSM: ; switch (sdev->dev_model) { case UPEKSONLY_1001: @@ -1144,7 +1146,7 @@ static void loopsm_run_state(struct fpi_ssm *ssm) AWFSM_1000_NUM_STATES); break; } - awfsm->priv = dev; + fpi_ssm_set_user_data(awfsm, dev); fpi_ssm_start_subsm(ssm, awfsm); } break; @@ -1176,7 +1178,7 @@ static void loopsm_run_state(struct fpi_ssm *ssm) CAPSM_1001_NUM_STATES); break; } - capsm->priv = dev; + fpi_ssm_set_user_data(capsm, dev); fpi_ssm_start_subsm(ssm, capsm); break; case LOOPSM_CAPTURE: @@ -1198,7 +1200,7 @@ static void loopsm_run_state(struct fpi_ssm *ssm) break; } sdev->capturing = FALSE; - deinitsm->priv = dev; + fpi_ssm_set_user_data(deinitsm, dev); fpi_ssm_start_subsm(ssm, deinitsm); break; case LOOPSM_FINAL: @@ -1244,9 +1246,9 @@ static void dev_deactivate(struct fp_img_dev *dev) static void loopsm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - int r = ssm->error; + int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); @@ -1263,9 +1265,9 @@ static void loopsm_complete(struct fpi_ssm *ssm) static void initsm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct sonly_dev *sdev = dev->priv; - int r = ssm->error; + int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); fpi_imgdev_activate_complete(dev, r); @@ -1273,7 +1275,7 @@ static void initsm_complete(struct fpi_ssm *ssm) return; sdev->loopsm = fpi_ssm_new(dev->dev, loopsm_run_state, LOOPSM_NUM_STATES); - sdev->loopsm->priv = dev; + fpi_ssm_set_user_data(sdev->loopsm, dev); fpi_ssm_start(sdev->loopsm, loopsm_complete); } @@ -1316,7 +1318,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) ssm = fpi_ssm_new(dev->dev, initsm_1001_run_state, INITSM_1001_NUM_STATES); break; } - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, initsm_complete); return 0; } diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 0d78fa61..2c406840 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -58,7 +58,7 @@ enum activate_states { static void upektc_next_init_cmd(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_dev *upekdev = dev->priv; upekdev->init_idx += 1; @@ -71,7 +71,7 @@ static void upektc_next_init_cmd(struct fpi_ssm *ssm) static void write_init_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_dev *upekdev = dev->priv; if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && @@ -100,11 +100,11 @@ static void read_init_data_cb(struct libusb_transfer *transfer) static void activate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_dev *upekdev = dev->priv; int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case WRITE_INIT: { struct libusb_transfer *transfer = libusb_alloc_transfer(0); @@ -150,11 +150,11 @@ static void activate_run_state(struct fpi_ssm *ssm) static void activate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - fp_dbg("status %d", ssm->error); - fpi_imgdev_activate_complete(dev, ssm->error); + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + fp_dbg("status %d", fpi_ssm_get_error(ssm)); + fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm)); - if (!ssm->error) + if (!fpi_ssm_get_error(ssm)) start_finger_detection(dev); fpi_ssm_free(ssm); } @@ -297,7 +297,7 @@ static void capture_cmd_cb(struct libusb_transfer *transfer) static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); unsigned char *data = transfer->buffer; struct fp_img *img; @@ -323,11 +323,11 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_dev *upekdev = dev->priv; int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_WRITE_CMD: { struct libusb_transfer *transfer = libusb_alloc_transfer(0); @@ -372,14 +372,14 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_dev *upekdev = dev->priv; fp_dbg("Capture completed"); if (upekdev->deactivating) complete_deactivation(dev); - else if (ssm->error) - fpi_imgdev_session_error(dev, ssm->error); + else if (fpi_ssm_get_error(ssm)) + fpi_imgdev_session_error(dev, fpi_ssm_get_error(ssm)); else start_finger_detection(dev); fpi_ssm_free(ssm); @@ -397,7 +397,7 @@ static void start_capture(struct fp_img_dev *dev) ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -406,7 +406,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) struct upektc_dev *upekdev = dev->priv; struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); upekdev->init_idx = 0; fpi_ssm_start(ssm, activate_sm_complete); return 0; diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 1ddb159c..914aa80b 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -118,7 +118,7 @@ static void upektc_img_submit_req(struct fpi_ssm *ssm, const unsigned char *buf, size_t buf_size, unsigned char seq, libusb_transfer_cb_fn cb) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; struct libusb_transfer *transfer = libusb_alloc_transfer(0); int r; @@ -149,7 +149,7 @@ static void upektc_img_submit_req(struct fpi_ssm *ssm, static void upektc_img_read_data(struct fpi_ssm *ssm, size_t buf_size, size_t buf_offset, libusb_transfer_cb_fn cb) { struct libusb_transfer *transfer = libusb_alloc_transfer(0); - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; int r; @@ -194,7 +194,7 @@ static void capture_reqs_cb(struct libusb_transfer *transfer) fpi_ssm_mark_aborted(ssm, -EIO); return; } - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_ACK_00_28_TERM: fpi_ssm_jump_to_state(ssm, CAPTURE_READ_DATA_TERM); break; @@ -225,7 +225,7 @@ static int upektc_img_process_image_frame(unsigned char *image_buf, unsigned cha static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; unsigned char *data = upekdev->response; struct fp_img *img; @@ -245,11 +245,11 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) fp_dbg("request completed, len: %.4x", transfer->actual_length); if (transfer->actual_length == 0) { - fpi_ssm_jump_to_state(ssm, ssm->cur_state); + fpi_ssm_jump_to_state(ssm, fpi_ssm_get_cur_state(ssm)); return; } - if (ssm->cur_state == CAPTURE_READ_DATA_TERM) { + if (fpi_ssm_get_cur_state(ssm) == CAPTURE_READ_DATA_TERM) { fp_dbg("Terminating SSM\n"); fpi_ssm_mark_completed(ssm); return; @@ -349,10 +349,10 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) static void capture_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_INIT_CAPTURE: upektc_img_submit_req(ssm, upek2020_init_capture, sizeof(upek2020_init_capture), upekdev->seq, capture_reqs_cb); @@ -386,9 +386,9 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; - int err = ssm->error; + int err = fpi_ssm_get_error(ssm); fp_dbg("Capture completed, %d", err); fpi_ssm_free(ssm); @@ -409,7 +409,7 @@ static void start_capture(struct fp_img_dev *dev) upekdev->image_size = 0; ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -447,10 +447,10 @@ static void deactivate_read_data_cb(struct libusb_transfer *transfer) static void deactivate_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEACTIVATE_DEINIT: upektc_img_submit_req(ssm, upek2020_deinit, sizeof(upek2020_deinit), upekdev->seq, deactivate_reqs_cb); @@ -464,9 +464,9 @@ static void deactivate_run_state(struct fpi_ssm *ssm) static void deactivate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct upektc_img_dev *upekdev = dev->priv; - int err = ssm->error; + int err = fpi_ssm_get_error(ssm); fp_dbg("Deactivate completed"); fpi_ssm_free(ssm); @@ -488,7 +488,7 @@ static void start_deactivation(struct fp_img_dev *dev) upekdev->image_size = 0; ssm = fpi_ssm_new(dev->dev, deactivate_run_state, DEACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, deactivate_sm_complete); } @@ -546,11 +546,12 @@ static void init_read_data_cb(struct libusb_transfer *transfer) static void activate_run_state(struct fpi_ssm *ssm) { struct libusb_transfer *transfer; - struct fp_img_dev *dev = ssm->priv; - struct upektc_img_dev *upekdev = dev->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); + struct upektc_img_dev *upekdev = idev->priv; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_CONTROL_REQ_1: case ACTIVATE_CONTROL_REQ_2: { @@ -567,7 +568,7 @@ static void activate_run_state(struct fpi_ssm *ssm) data = g_malloc0(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1); - libusb_fill_control_transfer(transfer, ssm->dev->udev, data, + libusb_fill_control_transfer(transfer, dev->udev, data, init_reqs_ctrl_cb, ssm, CTRL_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -608,8 +609,8 @@ static void activate_run_state(struct fpi_ssm *ssm) static void activate_sm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - int err = ssm->error; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + int err = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); fp_dbg("%s status %d", __func__, err); @@ -624,7 +625,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) struct upektc_img_dev *upekdev = dev->priv; struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); upekdev->seq = 0; fpi_ssm_start(ssm, activate_sm_complete); return 0; diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index 9dbfe12f..ed714004 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -529,23 +529,23 @@ static void initsm_read_msg_response_cb(struct fpi_ssm *ssm, enum read_msg_status status, uint8_t seq, unsigned char expect_subcmd, unsigned char subcmd) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); struct upekts_dev *upekdev = dev->priv; if (status != READ_MSG_RESPONSE) { fp_err("expected response, got %d seq=%x in state %d", status, seq, - ssm->cur_state); + fpi_ssm_get_cur_state(ssm)); fpi_ssm_mark_aborted(ssm, -1); } else if (subcmd != expect_subcmd) { fp_warn("expected response to subcmd 0x%02x, got response to %02x in " - "state %d", expect_subcmd, subcmd, ssm->cur_state); + "state %d", expect_subcmd, subcmd, fpi_ssm_get_cur_state(ssm)); fpi_ssm_mark_aborted(ssm, -1); } else if (seq != upekdev->seq) { fp_err("expected response to cmd seq=%02x, got response to %02x " - "in state %d", upekdev->seq, seq, ssm->cur_state); + "in state %d", upekdev->seq, seq, fpi_ssm_get_cur_state(ssm)); fpi_ssm_mark_aborted(ssm, -1); } else { - fp_dbg("state %d completed", ssm->cur_state); + fp_dbg("state %d completed", fpi_ssm_get_cur_state(ssm)); fpi_ssm_next_state(ssm); } } @@ -593,7 +593,7 @@ static void read28_06_cb(struct fp_dev *dev, enum read_msg_status status, static void initsm_read_msg_cmd_cb(struct fpi_ssm *ssm, enum read_msg_status status, uint8_t expect_seq, uint8_t seq) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); struct upekts_dev *upekdev = dev->priv; if (status == READ_MSG_ERROR) { @@ -601,14 +601,14 @@ static void initsm_read_msg_cmd_cb(struct fpi_ssm *ssm, return; } else if (status != READ_MSG_CMD) { fp_err("expected command, got %d seq=%x in state %d", status, seq, - ssm->cur_state); + fpi_ssm_get_cur_state(ssm)); fpi_ssm_mark_aborted(ssm, -1); return; } upekdev->seq = seq; if (seq != expect_seq) { fp_err("expected seq=%x, got %x in state %d", expect_seq, seq, - ssm->cur_state); + fpi_ssm_get_cur_state(ssm)); fpi_ssm_mark_aborted(ssm, -1); return; } @@ -645,9 +645,9 @@ static void ctrl400_cb(struct libusb_transfer *transfer) static void initsm_read_msg_handler(struct fpi_ssm *ssm, read_msg_cb_fn callback) { - int r = read_msg_async(ssm->dev, callback, ssm); + int r = read_msg_async(fpi_ssm_get_dev(ssm), callback, ssm); if (r < 0) { - fp_err("async read msg failed in state %d", ssm->cur_state); + fp_err("async read msg failed in state %d", fpi_ssm_get_cur_state(ssm)); fpi_ssm_mark_aborted(ssm, r); } } @@ -657,10 +657,10 @@ static void initsm_send_msg_cb(struct libusb_transfer *transfer) struct fpi_ssm *ssm = transfer->user_data; if (transfer->status == LIBUSB_TRANSFER_COMPLETED && transfer->length == transfer->actual_length) { - fp_dbg("state %d completed", ssm->cur_state); + fp_dbg("state %d completed", fpi_ssm_get_cur_state(ssm)); fpi_ssm_next_state(ssm); } else { - fp_err("failed, state=%d rqlength=%d actual_length=%d", ssm->cur_state, + fp_err("failed, state=%d rqlength=%d actual_length=%d", fpi_ssm_get_cur_state(ssm), transfer->length, transfer->actual_length); fpi_ssm_mark_aborted(ssm, -1); } @@ -670,7 +670,7 @@ static void initsm_send_msg_cb(struct libusb_transfer *transfer) static void initsm_send_msg28_handler(struct fpi_ssm *ssm, unsigned char subcmd, const unsigned char *data, uint16_t innerlen) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); struct libusb_transfer *transfer; int r; @@ -683,7 +683,7 @@ static void initsm_send_msg28_handler(struct fpi_ssm *ssm, r = libusb_submit_transfer(transfer); if (r < 0) { - fp_err("urb submission failed error %d in state %d", r, ssm->cur_state); + fp_err("urb submission failed error %d in state %d", r, fpi_ssm_get_cur_state(ssm)); g_free(transfer->buffer); libusb_free_transfer(transfer); fpi_ssm_mark_aborted(ssm, -EIO); @@ -692,12 +692,12 @@ static void initsm_send_msg28_handler(struct fpi_ssm *ssm, static void initsm_run_state(struct fpi_ssm *ssm) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); struct upekts_dev *upekdev = dev->priv; struct libusb_transfer *transfer; int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case WRITE_CTRL400: ; unsigned char *data; @@ -710,7 +710,7 @@ static void initsm_run_state(struct fpi_ssm *ssm) data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1); - libusb_fill_control_transfer(transfer, ssm->dev->udev, data, + libusb_fill_control_transfer(transfer, dev->udev, data, ctrl400_cb, ssm, TIMEOUT); r = libusb_submit_transfer(transfer); @@ -827,10 +827,10 @@ static void read_msg01_cb(struct fp_dev *dev, enum read_msg_status status, static void deinitsm_state_handler(struct fpi_ssm *ssm) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case SEND_RESP07: ; struct libusb_transfer *transfer; unsigned char dummy = 0; @@ -909,8 +909,8 @@ enum enroll_start_sm_states { /* Called when the device initialization state machine completes */ static void enroll_start_sm_cb_initsm(struct fpi_ssm *initsm) { - struct fpi_ssm *enroll_start_ssm = initsm->priv; - int error = initsm->error; + struct fpi_ssm *enroll_start_ssm = fpi_ssm_get_user_data(initsm); + int error = fpi_ssm_get_error(initsm); fpi_ssm_free(initsm); if (error) @@ -957,13 +957,13 @@ static void enroll_start_sm_cb_msg28(struct fp_dev *dev, static void enroll_start_sm_run_state(struct fpi_ssm *ssm) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case RUN_INITSM: ; struct fpi_ssm *initsm = initsm_new(dev); - initsm->priv = ssm; + fpi_ssm_set_user_data(initsm, ssm); fpi_ssm_start(initsm, enroll_start_sm_cb_initsm); break; case ENROLL_INIT: ; @@ -1150,10 +1150,10 @@ static void enroll_iterate(struct fp_dev *dev) static void enroll_started(struct fpi_ssm *ssm) { - struct fp_dev *dev = ssm->dev; - fpi_drvcb_enroll_started(dev, ssm->error); + struct fp_dev *dev = fpi_ssm_get_dev(ssm); + fpi_drvcb_enroll_started(dev, fpi_ssm_get_error(ssm)); - if (!ssm->error) + if (!fpi_ssm_get_error(ssm)) enroll_iterate(dev); fpi_ssm_free(ssm); @@ -1175,7 +1175,7 @@ static int enroll_start(struct fp_dev *dev) static void enroll_stop_deinit_cb(struct fpi_ssm *ssm) { /* don't really care about errors */ - fpi_drvcb_enroll_stopped(ssm->dev); + fpi_drvcb_enroll_stopped(fpi_ssm_get_dev(ssm)); fpi_ssm_free(ssm); } @@ -1189,7 +1189,7 @@ static int enroll_stop(struct fp_dev *dev) static void verify_stop_deinit_cb(struct fpi_ssm *ssm) { /* don't really care about errors */ - fpi_drvcb_verify_stopped(ssm->dev); + fpi_drvcb_verify_stopped(fpi_ssm_get_dev(ssm)); fpi_ssm_free(ssm); } @@ -1214,9 +1214,12 @@ enum { /* Called when the device initialization state machine completes */ static void verify_start_sm_cb_initsm(struct fpi_ssm *initsm) { - struct fpi_ssm *verify_start_ssm = initsm->priv; - if (initsm->error) - fpi_ssm_mark_aborted(verify_start_ssm, initsm->error); + struct fpi_ssm *verify_start_ssm = fpi_ssm_get_user_data(initsm); + int err; + + err = fpi_ssm_get_error(initsm); + if (err) + fpi_ssm_mark_aborted(verify_start_ssm, err); else fpi_ssm_next_state(verify_start_ssm); fpi_ssm_free(initsm); @@ -1236,13 +1239,13 @@ static void verify_init_2803_cb(struct libusb_transfer *transfer) static void verify_start_sm_run_state(struct fpi_ssm *ssm) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); int r; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case VERIFY_RUN_INITSM: ; struct fpi_ssm *initsm = initsm_new(dev); - initsm->priv = ssm; + fpi_ssm_set_user_data(initsm, ssm); fpi_ssm_start(initsm, verify_start_sm_cb_initsm); break; case VERIFY_INIT: ; @@ -1426,11 +1429,11 @@ static void verify_iterate(struct fp_dev *dev) static void verify_started(struct fpi_ssm *ssm) { - struct fp_dev *dev = ssm->dev; + struct fp_dev *dev = fpi_ssm_get_dev(ssm); struct upekts_dev *upekdev = dev->priv; - fpi_drvcb_verify_started(dev, ssm->error); - if (!ssm->error) { + fpi_drvcb_verify_started(dev, fpi_ssm_get_error(ssm)); + if (!fpi_ssm_get_error(ssm)) { upekdev->first_verify_iteration = TRUE; verify_iterate(dev); } diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index dfa945db..a28925ca 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -356,7 +356,7 @@ static void challenge_cb(struct fp_img_dev *dev, int status, */ static void sm_do_challenge_response(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); int r; G_DEBUG_HERE(); @@ -519,7 +519,7 @@ static void sm_write_reg_cb(struct fp_img_dev *dev, int result, void *user_data) static void sm_write_regs(struct fpi_ssm *ssm, uint16_t first_reg, uint16_t num_regs, void *data) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); int r = write_regs(dev, first_reg, num_regs, data, sm_write_reg_cb, ssm); if (r < 0) fpi_ssm_mark_aborted(ssm, r); @@ -548,7 +548,7 @@ static void sm_read_reg_cb(struct fp_img_dev *dev, int result, static void sm_read_regs(struct fpi_ssm *ssm, uint16_t reg, uint16_t num_regs) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; int r; @@ -689,7 +689,7 @@ static int calc_dev2(struct uru4k_image *img) static void imaging_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; struct uru4k_image *img = urudev->img_data; struct fp_img *fpimg; @@ -698,7 +698,7 @@ static void imaging_run_state(struct fpi_ssm *ssm) int i, r, to, dev2; char buf[5]; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case IMAGING_CAPTURE: urudev->img_lines_done = 0; urudev->img_block = 0; @@ -812,9 +812,9 @@ static void imaging_run_state(struct fpi_ssm *ssm) static void imaging_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; - int r = ssm->error; + int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); /* Report error before exiting imaging loop - the error handler @@ -863,7 +863,7 @@ enum rebootpwr_states { static void rebootpwr_pause_cb(void *data) { struct fpi_ssm *ssm = data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; if (!--urudev->rebootpwr_ctr) { @@ -876,10 +876,10 @@ static void rebootpwr_pause_cb(void *data) static void rebootpwr_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case REBOOTPWR_SET_HWSTAT: urudev->rebootpwr_ctr = 100; sm_set_hwstat(ssm, urudev->last_hwstat & 0xf); @@ -940,7 +940,7 @@ enum powerup_states { static void powerup_pause_cb(void *data) { struct fpi_ssm *ssm = data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; if (!--urudev->powerup_ctr) { @@ -955,10 +955,10 @@ static void powerup_pause_cb(void *data) static void powerup_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case POWERUP_INIT: urudev->powerup_ctr = 100; urudev->powerup_hwstat = urudev->last_hwstat & 0xf; @@ -1031,7 +1031,7 @@ static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int 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) { + else if (fpi_ssm_get_cur_state(ssm) != INIT_AWAIT_SCAN_POWER) { fp_dbg("early scanpwr interrupt"); urudev->scanpwr_irq_timeouts = -1; } else { @@ -1043,7 +1043,7 @@ static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status, static void init_scanpwr_timeout(void *user_data) { struct fpi_ssm *ssm = user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; fp_warn("powerup timed out"); @@ -1060,10 +1060,10 @@ static void init_scanpwr_timeout(void *user_data) static void init_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct uru4k_dev *urudev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case INIT_GET_HWSTAT: sm_read_reg(ssm, REG_HWSTAT); break; @@ -1077,7 +1077,7 @@ static void init_run_state(struct fpi_ssm *ssm) case INIT_REBOOT_POWER: ; struct fpi_ssm *rebootsm = fpi_ssm_new(dev->dev, rebootpwr_run_state, REBOOTPWR_NUM_STATES); - rebootsm->priv = dev; + fpi_ssm_set_user_data(rebootsm, dev); fpi_ssm_start_subsm(ssm, rebootsm); break; case INIT_CHECK_HWSTAT_POWERDOWN: @@ -1096,7 +1096,7 @@ static void init_run_state(struct fpi_ssm *ssm) struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state, POWERUP_NUM_STATES); - powerupsm->priv = dev; + fpi_ssm_set_user_data(powerupsm, dev); fpi_ssm_start_subsm(ssm, powerupsm); break; case INIT_AWAIT_SCAN_POWER: @@ -1140,8 +1140,8 @@ static void init_run_state(struct fpi_ssm *ssm) static void activate_initsm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; - int r = ssm->error; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); + int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); if (r) { @@ -1170,7 +1170,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) urudev->scanpwr_irq_timeouts = 0; urudev->activate_state = state; ssm = fpi_ssm_new(dev->dev, init_run_state, INIT_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_initsm_complete); return 0; } @@ -1224,7 +1224,7 @@ static int execute_state_change(struct fp_img_dev *dev) urudev->img_enc_seed = rand(); ssm = fpi_ssm_new(dev->dev, imaging_run_state, IMAGING_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, imaging_complete); return write_reg(dev, REG_MODE, MODE_CAPTURE, diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 02e57e35..7a6444b9 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -88,7 +88,7 @@ static void sm_write_reg_cb(struct libusb_transfer *transfer) static void sm_write_reg(struct fpi_ssm *ssm, unsigned char reg, unsigned char value) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -127,7 +127,7 @@ static void sm_exec_cmd_cb(struct libusb_transfer *transfer) static void sm_exec_cmd(struct fpi_ssm *ssm, unsigned char cmd, unsigned char param) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -192,7 +192,7 @@ static void capture_iterate(struct fpi_ssm *ssm); static void capture_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct v5s_dev *vdev = dev->priv; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -220,7 +220,7 @@ out: static void capture_iterate(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct v5s_dev *vdev = dev->priv; int iteration = vdev->capture_iteration; struct libusb_transfer *transfer = libusb_alloc_transfer(0); @@ -245,7 +245,7 @@ static void capture_iterate(struct fpi_ssm *ssm) static void sm_do_capture(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct v5s_dev *vdev = dev->priv; G_DEBUG_HERE(); @@ -267,10 +267,10 @@ enum loop_states { static void loop_run_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct v5s_dev *vdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case LOOP_SET_CONTRAST: sm_write_reg(ssm, REG_CONTRAST, 0x01); break; @@ -295,9 +295,9 @@ static void loop_run_state(struct fpi_ssm *ssm) static void loopsm_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct v5s_dev *vdev = dev->priv; - int r = ssm->error; + int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); fp_img_free(vdev->capture_img); @@ -316,7 +316,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) struct v5s_dev *vdev = dev->priv; struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, loop_run_state, LOOP_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); vdev->deactivating = FALSE; fpi_ssm_start(ssm, loopsm_complete); vdev->loop_running = TRUE; diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index e6d3915e..cbbda031 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -28,7 +28,7 @@ static void async_write_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); int transferred = transfer->actual_length, error = transfer->status, len = transfer->length; @@ -53,7 +53,7 @@ static void async_write_callback(struct libusb_transfer *transfer) /* Send data to EP1, the only out endpoint */ static void async_write(struct fpi_ssm *ssm, void *data, int len) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct libusb_device_handle *udev = idev->udev; struct vfs_dev_t *vdev = idev->priv; @@ -68,7 +68,7 @@ static void async_write(struct fpi_ssm *ssm, void *data, int len) static void async_read_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); int transferred = transfer->actual_length, error = transfer->status, len = transfer->length; @@ -95,7 +95,7 @@ static void async_read_callback(struct libusb_transfer *transfer) /* Receive data from the given ep and compare with expected */ static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct libusb_device_handle *udev = idev->udev; struct vfs_dev_t *vdev = idev->priv; @@ -120,7 +120,7 @@ static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len) static void async_abort_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); int transferred = transfer->actual_length, error = transfer->status; int ep = transfer->endpoint; @@ -143,13 +143,13 @@ static void async_abort_callback(struct libusb_transfer *transfer) fp_warn("Endpoint %d had extra %d bytes", ep - 0x80, transferred); - fpi_ssm_jump_to_state(ssm, ssm->cur_state); + fpi_ssm_jump_to_state(ssm, fpi_ssm_get_cur_state(ssm)); } /* Receive data from the given ep and compare with expected */ static void async_abort(struct fpi_ssm *ssm, int ep) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct libusb_device_handle *udev = idev->udev; struct vfs_dev_t *vdev = idev->priv; @@ -281,12 +281,12 @@ static void submit_image(struct fp_img_dev *idev) /* SSM loop for clear_ep2 */ static void clear_ep2_ssm(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); short result; char command04 = 0x04; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case SUBSM1_COMMAND_04: async_write(ssm, &command04, sizeof(command04)); break; @@ -309,23 +309,23 @@ static void clear_ep2_ssm(struct fpi_ssm *ssm) /* Send command to clear EP2 */ static void clear_ep2(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct fpi_ssm *subsm = fpi_ssm_new(idev->dev, clear_ep2_ssm, SUBSM1_STATES); - subsm->priv = idev; + fpi_ssm_set_user_data(subsm, idev); fpi_ssm_start_subsm(ssm, subsm); } static void send_control_packet_ssm(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct vfs_dev_t *vdev = idev->priv; short result; unsigned char *commit_result = NULL; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case SUBSM2_SEND_CONTROL: async_write(ssm, vdev->control_packet, VFS_CONTROL_PACKET_SIZE); break; @@ -387,11 +387,11 @@ static void send_control_packet_ssm(struct fpi_ssm *ssm) /* Send device state control packet */ static void send_control_packet(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct fpi_ssm *subsm = fpi_ssm_new(idev->dev, send_control_packet_ssm, SUBSM2_STATES); - subsm->priv = idev; + fpi_ssm_set_user_data(subsm, idev); fpi_ssm_start_subsm(ssm, subsm); } @@ -407,7 +407,7 @@ static void clear_data(struct vfs_dev_t *vdev) static void interrupt_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct vfs_dev_t *vdev = idev->priv; char *interrupt = vdev->interrupt; @@ -467,7 +467,7 @@ static void interrupt_callback(struct libusb_transfer *transfer) static void receive_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct vfs_dev_t *vdev = idev->priv; int transferred = transfer->actual_length, error = transfer->status; @@ -487,7 +487,7 @@ static void receive_callback(struct libusb_transfer *transfer) vdev->bytes += transferred; /* We need more data */ - fpi_ssm_jump_to_state(ssm, ssm->cur_state); + fpi_ssm_jump_to_state(ssm, fpi_ssm_get_cur_state(ssm)); } } @@ -495,12 +495,12 @@ static void receive_callback(struct libusb_transfer *transfer) static void wait_interrupt(void *data) { struct fpi_ssm *ssm = data; - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct vfs_dev_t *vdev = idev->priv; /* Keep sleeping while this flag is on */ if (vdev->wait_interrupt) - fpi_ssm_jump_to_state(ssm, ssm->cur_state); + fpi_ssm_jump_to_state(ssm, fpi_ssm_get_cur_state(ssm)); } /* SSM stub to prepare device to another scan after orange light was on */ @@ -520,11 +520,11 @@ static void scan_completed(void *data) /* Main SSM loop */ static void activate_ssm(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct libusb_device_handle *udev = idev->udev; struct vfs_dev_t *vdev = idev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case SSM_INITIAL_ABORT_1: async_abort(ssm, 1); break; @@ -673,7 +673,7 @@ static void activate_ssm(struct fpi_ssm *ssm) /* Callback for dev_activate ssm */ static void dev_activate_callback(struct fpi_ssm *ssm) { - struct fp_img_dev *idev = ssm->priv; + struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct vfs_dev_t *vdev = idev->priv; vdev->ssm_active = 0; @@ -692,7 +692,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) vdev->ssm_active = 1; struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, activate_ssm, SSM_STATES); - ssm->priv = idev; + fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, dev_activate_callback); return 0; } @@ -716,7 +716,7 @@ static void dev_deactivate(struct fp_img_dev *idev) static void dev_open_callback(struct fpi_ssm *ssm) { /* Notify open complete */ - fpi_imgdev_open_complete((struct fp_img_dev *)ssm->priv, 0); + fpi_imgdev_open_complete(fpi_ssm_get_user_data(ssm), 0); fpi_ssm_free(ssm); } @@ -737,7 +737,7 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) /* Clearing previous device state */ struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, activate_ssm, SSM_STATES); - ssm->priv = idev; + fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, dev_open_callback); return 0; } diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 7c39a649..7e0a6829 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -200,7 +200,7 @@ static int result_code(struct fp_img_dev *dev, int result) static void async_send_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Cleanup transfer */ @@ -244,7 +244,7 @@ out: /* Submit asynchronous send */ static void async_send(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; int r; @@ -284,7 +284,7 @@ static void async_send(struct fpi_ssm *ssm) static void async_recv_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Cleanup transfer */ @@ -331,7 +331,7 @@ out: /* Submit asynchronous recv */ static void async_recv(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; int r; @@ -368,7 +368,7 @@ static void async_load(struct fpi_ssm *ssm); static void async_load_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Cleanup transfer */ @@ -432,7 +432,7 @@ out: /* Submit asynchronous load */ static void async_load(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; unsigned char *buffer; int r; @@ -471,7 +471,7 @@ static void async_load(struct fpi_ssm *ssm) static void async_sleep_cb(void *data) { struct fpi_ssm *ssm = data; - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Cleanup timeout */ @@ -483,7 +483,7 @@ static void async_sleep_cb(void *data) /* Submit asynchronous sleep */ static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Add timeout */ @@ -509,7 +509,7 @@ enum /* Exec swap sequential state machine */ static void m_swap_state(struct fpi_ssm *ssm) { - switch (ssm->cur_state) + switch (fpi_ssm_get_cur_state(ssm)) { case M_SWAP_SEND: /* Send data */ @@ -526,7 +526,7 @@ static void m_swap_state(struct fpi_ssm *ssm) /* Start swap sequential state machine */ static void m_swap(struct fpi_ssm *ssm, unsigned char *data, size_t length) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; struct fpi_ssm *subsm; @@ -537,7 +537,7 @@ static void m_swap(struct fpi_ssm *ssm, unsigned char *data, size_t length) /* Start swap ssm */ subsm = fpi_ssm_new(dev->dev, m_swap_state, M_SWAP_NUM_STATES); - subsm->priv = dev; + fpi_ssm_set_user_data(subsm, dev); fpi_ssm_start_subsm(ssm, subsm); } @@ -625,7 +625,7 @@ static void vfs_get_finger_state(struct fpi_ssm *ssm) /* Load raw image from reader */ static void vfs_img_load(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; G_DEBUG_HERE(); @@ -756,7 +756,7 @@ static void img_copy(struct vfs101_dev *vdev, struct fp_img *img) /* Extract fingerpint image from raw data */ static void img_extract(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; struct fp_img *img; @@ -914,7 +914,7 @@ enum /* Exec loop sequential state machine */ static void m_loop_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Check action state */ @@ -925,7 +925,7 @@ static void m_loop_state(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) + switch (fpi_ssm_get_cur_state(ssm)) { case M_LOOP_0_GET_PRINT: /* Send get print command to the reader */ @@ -1178,7 +1178,7 @@ enum /* Exec init sequential state machine */ static void m_init_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; /* Check action state */ @@ -1189,7 +1189,7 @@ static void m_init_state(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) + switch (fpi_ssm_get_cur_state(ssm)) { case M_INIT_0_RECV_DIRTY: /* Recv eventualy dirty data */ @@ -1419,18 +1419,18 @@ static void m_init_state(struct fpi_ssm *ssm) /* Complete init sequential state machine */ static void m_init_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs101_dev *vdev = dev->priv; struct fpi_ssm *ssm_loop; - if (!ssm->error && vdev->active) + if (!fpi_ssm_get_error(ssm) && vdev->active) { /* Notify activate complete */ fpi_imgdev_activate_complete(dev, 0); /* Start loop ssm */ ssm_loop = fpi_ssm_new(dev->dev, m_loop_state, M_LOOP_NUM_STATES); - ssm_loop->priv = dev; + fpi_ssm_set_user_data(ssm_loop, dev); fpi_ssm_start(ssm_loop, m_loop_complete); } @@ -1465,7 +1465,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) /* Start init ssm */ ssm = fpi_ssm_new(dev->dev, m_init_state, M_INIT_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, m_init_complete); return 0; diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 6be8a6ff..86c9e600 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -37,7 +37,7 @@ static void async_sleep_cb(void *data) /* Submit asynchronous sleep */ static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct fpi_timeout *timeout; /* Add timeout */ @@ -53,7 +53,7 @@ static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) static int submit_image(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); vfs301_dev_t *vdev = dev->priv; int height; struct fp_img *img; @@ -105,10 +105,10 @@ enum /* Exec loop sequential state machine */ static void m_loop_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); vfs301_dev_t *vdev = dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case M_REQUEST_PRINT: vfs301_proto_request_fingerprint(dev->udev, vdev); fpi_ssm_next_state(ssm); @@ -170,10 +170,10 @@ static void m_loop_complete(struct fpi_ssm *ssm) /* Exec init sequential state machine */ static void m_init_state(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); vfs301_dev_t *vdev = dev->priv; - g_assert(ssm->cur_state == 0); + g_assert(fpi_ssm_get_cur_state(ssm) == 0); vfs301_proto_init(dev->udev, vdev); @@ -183,16 +183,16 @@ static void m_init_state(struct fpi_ssm *ssm) /* Complete init sequential state machine */ static void m_init_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct fpi_ssm *ssm_loop; - if (!ssm->error) { + if (!fpi_ssm_get_error(ssm)) { /* Notify activate complete */ fpi_imgdev_activate_complete(dev, 0); /* Start loop ssm */ ssm_loop = fpi_ssm_new(dev->dev, m_loop_state, M_LOOP_NUM_STATES); - ssm_loop->priv = dev; + fpi_ssm_set_user_data(ssm_loop, dev); fpi_ssm_start(ssm_loop, m_loop_complete); } @@ -207,7 +207,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) /* Start init ssm */ ssm = fpi_ssm_new(dev->dev, m_init_state, 1); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, m_init_complete); return 0; diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index be66137b..4d198223 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -76,17 +76,17 @@ static void start_scan(struct fp_img_dev *dev); static void async_send_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct usbexchange_data *data = (struct usbexchange_data *)ssm->priv; + struct usbexchange_data *data = fpi_ssm_get_user_data(ssm); struct usb_action *action; - if (ssm->cur_state >= data->stepcount) { + if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) { fp_err("Radiation detected!"); fpi_imgdev_session_error(data->device, -EINVAL); fpi_ssm_mark_aborted(ssm, -EINVAL); goto out; } - action = &data->actions[ssm->cur_state]; + action = &data->actions[fpi_ssm_get_cur_state(ssm)]; if (action->type != ACTION_SEND) { fp_err("Radiation detected!"); fpi_imgdev_session_error(data->device, -EINVAL); @@ -120,7 +120,7 @@ out: static void async_recv_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; - struct usbexchange_data *data = (struct usbexchange_data *)ssm->priv; + struct usbexchange_data *data = fpi_ssm_get_user_data(ssm); struct usb_action *action; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -131,14 +131,14 @@ static void async_recv_cb(struct libusb_transfer *transfer) goto out; } - if (ssm->cur_state >= data->stepcount) { + if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) { fp_err("Radiation detected!"); fpi_imgdev_session_error(data->device, -EINVAL); fpi_ssm_mark_aborted(ssm, -EINVAL); goto out; } - action = &data->actions[ssm->cur_state]; + action = &data->actions[fpi_ssm_get_cur_state(ssm)]; if (action->type != ACTION_RECEIVE) { fp_err("Radiation detected!"); fpi_imgdev_session_error(data->device, -EINVAL); @@ -173,16 +173,16 @@ out: static void usbexchange_loop(struct fpi_ssm *ssm) { - struct usbexchange_data *data = (struct usbexchange_data *)ssm->priv; - if (ssm->cur_state >= data->stepcount) { + struct usbexchange_data *data = fpi_ssm_get_user_data(ssm); + if (fpi_ssm_get_cur_state(ssm) >= data->stepcount) { fp_err("Bug detected: state %d out of range, only %d steps", - ssm->cur_state, data->stepcount); + fpi_ssm_get_cur_state(ssm), data->stepcount); fpi_imgdev_session_error(data->device, -EINVAL); fpi_ssm_mark_aborted(ssm, -EINVAL); return; } - struct usb_action *action = &data->actions[ssm->cur_state]; + struct usb_action *action = &data->actions[fpi_ssm_get_cur_state(ssm)]; struct libusb_transfer *transfer; int ret = -EINVAL; @@ -239,7 +239,7 @@ static void usb_exchange_async(struct fpi_ssm *ssm, struct fpi_ssm *subsm = fpi_ssm_new(data->device->dev, usbexchange_loop, data->stepcount); - subsm->priv = data; + fpi_ssm_set_user_data(subsm, data); fpi_ssm_start_subsm(ssm, subsm); } @@ -397,7 +397,7 @@ static int process_chunk(struct vfs5011_data *data, int transferred) void submit_image(struct fpi_ssm *ssm, struct vfs5011_data *data) { - struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct fp_img *img; data->rows = g_slist_reverse(data->rows); @@ -415,7 +415,7 @@ void submit_image(struct fpi_ssm *ssm, struct vfs5011_data *data) static void chunk_capture_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = (struct fpi_ssm *)transfer->user_data; - struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) || @@ -659,12 +659,12 @@ static void activate_loop(struct fpi_ssm *ssm) { enum {READ_TIMEOUT = 0}; - struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; int r; struct fpi_timeout *timeout; - fp_dbg("main_loop: state %d", ssm->cur_state); + fp_dbg("main_loop: state %d", fpi_ssm_get_cur_state(ssm)); if (data->deactivating) { fp_dbg("deactivating, marking completed"); @@ -672,7 +672,7 @@ static void activate_loop(struct fpi_ssm *ssm) return; } - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEV_ACTIVATE_REQUEST_FPRINT: data->init_sequence.stepcount = array_n_elements(vfs5011_initiate_capture); @@ -732,9 +732,9 @@ static void activate_loop(struct fpi_ssm *ssm) static void activate_loop_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; - int r = ssm->error; + int r = fpi_ssm_get_error(ssm); fp_dbg("finishing"); if (data->init_sequence.receive_buf != NULL) @@ -760,10 +760,10 @@ static void activate_loop_complete(struct fpi_ssm *ssm) static void open_loop(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; - switch (ssm->cur_state) { + switch (fpi_ssm_get_cur_state(ssm)) { case DEV_OPEN_START: data->init_sequence.stepcount = array_n_elements(vfs5011_initialization); @@ -779,7 +779,7 @@ static void open_loop(struct fpi_ssm *ssm) static void open_loop_complete(struct fpi_ssm *ssm) { - struct fp_img_dev *dev = (struct fp_img_dev *)ssm->priv; + struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; g_free(data->init_sequence.receive_buf); @@ -814,7 +814,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) struct fpi_ssm *ssm; ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, open_loop_complete); return 0; @@ -840,7 +840,7 @@ static void start_scan(struct fp_img_dev *dev) data->loop_running = TRUE; fp_dbg("creating ssm"); ssm = fpi_ssm_new(dev->dev, activate_loop, DEV_ACTIVATE_NUM_STATES); - ssm->priv = dev; + fpi_ssm_set_user_data(ssm, dev); fp_dbg("starting ssm"); fpi_ssm_start(ssm, activate_loop_complete); fp_dbg("ssm done, getting out"); diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index a5c89bd4..f7dfee90 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -354,18 +354,6 @@ typedef void (*ssm_handler_fn)(struct fpi_ssm *ssm); /* sequential state machine: state machine that iterates sequentially over * a predefined series of states. can be aborted by either completion or * abortion error conditions. */ -struct fpi_ssm { - struct fp_dev *dev; - struct fpi_ssm *parentsm; - void *priv; - int nr_states; - int cur_state; - gboolean completed; - int error; - ssm_completed_fn callback; - ssm_handler_fn handler; -}; - /* for library and drivers */ struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, @@ -380,6 +368,12 @@ void fpi_ssm_next_state(struct fpi_ssm *machine); void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state); void fpi_ssm_mark_completed(struct fpi_ssm *machine); void fpi_ssm_mark_aborted(struct fpi_ssm *machine, int error); +struct fp_dev *fpi_ssm_get_dev(struct fpi_ssm *machine); +void fpi_ssm_set_user_data(struct fpi_ssm *machine, + void *user_data); +void *fpi_ssm_get_user_data(struct fpi_ssm *machine); +int fpi_ssm_get_error(struct fpi_ssm *machine); +int fpi_ssm_get_cur_state(struct fpi_ssm *machine); void fpi_drvcb_open_complete(struct fp_dev *dev, int status); void fpi_drvcb_close_complete(struct fp_dev *dev); diff --git a/libfprint/drv.c b/libfprint/drv.c index 719417d9..d5507453 100644 --- a/libfprint/drv.c +++ b/libfprint/drv.c @@ -83,6 +83,25 @@ struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, return machine; } +struct fp_dev * +fpi_ssm_get_dev(struct fpi_ssm *machine) +{ + return machine->dev; +} + +void +fpi_ssm_set_user_data(struct fpi_ssm *machine, + void *user_data) +{ + machine->priv = user_data; +} + +void * +fpi_ssm_get_user_data(struct fpi_ssm *machine) +{ + return machine->priv; +} + /* Free a ssm */ void fpi_ssm_free(struct fpi_ssm *machine) { @@ -169,3 +188,12 @@ void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state) __ssm_call_handler(machine); } +int fpi_ssm_get_cur_state(struct fpi_ssm *machine) +{ + return machine->cur_state; +} + +int fpi_ssm_get_error(struct fpi_ssm *machine) +{ + return machine->error; +} From 00637c4f0b638b7b48b98e74aebeaa7d9de6429f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:46:18 +0200 Subject: [PATCH 101/141] lib: Remove fprint_get_drivers() from drivers API Drivers don't need to get a list of drivers. --- libfprint/drivers_api.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index f7dfee90..98ac0315 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -71,8 +71,6 @@ enum fp_dev_state { DEV_STATE_CAPTURE_STOPPING, }; -struct fp_driver **fprint_get_drivers (void); - struct fp_dev { struct fp_driver *drv; libusb_device_handle *udev; From d15282bff1caa51c1496f6258fa141ae54add125 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 12:48:20 +0200 Subject: [PATCH 102/141] lib: Remove minutiae utils from internal header It's only used by drivers. --- libfprint/fp_internal.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 6b74c4ac..57d1e351 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -418,9 +418,5 @@ void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img); void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result); void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error); -/* utils */ -int fpi_std_sq_dev(const unsigned char *buf, int size); -int fpi_mean_sq_diff_norm(unsigned char *buf1, unsigned char *buf2, int size); - #endif From d83d92adf2aa8df121802273eb813552260562db Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 14:33:49 +0200 Subject: [PATCH 103/141] lib: Make fp_dev structure opaque --- libfprint/core.c | 44 ++++++++++++++++++++++++++++++ libfprint/drivers/aes1610.c | 2 +- libfprint/drivers/aes2501.c | 2 +- libfprint/drivers/elan.c | 2 +- libfprint/drivers/upeksonly.c | 3 +- libfprint/drivers/upektc_img.c | 2 +- libfprint/drivers/upekts.c | 48 ++++++++++++++++---------------- libfprint/drivers/vfs101.c | 2 +- libfprint/drivers_api.h | 50 ++++++---------------------------- 9 files changed, 84 insertions(+), 71 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index 280fe65a..a5daa300 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -542,6 +542,50 @@ API_EXPORTED int fp_dev_supports_dscv_print(struct fp_dev *dev, 0, print->driver_id, print->devtype, 0); } +libusb_device_handle * +fpi_dev_get_usb_dev(struct fp_dev *dev) +{ + return dev->udev; +} + +void * +fpi_dev_get_user_data (struct fp_dev *dev) +{ + return dev->priv; +} + +void +fpi_dev_set_user_data (struct fp_dev *dev, + void *user_data) +{ + dev->priv = user_data; +} + +int +fpi_dev_get_nr_enroll_stages(struct fp_dev *dev) +{ + return dev->nr_enroll_stages; +} + +void +fpi_dev_set_nr_enroll_stages(struct fp_dev *dev, + int nr_enroll_stages) +{ + dev->nr_enroll_stages = nr_enroll_stages; +} + +struct fp_print_data * +fpi_dev_get_verify_data(struct fp_dev *dev) +{ + return dev->verify_data; +} + +enum fp_dev_state +fpi_dev_get_dev_state(struct fp_dev *dev) +{ + return dev->state; +} + /** * fp_driver_get_name: * @drv: the driver diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index 3801eb19..c07a69be 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -140,7 +140,7 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) data = g_malloc(bytes); dev = fpi_ssm_get_dev(ssm); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, bytes, + libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_IN, data, bytes, generic_ignore_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 84def287..83c3a4ff 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -218,7 +218,7 @@ static void generic_read_ignore_data(struct fpi_ssm *ssm, size_t bytes) } data = g_malloc(bytes); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, bytes, + libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_IN, data, bytes, generic_ignore_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index 640641c3..f03b5e39 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -406,7 +406,7 @@ static void capture_complete(struct fpi_ssm *ssm) * completed, so we need to keep feeding it images till it's had enough. * But after that it can't finalize enrollemnt until this callback exits. * That's why we schedule elan_capture instead of running it directly. */ - if (dev->dev->state == DEV_STATE_ENROLLING + if (fpi_dev_get_dev_state(dev->dev) == DEV_STATE_ENROLLING && !fpi_timeout_add(10, elan_capture_async, dev)) fpi_imgdev_session_error(dev, -ETIME); diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 85311856..72a9318c 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -591,7 +591,8 @@ static void sm_write_regs(struct fpi_ssm *ssm, data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, 0x40, 0x0c, 0, 0, 1); dev = fpi_ssm_get_dev(ssm); - libusb_fill_control_transfer(wrdata->transfer, dev->udev, data, + libusb_fill_control_transfer(wrdata->transfer, + fpi_dev_get_usb_dev(dev), data, write_regs_cb, wrdata, CTRL_TIMEOUT); wrdata->transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 914aa80b..96a0b492 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -568,7 +568,7 @@ static void activate_run_state(struct fpi_ssm *ssm) data = g_malloc0(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1); - libusb_fill_control_transfer(transfer, dev->udev, data, + libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(dev), data, init_reqs_ctrl_cb, ssm, CTRL_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index ed714004..a2bf971a 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -166,7 +166,7 @@ static struct libusb_transfer *alloc_send_cmd_transfer(struct fp_dev *dev, buf[urblen - 2] = crc >> 8; buf[urblen - 1] = crc & 0xff; - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, buf, urblen, + libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(dev), EP_OUT, buf, urblen, callback, user_data, TIMEOUT); return transfer; } @@ -178,7 +178,7 @@ static struct libusb_transfer *alloc_send_cmd28_transfer(struct fp_dev *dev, uint16_t _innerlen = innerlen; size_t len = innerlen + 6; unsigned char *buf = g_malloc0(len); - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); uint8_t seq = upekdev->seq + CMD_SEQ_INCREMENT; struct libusb_transfer *ret; @@ -417,7 +417,7 @@ static void read_msg_cb(struct libusb_transfer *transfer) fp_dbg("didn't fit in buffer, need to extend by %d bytes", needed); data = g_realloc((gpointer) data, MSG_READ_BUF_SIZE + needed); - libusb_fill_bulk_transfer(etransfer, udata->dev->udev, EP_IN, + libusb_fill_bulk_transfer(etransfer, fpi_dev_get_usb_dev(udata->dev), EP_IN, data + MSG_READ_BUF_SIZE, needed, read_msg_extend_cb, udata, TIMEOUT); @@ -456,7 +456,7 @@ static int __read_msg_async(struct read_msg_data *udata) return -ENOMEM; } - libusb_fill_bulk_transfer(transfer, udata->dev->udev, EP_IN, buf, + libusb_fill_bulk_transfer(transfer, fpi_dev_get_usb_dev(udata->dev), EP_IN, buf, MSG_READ_BUF_SIZE, read_msg_cb, udata, TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -530,7 +530,7 @@ static void initsm_read_msg_response_cb(struct fpi_ssm *ssm, unsigned char expect_subcmd, unsigned char subcmd) { struct fp_dev *dev = fpi_ssm_get_dev(ssm); - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); if (status != READ_MSG_RESPONSE) { fp_err("expected response, got %d seq=%x in state %d", status, seq, @@ -594,7 +594,7 @@ static void initsm_read_msg_cmd_cb(struct fpi_ssm *ssm, enum read_msg_status status, uint8_t expect_seq, uint8_t seq) { struct fp_dev *dev = fpi_ssm_get_dev(ssm); - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); if (status == READ_MSG_ERROR) { fpi_ssm_mark_aborted(ssm, -1); @@ -693,7 +693,7 @@ static void initsm_send_msg28_handler(struct fpi_ssm *ssm, static void initsm_run_state(struct fpi_ssm *ssm) { struct fp_dev *dev = fpi_ssm_get_dev(ssm); - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); struct libusb_transfer *transfer; int r; @@ -710,7 +710,7 @@ static void initsm_run_state(struct fpi_ssm *ssm) data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x0c, 0x100, 0x0400, 1); - libusb_fill_control_transfer(transfer, dev->udev, data, + libusb_fill_control_transfer(transfer, fpi_dev_get_usb_dev(dev), data, ctrl400_cb, ssm, TIMEOUT); r = libusb_submit_transfer(transfer); @@ -805,7 +805,7 @@ static void read_msg01_cb(struct fp_dev *dev, enum read_msg_status status, void *user_data) { struct fpi_ssm *ssm = user_data; - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); if (status == READ_MSG_ERROR) { fpi_ssm_mark_aborted(ssm, -1); @@ -867,7 +867,7 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data) struct upekts_dev *upekdev = NULL; int r; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_dev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; @@ -875,8 +875,8 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data) upekdev = g_malloc(sizeof(*upekdev)); upekdev->seq = 0xf0; /* incremented to 0x00 before first cmd */ - dev->priv = upekdev; - dev->nr_enroll_stages = 3; + fpi_dev_set_user_data(dev, upekdev); + fpi_dev_set_nr_enroll_stages(dev, 3); fpi_drvcb_open_complete(dev, 0); return 0; @@ -884,8 +884,10 @@ static int dev_init(struct fp_dev *dev, unsigned long driver_data) static void dev_exit(struct fp_dev *dev) { - libusb_release_interface(dev->udev, 0); - g_free(dev->priv); + void *user_data; + libusb_release_interface(fpi_dev_get_usb_dev(dev), 0); + user_data = fpi_dev_get_user_data(dev); + g_free(user_data); fpi_drvcb_close_complete(dev); } @@ -936,7 +938,7 @@ static void enroll_start_sm_cb_msg28(struct fp_dev *dev, enum read_msg_status status, uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, void *user_data) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); struct fpi_ssm *ssm = user_data; if (status != READ_MSG_RESPONSE) { @@ -999,7 +1001,7 @@ static void enroll_iterate(struct fp_dev *dev); static void e_handle_resp00(struct fp_dev *dev, unsigned char *data, size_t data_len) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); unsigned char status; int result = 0; @@ -1161,7 +1163,7 @@ static void enroll_started(struct fpi_ssm *ssm) static int enroll_start(struct fp_dev *dev) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); /* do_init state machine first */ struct fpi_ssm *ssm = fpi_ssm_new(dev, enroll_start_sm_run_state, @@ -1249,7 +1251,7 @@ static void verify_start_sm_run_state(struct fpi_ssm *ssm) fpi_ssm_start(initsm, verify_start_sm_cb_initsm); break; case VERIFY_INIT: ; - struct fp_print_data *print = dev->verify_data; + struct fp_print_data *print = fpi_dev_get_verify_data(dev); struct fp_print_data_item *item = print->prints->data; size_t data_len = sizeof(verify_hdr) + item->length; unsigned char *data = g_malloc(data_len); @@ -1355,7 +1357,7 @@ static void verify_rd2800_cb(struct fp_dev *dev, enum read_msg_status msgstat, uint8_t seq, unsigned char subcmd, unsigned char *data, size_t data_len, void *user_data) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); if (msgstat != READ_MSG_RESPONSE) { fp_err("expected response, got %d seq=%x", msgstat, seq); @@ -1394,7 +1396,7 @@ static void verify_wr2800_cb(struct libusb_transfer *transfer) static void verify_iterate(struct fp_dev *dev) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); if (upekdev->stop_verify) { do_verify_stop(dev); @@ -1430,7 +1432,7 @@ static void verify_iterate(struct fp_dev *dev) static void verify_started(struct fpi_ssm *ssm) { struct fp_dev *dev = fpi_ssm_get_dev(ssm); - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); fpi_drvcb_verify_started(dev, fpi_ssm_get_error(ssm)); if (!fpi_ssm_get_error(ssm)) { @@ -1443,7 +1445,7 @@ static void verify_started(struct fpi_ssm *ssm) static int verify_start(struct fp_dev *dev) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); struct fpi_ssm *ssm = fpi_ssm_new(dev, verify_start_sm_run_state, VERIFY_NUM_STATES); upekdev->stop_verify = FALSE; @@ -1453,7 +1455,7 @@ static int verify_start(struct fp_dev *dev) static int verify_stop(struct fp_dev *dev, gboolean iterating) { - struct upekts_dev *upekdev = dev->priv; + struct upekts_dev *upekdev = fpi_dev_get_user_data(dev); if (!iterating) do_verify_stop(dev); diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 7e0a6829..764628ae 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -647,7 +647,7 @@ static int action_completed(struct fp_img_dev *dev) struct vfs101_dev *vdev = dev->priv; if ((dev->action == IMG_ACTION_ENROLL) && - (vdev->enroll_stage < dev->dev->nr_enroll_stages)) + (vdev->enroll_stage < fpi_dev_get_nr_enroll_stages(dev->dev))) /* Enroll not completed, return false */ return FALSE; diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index 98ac0315..0bbfde86 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -71,48 +71,14 @@ enum fp_dev_state { DEV_STATE_CAPTURE_STOPPING, }; -struct fp_dev { - struct fp_driver *drv; - libusb_device_handle *udev; - uint32_t devtype; - void *priv; - - int nr_enroll_stages; - - /* read-only to drivers */ - struct fp_print_data *verify_data; - - /* drivers should not mess with any of the below */ - enum fp_dev_state state; - int __enroll_stage; - int unconditional_capture; - - /* async I/O callbacks and data */ - /* FIXME: convert this to generic state operational data mechanism? */ - fp_dev_open_cb open_cb; - void *open_cb_data; - fp_operation_stop_cb close_cb; - void *close_cb_data; - fp_enroll_stage_cb enroll_stage_cb; - void *enroll_stage_cb_data; - fp_operation_stop_cb enroll_stop_cb; - void *enroll_stop_cb_data; - fp_img_operation_cb verify_cb; - void *verify_cb_data; - fp_operation_stop_cb verify_stop_cb; - void *verify_stop_cb_data; - fp_identify_cb identify_cb; - void *identify_cb_data; - fp_operation_stop_cb identify_stop_cb; - void *identify_stop_cb_data; - fp_img_operation_cb capture_cb; - void *capture_cb_data; - fp_operation_stop_cb capture_stop_cb; - void *capture_stop_cb_data; - - /* FIXME: better place to put this? */ - struct fp_print_data **identify_gallery; -}; +struct fp_dev; +libusb_device_handle *fpi_dev_get_usb_dev(struct fp_dev *dev); +void *fpi_dev_get_user_data (struct fp_dev *dev); +void fpi_dev_set_user_data (struct fp_dev *dev, void *user_data); +int fpi_dev_get_nr_enroll_stages(struct fp_dev *dev); +void fpi_dev_set_nr_enroll_stages(struct fp_dev *dev, int nr_enroll_stages); +struct fp_print_data *fpi_dev_get_verify_data(struct fp_dev *dev); +enum fp_dev_state fpi_dev_get_dev_state(struct fp_dev *dev); enum fp_imgdev_state { IMGDEV_STATE_INACTIVE, From f40f231a63cfc0f319fcc4808c90c47f4592bb89 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:06:02 +0200 Subject: [PATCH 104/141] lib: Make fp_img_dev structure opaque --- libfprint/drivers/aes1610.c | 36 ++++++++------ libfprint/drivers/aes1660.c | 9 ++-- libfprint/drivers/aes2501.c | 39 ++++++++------- libfprint/drivers/aes2550.c | 50 ++++++++++--------- libfprint/drivers/aes2660.c | 10 ++-- libfprint/drivers/aes3500.c | 9 ++-- libfprint/drivers/aes3k.c | 10 ++-- libfprint/drivers/aes4000.c | 9 ++-- libfprint/drivers/aesx660.c | 38 +++++++------- libfprint/drivers/elan.c | 57 ++++++++++----------- libfprint/drivers/etes603.c | 58 +++++++++++----------- libfprint/drivers/fdu2000.c | 28 +++++------ libfprint/drivers/upeksonly.c | 91 ++++++++++++++++++---------------- libfprint/drivers/upektc.c | 53 ++++++++++---------- libfprint/drivers/upektc_img.c | 45 +++++++++-------- libfprint/drivers/uru4000.c | 62 +++++++++++------------ libfprint/drivers/vcom5s.c | 35 +++++++------ libfprint/drivers/vfs0050.c | 55 ++++++++++---------- libfprint/drivers/vfs101.c | 77 ++++++++++++++-------------- libfprint/drivers/vfs301.c | 33 ++++++------ libfprint/drivers/vfs5011.c | 52 ++++++++++++------- libfprint/drivers_api.h | 28 ++++------- libfprint/img.c | 50 +++++++++++++++++++ 23 files changed, 518 insertions(+), 416 deletions(-) diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c index c07a69be..f307a3bc 100644 --- a/libfprint/drivers/aes1610.c +++ b/libfprint/drivers/aes1610.c @@ -233,7 +233,7 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, void *user_da } data = g_malloc(19); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 19, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 19, finger_det_data_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -247,7 +247,7 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, void *user_da static void start_finger_detection(struct fp_img_dev *dev) { - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); if (aesdev->deactivating) { complete_deactivation(dev); @@ -559,7 +559,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) unsigned char *stripdata; struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; int sum, i; @@ -646,7 +646,7 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); int r; switch (fpi_ssm_get_cur_state(ssm)) { @@ -677,7 +677,7 @@ static void capture_run_state(struct fpi_ssm *ssm) } data = g_malloc(665); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 665, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 665, capture_read_strip_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -693,7 +693,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); if (aesdev->deactivating) @@ -707,7 +707,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; if (aesdev->deactivating) { @@ -715,7 +715,7 @@ static void start_capture(struct fp_img_dev *dev) return; } - ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); @@ -766,8 +766,8 @@ static void activate_sm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct aes1610_dev *aesdev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); aesdev->read_regs_retry_count = 0; @@ -777,7 +777,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); /* FIXME: audit cancellation points, probably need more, specifically * in error handling paths? */ aesdev->deactivating = TRUE; @@ -785,7 +785,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { - struct aes1610_dev *aesdev = dev->priv; + struct aes1610_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); /* FIXME: if we're in the middle of a scan, we should cancel the scan. @@ -803,22 +803,26 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { /* FIXME check endpoints */ int r; + struct aes1610_dev *aesdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = g_malloc0(sizeof(struct aes1610_dev)); + aesdev = g_malloc0(sizeof(struct aes1610_dev)); + fpi_imgdev_set_user_data(dev, aesdev); fpi_imgdev_open_complete(dev, 0); return 0; } static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + struct aes1610_dev *aesdev; + aesdev = fpi_imgdev_get_user_data(dev); + g_free(aesdev); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index e2aeeff1..c43ae517 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -40,13 +40,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; struct aesX660_dev *aesdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev)); + aesdev = g_malloc0(sizeof(struct aesX660_dev)); + fpi_imgdev_set_user_data(dev, aesdev); aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE); aesdev->init_seqs[0] = aes1660_init_1; aesdev->init_seqs_len[0] = array_n_elements(aes1660_init_1); @@ -63,10 +64,10 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); g_free(aesdev->buffer); g_free(aesdev); - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c index 83c3a4ff..87879a46 100644 --- a/libfprint/drivers/aes2501.c +++ b/libfprint/drivers/aes2501.c @@ -122,7 +122,7 @@ static void read_regs_rq_cb(struct fp_img_dev *dev, int result, void *user_data) } data = g_malloc(126); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 126, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 126, read_regs_data_cb, rdata, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -333,7 +333,7 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, } data = g_malloc(20); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 20, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 20, finger_det_data_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -346,7 +346,7 @@ static void finger_det_reqs_cb(struct fp_img_dev *dev, int result, static void start_finger_detection(struct fp_img_dev *dev) { - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); if (aesdev->deactivating) { @@ -438,7 +438,7 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer) unsigned char *stripdata; struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; int sum; int threshold; @@ -523,7 +523,7 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); int r; switch (fpi_ssm_get_cur_state(ssm)) { @@ -558,7 +558,7 @@ static void capture_run_state(struct fpi_ssm *ssm) } data = g_malloc(1705); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, 1705, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, 1705, capture_read_strip_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -574,7 +574,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); if (aesdev->deactivating) @@ -588,7 +588,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; if (aesdev->deactivating) { @@ -599,7 +599,7 @@ static void start_capture(struct fp_img_dev *dev) aesdev->no_finger_cnt = 0; /* Reset gain */ strip_scan_reqs[4].value = AES2501_ADREFHI_MAX_VALUE; - ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); @@ -714,7 +714,7 @@ void activate_read_regs_cb(struct fp_img_dev *dev, int status, unsigned char *regs, void *user_data) { struct fpi_ssm *ssm = user_data; - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); if (status != 0) { fpi_ssm_mark_aborted(ssm, status); @@ -804,8 +804,8 @@ static void activate_sm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct aes2501_dev *aesdev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); aesdev->read_regs_retry_count = 0; @@ -815,7 +815,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); /* FIXME: audit cancellation points, probably need more, specifically * in error handling paths? */ aesdev->deactivating = TRUE; @@ -823,7 +823,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { - struct aes2501_dev *aesdev = dev->priv; + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); /* FIXME: if we're in the middle of a scan, we should cancel the scan. @@ -840,22 +840,25 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { /* FIXME check endpoints */ int r; + struct aes2501_dev *aesdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = g_malloc0(sizeof(struct aes2501_dev)); + aesdev = g_malloc0(sizeof(struct aes2501_dev)); + fpi_imgdev_set_user_data(dev, aesdev); fpi_imgdev_open_complete(dev, 0); return 0; } static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + struct aes2501_dev *aesdev = fpi_imgdev_get_user_data(dev); + g_free(aesdev); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c index c6d25926..ab4acaab 100644 --- a/libfprint/drivers/aes2550.c +++ b/libfprint/drivers/aes2550.c @@ -133,7 +133,7 @@ static void finger_det_reqs_cb(struct libusb_transfer *t) /* 2 bytes of result */ data = g_malloc(AES2550_EP_IN_BUF_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE, finger_det_data_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -149,7 +149,7 @@ exit_free_transfer: static void start_finger_detection(struct fp_img_dev *dev) { int r; - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); struct libusb_transfer *transfer; G_DEBUG_HERE(); @@ -163,7 +163,7 @@ static void start_finger_detection(struct fp_img_dev *dev) fpi_imgdev_session_error(dev, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, finger_det_reqs, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, finger_det_reqs, sizeof(finger_det_reqs), finger_det_reqs_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -204,7 +204,7 @@ static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data) { unsigned char *stripdata; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); struct fpi_frame *stripe; int len; @@ -246,7 +246,7 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (transfer->length == transfer->actual_length) && @@ -274,7 +274,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; int r; @@ -336,7 +336,7 @@ static void capture_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, capture_reqs, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, capture_reqs, sizeof(capture_reqs), capture_reqs_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -356,7 +356,7 @@ static void capture_run_state(struct fpi_ssm *ssm) } data = g_malloc(AES2550_EP_IN_BUF_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE, capture_read_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -374,7 +374,7 @@ static void capture_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, capture_set_idle_reqs, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, capture_set_idle_reqs, sizeof(capture_set_idle_reqs), capture_set_idle_reqs_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -389,7 +389,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); fp_dbg("Capture completed"); if (aesdev->deactivating) @@ -403,7 +403,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; if (aesdev->deactivating) { @@ -412,7 +412,7 @@ static void start_capture(struct fp_img_dev *dev) } aesdev->heartbeat_cnt = 0; - ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); @@ -496,7 +496,7 @@ static void activate_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, init_reqs, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, init_reqs, sizeof(init_reqs), init_reqs_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -516,7 +516,7 @@ static void activate_run_state(struct fpi_ssm *ssm) } data = g_malloc(AES2550_EP_IN_BUF_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE, init_read_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -534,7 +534,7 @@ static void activate_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, calibrate_reqs, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, calibrate_reqs, sizeof(calibrate_reqs), init_reqs_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -554,7 +554,7 @@ static void activate_run_state(struct fpi_ssm *ssm) } data = g_malloc(AES2550_EP_IN_BUF_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, data, AES2550_EP_IN_BUF_SIZE, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, AES2550_EP_IN_BUF_SIZE, calibrate_read_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -581,7 +581,7 @@ static void activate_sm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_sm_complete); @@ -590,14 +590,14 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); aesdev->deactivating = TRUE; } static void complete_deactivation(struct fp_img_dev *dev) { - struct aes2550_dev *aesdev = dev->priv; + struct aes2550_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); aesdev->deactivating = FALSE; @@ -611,22 +611,26 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { /* TODO check that device has endpoints we're using */ int r; + struct aes2550_dev *aes2550_dev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = g_malloc0(sizeof(struct aes2550_dev)); + aes2550_dev = g_malloc0(sizeof(struct aes2550_dev)); + fpi_imgdev_set_user_data(dev, aes2550_dev); fpi_imgdev_open_complete(dev, 0); return 0; } static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + struct aes2550_dev *aesdev; + aesdev = fpi_imgdev_get_user_data(dev); + g_free(aesdev); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index 7979d7a9..d4b453aa 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -40,13 +40,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; struct aesX660_dev *aesdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev)); + aesdev = g_malloc0(sizeof(struct aesX660_dev)); + fpi_imgdev_set_user_data(dev, aesdev); aesdev->buffer = g_malloc0(AES2660_FRAME_SIZE + AESX660_HEADER_SIZE); /* No scaling for AES2660 */ aesdev->init_seqs[0] = aes2660_init_1; @@ -64,10 +65,11 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev; + aesdev = fpi_imgdev_get_user_data(dev); g_free(aesdev->buffer); g_free(aesdev); - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aes3500.c b/libfprint/drivers/aes3500.c index 8a16ebf2..5d32f8ab 100644 --- a/libfprint/drivers/aes3500.c +++ b/libfprint/drivers/aes3500.c @@ -122,13 +122,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; struct aes3k_dev *aesdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev)); + aesdev = g_malloc0(sizeof(struct aes3k_dev)); + fpi_imgdev_set_user_data(dev, aesdev); if (!aesdev) return -ENOMEM; @@ -147,9 +148,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - struct aes3k_dev *aesdev = dev->priv; + struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev); g_free(aesdev); - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c index 8f384fea..d64efda8 100644 --- a/libfprint/drivers/aes3k.c +++ b/libfprint/drivers/aes3k.c @@ -63,7 +63,7 @@ static void aes3k_assemble_image(unsigned char *input, size_t width, size_t heig static void img_cb(struct libusb_transfer *transfer) { struct fp_img_dev *dev = transfer->user_data; - struct aes3k_dev *aesdev = dev->priv; + struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *ptr = transfer->buffer; struct fp_img *tmp; struct fp_img *img; @@ -112,7 +112,7 @@ err: static void do_capture(struct fp_img_dev *dev) { - struct aes3k_dev *aesdev = dev->priv; + struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data; int r; @@ -123,7 +123,7 @@ static void do_capture(struct fp_img_dev *dev) } data = g_malloc(aesdev->data_buflen); - libusb_fill_bulk_transfer(aesdev->img_trf, dev->udev, EP_IN, data, + libusb_fill_bulk_transfer(aesdev->img_trf, fpi_imgdev_get_usb_dev(dev), EP_IN, data, aesdev->data_buflen, img_cb, dev, 0); r = libusb_submit_transfer(aesdev->img_trf); @@ -144,14 +144,14 @@ static void init_reqs_cb(struct fp_img_dev *dev, int result, void *user_data) int aes3k_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct aes3k_dev *aesdev = dev->priv; + struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev); aes_write_regv(dev, aesdev->init_reqs, aesdev->init_reqs_len, init_reqs_cb, NULL); return 0; } void aes3k_dev_deactivate(struct fp_img_dev *dev) { - struct aes3k_dev *aesdev = dev->priv; + struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev); /* FIXME: should wait for cancellation to complete before returning * from deactivation, otherwise app may legally exit before we've diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index 3a8beba1..c26dc64a 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -119,13 +119,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; struct aes3k_dev *aesdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - aesdev = dev->priv = g_malloc0(sizeof(struct aes3k_dev)); + aesdev = g_malloc0(sizeof(struct aes3k_dev)); + fpi_imgdev_set_user_data(dev, aesdev); if (!aesdev) return -ENOMEM; @@ -144,9 +145,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - struct aes3k_dev *aesdev = dev->priv; + struct aes3k_dev *aesdev = fpi_imgdev_get_user_data(dev); g_free(aesdev); - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c index 95e88492..e443e219 100644 --- a/libfprint/drivers/aesx660.c +++ b/libfprint/drivers/aesx660.c @@ -49,7 +49,7 @@ static void aesX660_send_cmd_timeout(struct fpi_ssm *ssm, const unsigned char *c return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, (unsigned char *)cmd, cmd_len, callback, ssm, timeout); r = libusb_submit_transfer(transfer); @@ -80,7 +80,7 @@ static void aesX660_read_response(struct fpi_ssm *ssm, size_t buf_len, } data = g_malloc(buf_len); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, data, buf_len, callback, ssm, BULK_TIMEOUT); @@ -145,7 +145,7 @@ static void finger_det_read_fd_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; aesdev->fd_data_transfer = NULL; @@ -198,7 +198,7 @@ static void finger_det_set_idle_cmd_cb(struct libusb_transfer *transfer) static void finger_det_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); int err = fpi_ssm_get_error(ssm); fp_dbg("Finger detection completed"); @@ -240,14 +240,14 @@ static void finger_det_run_state(struct fpi_ssm *ssm) static void start_finger_detection(struct fp_img_dev *dev) { struct fpi_ssm *ssm; - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); if (aesdev->deactivating) { complete_deactivation(dev); return; } - ssm = fpi_ssm_new(dev->dev, finger_det_run_state, FINGER_DET_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), finger_det_run_state, FINGER_DET_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, finger_det_sm_complete); } @@ -268,7 +268,7 @@ static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data) struct fpi_frame *stripe; unsigned char *stripdata; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); stripe = g_malloc(aesdev->assembling_ctx->frame_width * FRAME_HEIGHT / 2 + sizeof(struct fpi_frame)); /* 4 bpp */ stripdata = stripe->data; @@ -296,7 +296,7 @@ static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (transfer->length == transfer->actual_length)) { @@ -322,7 +322,7 @@ static void capture_read_stripe_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; int finger_missing = 0; size_t copied, actual_len = transfer->actual_length; @@ -374,7 +374,7 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_SEND_LED_CMD: @@ -403,7 +403,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); int err = fpi_ssm_get_error(ssm); fp_dbg("Capture completed"); @@ -419,7 +419,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; if (aesdev->deactivating) { @@ -427,7 +427,7 @@ static void start_capture(struct fp_img_dev *dev) return; } - ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); @@ -450,7 +450,7 @@ static void activate_read_id_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; if ((transfer->status != LIBUSB_TRANSFER_COMPLETED) || @@ -501,7 +501,7 @@ static void activate_read_init_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; fp_dbg("read_init_cb\n"); @@ -537,7 +537,7 @@ out: static void activate_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_SET_IDLE: @@ -594,7 +594,7 @@ static void activate_sm_complete(struct fpi_ssm *ssm) int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_sm_complete); @@ -603,7 +603,7 @@ int aesX660_dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) void aesX660_dev_deactivate(struct fp_img_dev *dev) { - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); if (aesdev->fd_data_transfer) libusb_cancel_transfer(aesdev->fd_data_transfer); @@ -613,7 +613,7 @@ void aesX660_dev_deactivate(struct fp_img_dev *dev) static void complete_deactivation(struct fp_img_dev *dev) { - struct aesX660_dev *aesdev = dev->priv; + struct aesX660_dev *aesdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); aesdev->deactivating = FALSE; diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c index f03b5e39..0ff16dcd 100644 --- a/libfprint/drivers/elan.c +++ b/libfprint/drivers/elan.c @@ -76,7 +76,7 @@ static void elan_dev_reset(struct elan_dev *elandev) static void elan_save_frame(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); unsigned char raw_height = elandev->frame_width; unsigned char raw_width = elandev->raw_frame_width; unsigned short *frame = @@ -137,7 +137,7 @@ static void elan_process_frame(unsigned short *raw_frame, GSList ** frames) static void elan_submit_image(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); GSList *frames = NULL; struct fp_img *img; @@ -162,7 +162,7 @@ static void elan_submit_image(struct fp_img_dev *dev) static void elan_cmd_done(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -177,7 +177,7 @@ static void elan_cmd_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -219,7 +219,7 @@ static void elan_cmd_cb(struct libusb_transfer *transfer) static void elan_cmd_read(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); int response_len = elandev->cmds[elandev->cmd_idx].response_len; G_DEBUG_HERE(); @@ -239,7 +239,7 @@ static void elan_cmd_read(struct fpi_ssm *ssm) g_free(elandev->last_read); elandev->last_read = g_malloc(response_len); - libusb_fill_bulk_transfer(transfer, dev->udev, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), elandev->cmds[elandev->cmd_idx].response_in, elandev->last_read, response_len, elan_cmd_cb, ssm, elandev->cmd_timeout); @@ -252,7 +252,7 @@ static void elan_cmd_read(struct fpi_ssm *ssm) static void elan_run_next_cmd(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -263,7 +263,7 @@ static void elan_run_next_cmd(struct fpi_ssm *ssm) } elandev->cur_transfer = transfer; - libusb_fill_bulk_transfer(transfer, dev->udev, ELAN_EP_CMD_OUT, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), ELAN_EP_CMD_OUT, (unsigned char *)elandev->cmds[elandev-> cmd_idx].cmd, ELAN_CMD_LEN, elan_cmd_cb, ssm, @@ -279,7 +279,7 @@ static void elan_run_cmds(struct fpi_ssm *ssm, const struct elan_cmd *cmds, size_t cmds_len, int cmd_timeout) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -315,13 +315,13 @@ static void deactivate_complete(struct fpi_ssm *ssm) static void elan_deactivate(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); elan_dev_reset(elandev); - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_deactivate_run_state, + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), elan_deactivate_run_state, DEACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, deactivate_complete); @@ -338,7 +338,7 @@ enum capture_states { static void elan_capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_START: @@ -378,7 +378,7 @@ static void elan_capture_async(void *data) static void capture_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -406,7 +406,7 @@ static void capture_complete(struct fpi_ssm *ssm) * completed, so we need to keep feeding it images till it's had enough. * But after that it can't finalize enrollemnt until this callback exits. * That's why we schedule elan_capture instead of running it directly. */ - if (fpi_dev_get_dev_state(dev->dev) == DEV_STATE_ENROLLING + if (fpi_dev_get_dev_state(fpi_imgdev_get_dev(dev)) == DEV_STATE_ENROLLING && !fpi_timeout_add(10, elan_capture_async, dev)) fpi_imgdev_session_error(dev, -ETIME); @@ -415,13 +415,13 @@ static void capture_complete(struct fpi_ssm *ssm) static void elan_capture(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); elan_dev_reset(elandev); struct fpi_ssm *ssm = - fpi_ssm_new(dev->dev, elan_capture_run_state, CAPTURE_NUM_STATES); + fpi_ssm_new(fpi_imgdev_get_dev(dev), elan_capture_run_state, CAPTURE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_complete); } @@ -458,7 +458,7 @@ static void elan_calibrate_run_state(struct fpi_ssm *ssm) static void calibrate_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -475,12 +475,12 @@ static void calibrate_complete(struct fpi_ssm *ssm) static void elan_calibrate(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); elan_dev_reset(elandev); - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, elan_calibrate_run_state, + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), elan_calibrate_run_state, CALIBRATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, calibrate_complete); @@ -498,7 +498,7 @@ enum activate_states { static void elan_activate_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case ACTIVATE_GET_SENSOR_DIM: @@ -528,7 +528,7 @@ static void elan_activate_run_state(struct fpi_ssm *ssm) static void activate_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -543,13 +543,13 @@ static void activate_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); elan_dev_reset(elandev); struct fpi_ssm *ssm = - fpi_ssm_new(dev->dev, elan_activate_run_state, ACTIVATE_NUM_STATES); + fpi_ssm_new(fpi_imgdev_get_dev(dev), elan_activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_complete); @@ -563,32 +563,33 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) G_DEBUG_HERE(); - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = elandev = g_malloc0(sizeof(struct elan_dev)); + elandev = g_malloc0(sizeof(struct elan_dev)); + fpi_imgdev_set_user_data(dev, elandev); fpi_imgdev_open_complete(dev, 0); return 0; } static void dev_deinit(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); elan_dev_reset(elandev); g_free(elandev); - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } static void dev_deactivate(struct fp_img_dev *dev) { - struct elan_dev *elandev = dev->priv; + struct elan_dev *elandev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); diff --git a/libfprint/drivers/etes603.c b/libfprint/drivers/etes603.c index de1f0bdc..fdaf7f20 100644 --- a/libfprint/drivers/etes603.c +++ b/libfprint/drivers/etes603.c @@ -639,7 +639,7 @@ enum { static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb, void *cb_arg) { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *buffer; int length; @@ -656,7 +656,7 @@ static int async_tx(struct fp_img_dev *idev, unsigned int ep, void *cb, } else { return -EIO; } - libusb_fill_bulk_transfer(transfer, idev->udev, ep, buffer, length, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(idev), ep, buffer, length, cb, cb_arg, BULK_TIMEOUT); if (libusb_submit_transfer(transfer)) { @@ -671,7 +671,7 @@ static void async_tx_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fp_warn("transfer is not completed (status=%d)", @@ -702,7 +702,7 @@ static void async_tx_cb(struct libusb_transfer *transfer) static void m_exit_state(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); switch (fpi_ssm_get_cur_state(ssm)) { case EXIT_SET_REGS_REQ: @@ -742,7 +742,7 @@ static void m_exit_complete(struct fpi_ssm *ssm) static void m_exit_start(struct fp_img_dev *idev) { - struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, m_exit_state, + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_exit_state, EXIT_NUM_STATES); fp_dbg("Switching device to idle mode"); fpi_ssm_set_user_data(ssm, idev); @@ -752,7 +752,7 @@ static void m_exit_start(struct fp_img_dev *idev) static void m_capture_state(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (dev->is_active == FALSE) { fpi_ssm_mark_completed(ssm); @@ -833,10 +833,10 @@ err: static void m_capture_complete(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (fpi_ssm_get_error(ssm)) { - if (idev->action_state != IMG_ACQUIRE_STATE_DEACTIVATING) { + if (fpi_imgdev_get_action_state(idev) != IMG_ACQUIRE_STATE_DEACTIVATING) { fp_err("Error while capturing fingerprint " "(fpi_ssm_get_error(ssm)=%d)", fpi_ssm_get_error(ssm)); fpi_imgdev_session_error(idev, fpi_ssm_get_error(ssm)); @@ -855,7 +855,7 @@ static void m_capture_complete(struct fpi_ssm *ssm) static void m_finger_state(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (dev->is_active == FALSE) { fpi_ssm_mark_completed(ssm); @@ -951,16 +951,16 @@ err: static void m_finger_complete(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (!fpi_ssm_get_error(ssm)) { struct fpi_ssm *ssm_cap; - ssm_cap = fpi_ssm_new(idev->dev, m_capture_state, + ssm_cap = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_capture_state, CAP_NUM_STATES); fpi_ssm_set_user_data(ssm_cap, idev); fpi_ssm_start(ssm_cap, m_capture_complete); } else { - if (idev->action_state != IMG_ACQUIRE_STATE_DEACTIVATING) { + if (fpi_imgdev_get_action_state(idev) != IMG_ACQUIRE_STATE_DEACTIVATING) { fp_err("Error while capturing fingerprint " "(fpi_ssm_get_error(ssm)=%d)", fpi_ssm_get_error(ssm)); fpi_imgdev_session_error(idev, -4); @@ -974,7 +974,7 @@ static void m_finger_complete(struct fpi_ssm *ssm) static void m_start_fingerdetect(struct fp_img_dev *idev) { struct fpi_ssm *ssmf; - ssmf = fpi_ssm_new(idev->dev, m_finger_state, FGR_NUM_STATES); + ssmf = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_finger_state, FGR_NUM_STATES); fpi_ssm_set_user_data(ssmf, idev); fpi_ssm_start(ssmf, m_finger_complete); } @@ -985,7 +985,7 @@ static void m_start_fingerdetect(struct fp_img_dev *idev) static void m_tunevrb_state(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); float hist[5]; if (dev->is_active == FALSE) { @@ -1143,7 +1143,7 @@ static void m_tunevrb_complete(struct fpi_ssm *ssm) fp_dbg("Tuning is done. Starting finger detection."); m_start_fingerdetect(idev); } else { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); fp_err("Error while tuning VRT"); dev->is_active = FALSE; reset_param(dev); @@ -1159,7 +1159,7 @@ static void m_tunevrb_complete(struct fpi_ssm *ssm) static void m_tunedc_state(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (dev->is_active == FALSE) { fpi_ssm_mark_completed(ssm); @@ -1264,12 +1264,12 @@ static void m_tunedc_complete(struct fpi_ssm *ssm) struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); if (!fpi_ssm_get_error(ssm)) { struct fpi_ssm *ssm_tune; - ssm_tune = fpi_ssm_new(idev->dev, m_tunevrb_state, + ssm_tune = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_tunevrb_state, TUNEVRB_NUM_STATES); fpi_ssm_set_user_data(ssm_tune, idev); fpi_ssm_start(ssm_tune, m_tunevrb_complete); } else { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); fp_err("Error while tuning DCOFFSET"); dev->is_active = FALSE; reset_param(dev); @@ -1281,7 +1281,7 @@ static void m_tunedc_complete(struct fpi_ssm *ssm) static void m_init_state(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); if (dev->is_active == FALSE) { fpi_ssm_mark_completed(ssm); @@ -1384,12 +1384,12 @@ static void m_init_complete(struct fpi_ssm *ssm) struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); if (!fpi_ssm_get_error(ssm)) { struct fpi_ssm *ssm_tune; - ssm_tune = fpi_ssm_new(idev->dev, m_tunedc_state, + ssm_tune = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_tunedc_state, TUNEDC_NUM_STATES); fpi_ssm_set_user_data(ssm_tune, idev); fpi_ssm_start(ssm_tune, m_tunedc_complete); } else { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); fp_err("Error initializing the device"); dev->is_active = FALSE; reset_param(dev); @@ -1400,7 +1400,7 @@ static void m_init_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); struct fpi_ssm *ssm; g_assert(dev); @@ -1416,7 +1416,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) if (dev->dcoffset == 0) { fp_dbg("Tuning device..."); - ssm = fpi_ssm_new(idev->dev, m_init_state, INIT_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_init_state, INIT_NUM_STATES); fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, m_init_complete); } else { @@ -1424,7 +1424,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) "VRB=0x%02X,GAIN=0x%02X).", dev->dcoffset, dev->vrt, dev->vrb, dev->gain); fpi_imgdev_activate_complete(idev, 0); - ssm = fpi_ssm_new(idev->dev, m_finger_state, FGR_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), m_finger_state, FGR_NUM_STATES); fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, m_finger_complete); } @@ -1433,7 +1433,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *idev) { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); fp_dbg("deactivating"); @@ -1450,13 +1450,13 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) struct etes603_dev *dev; dev = g_malloc0(sizeof(struct etes603_dev)); - idev->priv = dev; + fpi_imgdev_set_user_data(idev, dev); dev->req = g_malloc(sizeof(struct egis_msg)); dev->ans = g_malloc(FE_SIZE); dev->fp = g_malloc(FE_SIZE * 4); - ret = libusb_claim_interface(idev->udev, 0); + ret = libusb_claim_interface(fpi_imgdev_get_usb_dev(idev), 0); if (ret != LIBUSB_SUCCESS) { fp_err("libusb_claim_interface failed on interface 0: %s", libusb_error_name(ret)); return ret; @@ -1468,14 +1468,14 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) static void dev_close(struct fp_img_dev *idev) { - struct etes603_dev *dev = idev->priv; + struct etes603_dev *dev = fpi_imgdev_get_user_data(idev); g_free(dev->req); g_free(dev->ans); g_free(dev->fp); g_free(dev); - libusb_release_interface(idev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(idev), 0); fpi_imgdev_close_complete(idev); } diff --git a/libfprint/drivers/fdu2000.c b/libfprint/drivers/fdu2000.c index 867cfed9..bdd2983d 100644 --- a/libfprint/drivers/fdu2000.c +++ b/libfprint/drivers/fdu2000.c @@ -169,25 +169,25 @@ capture(struct fp_img_dev *dev, gboolean unconditional, image = g_malloc0(RAW_IMAGE_SIZE); - if ((r = bulk_write_safe(dev->udev, LED_ON))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), LED_ON))) { fp_err("Command: LED_ON"); goto out; } - if ((r = bulk_write_safe(dev->udev, CAPTURE_READY))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_READY))) { fp_err("Command: CAPTURE_READY"); goto out; } read: - if ((r = bulk_write_safe(dev->udev, CAPTURE_READ))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_READ))) { fp_err("Command: CAPTURE_READ"); goto out; } /* Now we are ready to read from dev */ - r = libusb_bulk_transfer(dev->udev, &msg, &bytes, BULK_TIMEOUT * 10); + r = libusb_bulk_transfer(fpi_imgdev_get_usb_dev(dev), &msg, &bytes, BULK_TIMEOUT * 10); if (r < 0 || bytes < 1) goto read; @@ -228,12 +228,12 @@ read: } } - if ((r = bulk_write_safe(dev->udev, CAPTURE_END))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_END))) { fp_err("Command: CAPTURE_END"); goto out; } - if ((r = bulk_write_safe(dev->udev, LED_OFF))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), LED_OFF))) { fp_err("Command: LED_OFF"); goto out; } @@ -254,27 +254,27 @@ static gint dev_init(struct fp_img_dev *dev, unsigned long driver_data) { gint r; - //if ( (r = usb_set_configuration(dev->udev, 1)) < 0 ) + //if ( (r = usb_set_configuration(fpi_imgdev_get_usb_dev(dev), 1)) < 0 ) // goto out; - if ( (r = libusb_claim_interface(dev->udev, 0)) < 0 ) { + if ( (r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0)) < 0 ) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - //if ( (r = usb_set_altinterface(dev->udev, 1)) < 0 ) + //if ( (r = usb_set_altinterface(fpi_imgdev_get_usb_dev(dev), 1)) < 0 ) // goto out; - //if ( (r = usb_clear_halt(dev->udev, EP_CMD)) < 0 ) + //if ( (r = usb_clear_halt(fpi_imgdev_get_usb_dev(dev), EP_CMD)) < 0 ) // goto out; /* Make sure sensor mode is not capture_{ready|read} */ - if ((r = bulk_write_safe(dev->udev, CAPTURE_END))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_END))) { fp_err("Command: CAPTURE_END"); goto out; } - if ((r = bulk_write_safe(dev->udev, LED_OFF))) { + if ((r = bulk_write_safe(fpi_imgdev_get_usb_dev(dev), LED_OFF))) { fp_err("Command: LED_OFF"); goto out; } @@ -289,10 +289,10 @@ out: static void dev_exit(struct fp_img_dev *dev) { - if (bulk_write_safe(dev->udev, CAPTURE_END)) + if (bulk_write_safe(fpi_imgdev_get_usb_dev(dev), CAPTURE_END)) fp_err("Command: CAPTURE_END"); - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); } static const struct usb_id id_table[] = { diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 72a9318c..3827e1fc 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -176,7 +176,7 @@ static void free_img_transfers(struct sonly_dev *sdev) static void last_transfer_killed(struct fp_img_dev *dev) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (sdev->killing_transfers) { case ABORT_SSM: fp_dbg("abort ssm error %d", sdev->kill_status_code); @@ -197,7 +197,7 @@ static void last_transfer_killed(struct fp_img_dev *dev) static void cancel_img_transfers(struct fp_img_dev *dev) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); int i; if (sdev->num_flying == 0) { @@ -224,7 +224,7 @@ static gboolean is_capturing(struct sonly_dev *sdev) static void handoff_img(struct fp_img_dev *dev) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); struct fp_img *img; GSList *elem = sdev->rows; @@ -252,7 +252,7 @@ static void handoff_img(struct fp_img_dev *dev) static void row_complete(struct fp_img_dev *dev) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); sdev->rowbuf_offset = -1; if (sdev->num_rows > 0) { @@ -340,7 +340,7 @@ static void row_complete(struct fp_img_dev *dev) /* add data to row buffer */ static void add_to_rowbuf(struct fp_img_dev *dev, unsigned char *data, int size) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); memcpy(sdev->rowbuf + sdev->rowbuf_offset, data, size); sdev->rowbuf_offset += size; @@ -374,7 +374,7 @@ static int rowbuf_remaining(struct sonly_dev *sdev) static void handle_packet(struct fp_img_dev *dev, unsigned char *data) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); uint16_t seqnum = data[0] << 8 | data[1]; int abs_base_addr; int for_rowbuf; @@ -470,7 +470,7 @@ static void img_data_cb(struct libusb_transfer *transfer) { struct img_transfer_data *idata = transfer->user_data; struct fp_img_dev *dev = idata->dev; - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); int i; idata->flying = FALSE; @@ -629,7 +629,8 @@ static void sm_write_reg(struct fpi_ssm *ssm, uint8_t reg, uint8_t value) fp_dbg("set %02x=%02x", reg, value); data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 1); libusb_fill_control_setup(data, 0x40, 0x0c, 0, reg, 1); - libusb_fill_control_transfer(transfer, dev->udev, data, sm_write_reg_cb, + libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), + data, sm_write_reg_cb, ssm, CTRL_TIMEOUT); data[LIBUSB_CONTROL_SETUP_SIZE] = value; @@ -648,7 +649,7 @@ static void sm_read_reg_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fpi_ssm_mark_aborted(ssm, -EIO); @@ -676,7 +677,8 @@ static void sm_read_reg(struct fpi_ssm *ssm, uint8_t reg) fp_dbg("read reg %02x", reg); data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + 8); libusb_fill_control_setup(data, 0xc0, 0x0c, 0, reg, 8); - libusb_fill_control_transfer(transfer, dev->udev, data, sm_read_reg_cb, + libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), + data, sm_read_reg_cb, ssm, CTRL_TIMEOUT); transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK | LIBUSB_TRANSFER_FREE_TRANSFER; @@ -693,7 +695,7 @@ static void sm_await_intr_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { g_free(transfer->buffer); @@ -725,7 +727,8 @@ static void sm_await_intr(struct fpi_ssm *ssm) G_DEBUG_HERE(); data = g_malloc(4); - libusb_fill_interrupt_transfer(transfer, dev->udev, 0x83, data, 4, + libusb_fill_interrupt_transfer(transfer, fpi_imgdev_get_usb_dev(dev), + 0x83, data, 4, sm_await_intr_cb, ssm, 0); transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK | LIBUSB_TRANSFER_FREE_TRANSFER; @@ -763,7 +766,7 @@ enum awfsm_1000_states { static void awfsm_2016_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case AWFSM_2016_WRITEV_1: @@ -851,7 +854,7 @@ enum capsm_1001_states { static void capsm_fire_bulk(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); int i; for (i = 0; i < NUM_BULK_TRANSFERS; i++) { int r = libusb_submit_transfer(sdev->img_transfer[i]); @@ -881,7 +884,7 @@ static void capsm_fire_bulk(struct fpi_ssm *ssm) static void capsm_2016_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case CAPSM_2016_INIT: @@ -913,7 +916,7 @@ static void capsm_2016_run_state(struct fpi_ssm *ssm) static void capsm_1000_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case CAPSM_1000_INIT: @@ -939,7 +942,7 @@ static void capsm_1000_run_state(struct fpi_ssm *ssm) static void capsm_1001_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case CAPSM_1001_INIT: @@ -1048,7 +1051,7 @@ enum initsm_1001_states { static void initsm_2016_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case INITSM_2016_WRITEV_1: @@ -1120,7 +1123,7 @@ enum loopsm_states { static void loopsm_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case LOOPSM_RUN_AWFSM: ; @@ -1139,11 +1142,11 @@ static void loopsm_run_state(struct fpi_ssm *ssm) struct fpi_ssm *awfsm = NULL; switch (sdev->dev_model) { case UPEKSONLY_2016: - awfsm = fpi_ssm_new(dev->dev, awfsm_2016_run_state, + awfsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), awfsm_2016_run_state, AWFSM_2016_NUM_STATES); break; case UPEKSONLY_1000: - awfsm = fpi_ssm_new(dev->dev, awfsm_1000_run_state, + awfsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), awfsm_1000_run_state, AWFSM_1000_NUM_STATES); break; } @@ -1167,15 +1170,15 @@ static void loopsm_run_state(struct fpi_ssm *ssm) struct fpi_ssm *capsm = NULL; switch (sdev->dev_model) { case UPEKSONLY_2016: - capsm = fpi_ssm_new(dev->dev, capsm_2016_run_state, + capsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capsm_2016_run_state, CAPSM_2016_NUM_STATES); break; case UPEKSONLY_1000: - capsm = fpi_ssm_new(dev->dev, capsm_1000_run_state, + capsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capsm_1000_run_state, CAPSM_1000_NUM_STATES); break; case UPEKSONLY_1001: - capsm = fpi_ssm_new(dev->dev, capsm_1001_run_state, + capsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capsm_1001_run_state, CAPSM_1001_NUM_STATES); break; } @@ -1188,15 +1191,15 @@ static void loopsm_run_state(struct fpi_ssm *ssm) struct fpi_ssm *deinitsm = NULL; switch (sdev->dev_model) { case UPEKSONLY_2016: - deinitsm = fpi_ssm_new(dev->dev, deinitsm_2016_run_state, + deinitsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deinitsm_2016_run_state, DEINITSM_2016_NUM_STATES); break; case UPEKSONLY_1000: - deinitsm = fpi_ssm_new(dev->dev, deinitsm_1000_run_state, + deinitsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deinitsm_1000_run_state, DEINITSM_1000_NUM_STATES); break; case UPEKSONLY_1001: - deinitsm = fpi_ssm_new(dev->dev, deinitsm_1001_run_state, + deinitsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deinitsm_1001_run_state, DEINITSM_1001_NUM_STATES); break; } @@ -1215,7 +1218,7 @@ static void loopsm_run_state(struct fpi_ssm *ssm) static void deactivate_done(struct fp_img_dev *dev) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); free_img_transfers(sdev); @@ -1232,7 +1235,7 @@ static void deactivate_done(struct fp_img_dev *dev) static void dev_deactivate(struct fp_img_dev *dev) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); if (!sdev->capturing) { deactivate_done(dev); @@ -1248,7 +1251,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static void loopsm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); @@ -1267,7 +1270,7 @@ static void loopsm_complete(struct fpi_ssm *ssm) static void initsm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); @@ -1275,14 +1278,14 @@ static void initsm_complete(struct fpi_ssm *ssm) if (r != 0) return; - sdev->loopsm = fpi_ssm_new(dev->dev, loopsm_run_state, LOOPSM_NUM_STATES); + sdev->loopsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), loopsm_run_state, LOOPSM_NUM_STATES); fpi_ssm_set_user_data(sdev->loopsm, dev); fpi_ssm_start(sdev->loopsm, loopsm_complete); } static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct sonly_dev *sdev = dev->priv; + struct sonly_dev *sdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm = NULL; int i; @@ -1304,19 +1307,20 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) sdev->img_transfer_data[i].idx = i; sdev->img_transfer_data[i].dev = dev; data = g_malloc(4096); - libusb_fill_bulk_transfer(sdev->img_transfer[i], dev->udev, 0x81, data, + libusb_fill_bulk_transfer(sdev->img_transfer[i], fpi_imgdev_get_usb_dev(dev), + 0x81, data, 4096, img_data_cb, &sdev->img_transfer_data[i], 0); } switch (sdev->dev_model) { case UPEKSONLY_2016: - ssm = fpi_ssm_new(dev->dev, initsm_2016_run_state, INITSM_2016_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), initsm_2016_run_state, INITSM_2016_NUM_STATES); break; case UPEKSONLY_1000: - ssm = fpi_ssm_new(dev->dev, initsm_1000_run_state, INITSM_1000_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), initsm_1000_run_state, INITSM_1000_NUM_STATES); break; case UPEKSONLY_1001: - ssm = fpi_ssm_new(dev->dev, initsm_1001_run_state, INITSM_1001_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), initsm_1001_run_state, INITSM_1001_NUM_STATES); break; } fpi_ssm_set_user_data(ssm, dev); @@ -1329,19 +1333,20 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; struct sonly_dev *sdev; - r = libusb_set_configuration(dev->udev, 1); + r = libusb_set_configuration(fpi_imgdev_get_usb_dev(dev), 1); if (r < 0) { fp_err("could not set configuration 1"); return r; } - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - sdev = dev->priv = g_malloc0(sizeof(struct sonly_dev)); + sdev = g_malloc0(sizeof(struct sonly_dev)); + fpi_imgdev_set_user_data(dev, sdev); sdev->dev_model = (int)driver_data; switch (driver_data) { case UPEKSONLY_1000: @@ -1367,8 +1372,10 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + void *user_data; + user_data = fpi_imgdev_get_user_data(dev); + g_free(user_data); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 2c406840..6097c26c 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -59,7 +59,7 @@ enum activate_states { static void upektc_next_init_cmd(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); upekdev->init_idx += 1; if (upekdev->init_idx == upekdev->setup_commands_len) @@ -72,7 +72,7 @@ static void write_init_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) && (transfer->length == transfer->actual_length)) { @@ -101,7 +101,7 @@ static void read_init_data_cb(struct libusb_transfer *transfer) static void activate_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); int r; switch (fpi_ssm_get_cur_state(ssm)) { @@ -112,7 +112,7 @@ static void activate_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_out, (unsigned char*)upekdev->setup_commands[upekdev->init_idx].cmd, UPEKTC_CMD_LEN, write_init_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -133,7 +133,7 @@ static void activate_run_state(struct fpi_ssm *ssm) } data = g_malloc(upekdev->setup_commands[upekdev->init_idx].response_len); - libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_in, data, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_in, data, upekdev->setup_commands[upekdev->init_idx].response_len, read_init_data_cb, ssm, BULK_TIMEOUT); @@ -181,7 +181,7 @@ static int finger_present(unsigned char *img, size_t len, int sum_threshold) static void finger_det_data_cb(struct libusb_transfer *transfer) { struct fp_img_dev *dev = transfer->user_data; - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { @@ -214,7 +214,7 @@ static void finger_det_cmd_cb(struct libusb_transfer *t) unsigned char *data; int r; struct fp_img_dev *dev = t->user_data; - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); if (t->status != LIBUSB_TRANSFER_COMPLETED) { fp_dbg("req transfer status %d\n", t->status); @@ -233,7 +233,7 @@ static void finger_det_cmd_cb(struct libusb_transfer *t) } data = g_malloc(IMAGE_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_in, data, IMAGE_SIZE, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_in, data, IMAGE_SIZE, finger_det_data_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -249,7 +249,7 @@ exit_free_transfer: static void start_finger_detection(struct fp_img_dev *dev) { int r; - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); struct libusb_transfer *transfer; G_DEBUG_HERE(); @@ -263,7 +263,7 @@ static void start_finger_detection(struct fp_img_dev *dev) fpi_imgdev_session_error(dev, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_out, (unsigned char *)scan_cmd, UPEKTC_CMD_LEN, finger_det_cmd_cb, dev, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -324,7 +324,7 @@ out: static void capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); int r; switch (fpi_ssm_get_cur_state(ssm)) { @@ -335,7 +335,7 @@ static void capture_run_state(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_out, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_out, (unsigned char *)scan_cmd, UPEKTC_CMD_LEN, capture_cmd_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -356,7 +356,7 @@ static void capture_run_state(struct fpi_ssm *ssm) } data = g_malloc(IMAGE_SIZE); - libusb_fill_bulk_transfer(transfer, dev->udev, upekdev->ep_in, data, IMAGE_SIZE, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), upekdev->ep_in, data, IMAGE_SIZE, capture_read_data_cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -373,7 +373,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); fp_dbg("Capture completed"); if (upekdev->deactivating) @@ -387,7 +387,7 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; if (upekdev->deactivating) { @@ -395,7 +395,7 @@ static void start_capture(struct fp_img_dev *dev) return; } - ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES); G_DEBUG_HERE(); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); @@ -403,8 +403,8 @@ static void start_capture(struct fp_img_dev *dev) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct upektc_dev *upekdev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); upekdev->init_idx = 0; @@ -414,14 +414,14 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); upekdev->deactivating = TRUE; } static void complete_deactivation(struct fp_img_dev *dev) { - struct upektc_dev *upekdev = dev->priv; + struct upektc_dev *upekdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); upekdev->deactivating = FALSE; @@ -434,13 +434,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; struct upektc_dev *upekdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = upekdev = g_malloc0(sizeof(struct upektc_dev)); + upekdev = g_malloc0(sizeof(struct upektc_dev)); + fpi_imgdev_set_user_data(dev, upekdev); switch (driver_data) { case UPEKTC_2015: upekdev->ep_in = UPEKTC_EP_IN; @@ -459,7 +460,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) default: fp_err("Device variant %lu is not known\n", driver_data); g_free(upekdev); - dev->priv = NULL; + fpi_imgdev_set_user_data(dev, NULL); return -ENODEV; break; } @@ -469,8 +470,10 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + void *user_data; + user_data = fpi_imgdev_get_user_data(dev); + g_free(user_data); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 96a0b492..f0f2f18c 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -119,7 +119,7 @@ static void upektc_img_submit_req(struct fpi_ssm *ssm, libusb_transfer_cb_fn cb) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); struct libusb_transfer *transfer = libusb_alloc_transfer(0); int r; @@ -136,7 +136,7 @@ static void upektc_img_submit_req(struct fpi_ssm *ssm, upektc_img_cmd_fix_seq(upekdev->cmd, seq); upektc_img_cmd_update_crc(upekdev->cmd, buf_size); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_OUT, upekdev->cmd, buf_size, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT, upekdev->cmd, buf_size, cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -150,7 +150,7 @@ static void upektc_img_read_data(struct fpi_ssm *ssm, size_t buf_size, size_t bu { struct libusb_transfer *transfer = libusb_alloc_transfer(0); struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); int r; if (!transfer) { @@ -162,7 +162,7 @@ static void upektc_img_read_data(struct fpi_ssm *ssm, size_t buf_size, size_t bu transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, upekdev->response + buf_offset, buf_size, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, upekdev->response + buf_offset, buf_size, cb, ssm, BULK_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -226,7 +226,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); unsigned char *data = upekdev->response; struct fp_img *img; size_t response_size; @@ -350,7 +350,7 @@ static void capture_read_data_cb(struct libusb_transfer *transfer) static void capture_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case CAPTURE_INIT_CAPTURE: @@ -387,7 +387,7 @@ static void capture_run_state(struct fpi_ssm *ssm) static void capture_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); int err = fpi_ssm_get_error(ssm); fp_dbg("Capture completed, %d", err); @@ -403,12 +403,12 @@ static void capture_sm_complete(struct fpi_ssm *ssm) static void start_capture(struct fp_img_dev *dev) { - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; upekdev->image_size = 0; - ssm = fpi_ssm_new(dev->dev, capture_run_state, CAPTURE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), capture_run_state, CAPTURE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, capture_sm_complete); } @@ -448,7 +448,7 @@ static void deactivate_read_data_cb(struct libusb_transfer *transfer) static void deactivate_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case DEACTIVATE_DEINIT: @@ -465,7 +465,7 @@ static void deactivate_run_state(struct fpi_ssm *ssm) static void deactivate_sm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); int err = fpi_ssm_get_error(ssm); fp_dbg("Deactivate completed"); @@ -482,12 +482,12 @@ static void deactivate_sm_complete(struct fpi_ssm *ssm) static void start_deactivation(struct fp_img_dev *dev) { - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; upekdev->image_size = 0; - ssm = fpi_ssm_new(dev->dev, deactivate_run_state, DEACTIVATE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deactivate_run_state, DEACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, deactivate_sm_complete); } @@ -547,7 +547,7 @@ static void activate_run_state(struct fpi_ssm *ssm) { struct libusb_transfer *transfer; struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct upektc_img_dev *upekdev = idev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(idev); struct fp_dev *dev = fpi_ssm_get_dev(ssm); int r; @@ -622,8 +622,8 @@ static void activate_sm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct upektc_img_dev *upekdev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, activate_run_state, + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_run_state, ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); upekdev->seq = 0; @@ -633,7 +633,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct upektc_img_dev *upekdev = dev->priv; + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); upekdev->deactivating = TRUE; } @@ -642,22 +642,25 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { /* TODO check that device has endpoints we're using */ int r; + struct upektc_img_dev *upekdev; - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { fp_err("could not claim interface 0: %s", libusb_error_name(r)); return r; } - dev->priv = g_malloc0(sizeof(struct upektc_img_dev)); + upekdev = g_malloc0(sizeof(struct upektc_img_dev)); + fpi_imgdev_set_user_data(dev, upekdev); fpi_imgdev_open_complete(dev, 0); return 0; } static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + struct upektc_img_dev *upekdev = fpi_imgdev_get_user_data(dev); + g_free(upekdev); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index a28925ca..6ed311d3 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -201,7 +201,7 @@ static int write_regs(struct fp_img_dev *dev, uint16_t first_reg, data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + num_regs); memcpy(data + LIBUSB_CONTROL_SETUP_SIZE, values, num_regs); libusb_fill_control_setup(data, CTRL_OUT, USB_RQ, first_reg, 0, num_regs); - libusb_fill_control_transfer(transfer, dev->udev, data, write_regs_cb, + libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, write_regs_cb, wrdata, CTRL_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -267,7 +267,7 @@ static int read_regs(struct fp_img_dev *dev, uint16_t first_reg, data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE + num_regs); libusb_fill_control_setup(data, CTRL_IN, USB_RQ, first_reg, 0, num_regs); - libusb_fill_control_transfer(transfer, dev->udev, data, read_regs_cb, + libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, read_regs_cb, rrdata, CTRL_TIMEOUT); r = libusb_submit_transfer(transfer); @@ -317,7 +317,7 @@ static void challenge_cb(struct fp_img_dev *dev, int status, uint16_t num_regs, unsigned char *data, void *user_data) { struct fpi_ssm *ssm = user_data; - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); unsigned char *respdata; PK11Context *ctx; int r, outlen; @@ -374,7 +374,7 @@ static int start_irq_handler(struct fp_img_dev *dev); static void irq_handler(struct libusb_transfer *transfer) { struct fp_img_dev *dev = transfer->user_data; - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); unsigned char *data = transfer->buffer; uint16_t type; int r = 0; @@ -426,7 +426,7 @@ out: static int start_irq_handler(struct fp_img_dev *dev) { - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); struct libusb_transfer *transfer = libusb_alloc_transfer(0); unsigned char *data; int r; @@ -435,7 +435,7 @@ static int start_irq_handler(struct fp_img_dev *dev) return -ENOMEM; data = g_malloc(IRQ_LENGTH); - libusb_fill_bulk_transfer(transfer, dev->udev, EP_INTR, data, IRQ_LENGTH, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_INTR, data, IRQ_LENGTH, irq_handler, dev, 0); urudev->irq_transfer = transfer; @@ -450,7 +450,7 @@ static int start_irq_handler(struct fp_img_dev *dev) static void stop_irq_handler(struct fp_img_dev *dev, irqs_stopped_cb_fn cb) { - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); struct libusb_transfer *transfer = urudev->irq_transfer; if (transfer) { libusb_cancel_transfer(transfer); @@ -484,7 +484,7 @@ static void change_state_write_reg_cb(struct fp_img_dev *dev, int status, static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); switch (state) { case IMGDEV_STATE_INACTIVE: @@ -535,7 +535,7 @@ static void sm_read_reg_cb(struct fp_img_dev *dev, int result, uint16_t num_regs, unsigned char *data, void *user_data) { struct fpi_ssm *ssm = user_data; - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); if (result) { fpi_ssm_mark_aborted(ssm, result); @@ -549,7 +549,7 @@ static void sm_read_reg_cb(struct fp_img_dev *dev, int result, static void sm_read_regs(struct fpi_ssm *ssm, uint16_t reg, uint16_t num_regs) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); int r; if (num_regs > sizeof(urudev->last_reg_rd)) { @@ -690,7 +690,7 @@ static int calc_dev2(struct uru4k_image *img) static void imaging_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); struct uru4k_image *img = urudev->img_data; struct fp_img *fpimg; uint32_t key; @@ -702,7 +702,7 @@ static void imaging_run_state(struct fpi_ssm *ssm) case IMAGING_CAPTURE: urudev->img_lines_done = 0; urudev->img_block = 0; - libusb_fill_bulk_transfer(urudev->img_transfer, dev->udev, EP_DATA, + libusb_fill_bulk_transfer(urudev->img_transfer, fpi_imgdev_get_usb_dev(dev), EP_DATA, urudev->img_data, sizeof(struct uru4k_image), image_transfer_cb, ssm, 0); r = libusb_submit_transfer(urudev->img_transfer); if (r < 0) @@ -813,7 +813,7 @@ static void imaging_run_state(struct fpi_ssm *ssm) static void imaging_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); @@ -864,7 +864,7 @@ static void rebootpwr_pause_cb(void *data) { struct fpi_ssm *ssm = data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); if (!--urudev->rebootpwr_ctr) { fp_err("could not reboot device power"); @@ -877,7 +877,7 @@ static void rebootpwr_pause_cb(void *data) static void rebootpwr_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case REBOOTPWR_SET_HWSTAT: @@ -941,7 +941,7 @@ static void powerup_pause_cb(void *data) { struct fpi_ssm *ssm = data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); if (!--urudev->powerup_ctr) { fp_err("could not power device up"); @@ -956,7 +956,7 @@ static void powerup_pause_cb(void *data) static void powerup_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case POWERUP_INIT: @@ -1025,7 +1025,7 @@ 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; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); if (status) fpi_ssm_mark_aborted(ssm, status); @@ -1044,7 +1044,7 @@ static void init_scanpwr_timeout(void *user_data) { struct fpi_ssm *ssm = user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); fp_warn("powerup timed out"); urudev->irq_cb = NULL; @@ -1061,7 +1061,7 @@ static void init_scanpwr_timeout(void *user_data) static void init_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case INIT_GET_HWSTAT: @@ -1075,7 +1075,7 @@ static void init_run_state(struct fpi_ssm *ssm) fpi_ssm_jump_to_state(ssm, INIT_CHECK_HWSTAT_POWERDOWN); break; case INIT_REBOOT_POWER: ; - struct fpi_ssm *rebootsm = fpi_ssm_new(dev->dev, rebootpwr_run_state, + struct fpi_ssm *rebootsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), rebootpwr_run_state, REBOOTPWR_NUM_STATES); fpi_ssm_set_user_data(rebootsm, dev); fpi_ssm_start_subsm(ssm, rebootsm); @@ -1094,7 +1094,7 @@ static void init_run_state(struct fpi_ssm *ssm) urudev->irq_cb_data = ssm; urudev->irq_cb = init_scanpwr_irq_cb; - struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state, + struct fpi_ssm *powerupsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), powerup_run_state, POWERUP_NUM_STATES); fpi_ssm_set_user_data(powerupsm, dev); fpi_ssm_start_subsm(ssm, powerupsm); @@ -1159,7 +1159,7 @@ static void activate_initsm_complete(struct fpi_ssm *ssm) * call. */ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; int r; @@ -1169,7 +1169,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) urudev->scanpwr_irq_timeouts = 0; urudev->activate_state = state; - ssm = fpi_ssm_new(dev->dev, init_run_state, INIT_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), init_run_state, INIT_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, activate_initsm_complete); return 0; @@ -1195,7 +1195,7 @@ static void dev_deactivate(struct fp_img_dev *dev) static int execute_state_change(struct fp_img_dev *dev) { - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; switch (urudev->activate_state) { @@ -1223,7 +1223,7 @@ static int execute_state_change(struct fp_img_dev *dev) urudev->img_data = g_malloc(sizeof(struct uru4k_image)); urudev->img_enc_seed = rand(); - ssm = fpi_ssm_new(dev->dev, imaging_run_state, IMAGING_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), imaging_run_state, IMAGING_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, imaging_complete); @@ -1257,7 +1257,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) int r; /* Find fingerprint interface */ - r = libusb_get_config_descriptor(libusb_get_device(dev->udev), 0, &config); + r = libusb_get_config_descriptor(libusb_get_device(fpi_imgdev_get_usb_dev(dev)), 0, &config); if (r < 0) { fp_err("Failed to get config descriptor"); return r; @@ -1311,7 +1311,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) /* Device looks like a supported reader */ - r = libusb_claim_interface(dev->udev, iface_desc->bInterfaceNumber); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), iface_desc->bInterfaceNumber); if (r < 0) { fp_err("interface claim failed: %s", libusb_error_name(r)); goto out; @@ -1351,7 +1351,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) } urudev->param = PK11_ParamFromIV(urudev->cipher, NULL); - dev->priv = urudev; + fpi_imgdev_set_user_data(dev, urudev); fpi_imgdev_open_complete(dev, 0); out: @@ -1361,14 +1361,14 @@ out: static void dev_deinit(struct fp_img_dev *dev) { - struct uru4k_dev *urudev = dev->priv; + struct uru4k_dev *urudev = fpi_imgdev_get_user_data(dev); if (urudev->symkey) PK11_FreeSymKey (urudev->symkey); if (urudev->param) SECITEM_FreeItem(urudev->param, PR_TRUE); if (urudev->slot) PK11_FreeSlot(urudev->slot); - libusb_release_interface(dev->udev, urudev->interface); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), urudev->interface); g_free(urudev); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/vcom5s.c b/libfprint/drivers/vcom5s.c index 7a6444b9..cbd03751 100644 --- a/libfprint/drivers/vcom5s.c +++ b/libfprint/drivers/vcom5s.c @@ -101,7 +101,7 @@ static void sm_write_reg(struct fpi_ssm *ssm, unsigned char reg, fp_dbg("set %02x=%02x", reg, value); data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE); libusb_fill_control_setup(data, CTRL_OUT, reg, value, 0, 0); - libusb_fill_control_transfer(transfer, dev->udev, data, sm_write_reg_cb, + libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, sm_write_reg_cb, ssm, CTRL_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -140,7 +140,7 @@ static void sm_exec_cmd(struct fpi_ssm *ssm, unsigned char cmd, fp_dbg("cmd %02x param %02x", cmd, param); data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE); libusb_fill_control_setup(data, CTRL_IN, cmd, param, 0, 0); - libusb_fill_control_transfer(transfer, dev->udev, data, sm_exec_cmd_cb, + libusb_fill_control_transfer(transfer, fpi_imgdev_get_usb_dev(dev), data, sm_exec_cmd_cb, ssm, CTRL_TIMEOUT); r = libusb_submit_transfer(transfer); if (r < 0) { @@ -193,7 +193,7 @@ static void capture_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct v5s_dev *vdev = dev->priv; + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fpi_ssm_mark_aborted(ssm, -EIO); @@ -221,7 +221,7 @@ out: static void capture_iterate(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct v5s_dev *vdev = dev->priv; + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); int iteration = vdev->capture_iteration; struct libusb_transfer *transfer = libusb_alloc_transfer(0); int r; @@ -231,7 +231,7 @@ static void capture_iterate(struct fpi_ssm *ssm) return; } - libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(dev), EP_IN, vdev->capture_img->data + (RQ_SIZE * iteration), RQ_SIZE, capture_cb, ssm, CTRL_TIMEOUT); transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; @@ -246,7 +246,7 @@ static void capture_iterate(struct fpi_ssm *ssm) static void sm_do_capture(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct v5s_dev *vdev = dev->priv; + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); vdev->capture_img = fpi_img_new_for_imgdev(dev); @@ -268,7 +268,7 @@ enum loop_states { static void loop_run_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct v5s_dev *vdev = dev->priv; + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case LOOP_SET_CONTRAST: @@ -296,7 +296,7 @@ static void loop_run_state(struct fpi_ssm *ssm) static void loopsm_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct v5s_dev *vdev = dev->priv; + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); int r = fpi_ssm_get_error(ssm); fpi_ssm_free(ssm); @@ -313,8 +313,8 @@ static void loopsm_complete(struct fpi_ssm *ssm) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct v5s_dev *vdev = dev->priv; - struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, loop_run_state, + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), loop_run_state, LOOP_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); vdev->deactivating = FALSE; @@ -326,7 +326,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { - struct v5s_dev *vdev = dev->priv; + struct v5s_dev *vdev = fpi_imgdev_get_user_data(dev); if (vdev->loop_running) vdev->deactivating = TRUE; else @@ -336,9 +336,12 @@ static void dev_deactivate(struct fp_img_dev *dev) static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) { int r; - dev->priv = g_malloc0(sizeof(struct v5s_dev)); + struct v5s_dev *v5s_dev; - r = libusb_claim_interface(dev->udev, 0); + v5s_dev = g_malloc0(sizeof(struct v5s_dev)); + fpi_imgdev_set_user_data(dev, v5s_dev); + + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) fp_err("could not claim interface 0: %s", libusb_error_name(r)); @@ -350,8 +353,10 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) static void dev_deinit(struct fp_img_dev *dev) { - g_free(dev->priv); - libusb_release_interface(dev->udev, 0); + struct v5s_dev *v5s_dev; + v5s_dev = fpi_imgdev_get_user_data(dev); + g_free(v5s_dev); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); fpi_imgdev_close_complete(dev); } diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index cbbda031..c4694e6d 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -54,8 +54,8 @@ static void async_write_callback(struct libusb_transfer *transfer) static void async_write(struct fpi_ssm *ssm, void *data, int len) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = idev->udev; - struct vfs_dev_t *vdev = idev->priv; + struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); vdev->transfer = libusb_alloc_transfer(0); vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; @@ -96,8 +96,8 @@ static void async_read_callback(struct libusb_transfer *transfer) static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = idev->udev; - struct vfs_dev_t *vdev = idev->priv; + struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); ep |= LIBUSB_ENDPOINT_IN; @@ -150,8 +150,8 @@ static void async_abort_callback(struct libusb_transfer *transfer) static void async_abort(struct fpi_ssm *ssm, int ep) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = idev->udev; - struct vfs_dev_t *vdev = idev->priv; + struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); int len = VFS_USB_BUFFER_SIZE; unsigned char *data = g_malloc(VFS_USB_BUFFER_SIZE); @@ -259,7 +259,7 @@ static struct fp_img *prepare_image(struct vfs_dev_t *vdev) /* Processes and submits image after fingerprint received */ static void submit_image(struct fp_img_dev *idev) { - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); /* We were not asked to submit image actually */ if (!vdev->active) @@ -312,7 +312,7 @@ static void clear_ep2(struct fpi_ssm *ssm) struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct fpi_ssm *subsm = - fpi_ssm_new(idev->dev, clear_ep2_ssm, SUBSM1_STATES); + fpi_ssm_new(fpi_imgdev_get_dev(idev), clear_ep2_ssm, SUBSM1_STATES); fpi_ssm_set_user_data(subsm, idev); fpi_ssm_start_subsm(ssm, subsm); } @@ -320,7 +320,7 @@ static void clear_ep2(struct fpi_ssm *ssm) static void send_control_packet_ssm(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); short result; unsigned char *commit_result = NULL; @@ -390,7 +390,7 @@ static void send_control_packet(struct fpi_ssm *ssm) struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); struct fpi_ssm *subsm = - fpi_ssm_new(idev->dev, send_control_packet_ssm, SUBSM2_STATES); + fpi_ssm_new(fpi_imgdev_get_dev(idev), send_control_packet_ssm, SUBSM2_STATES); fpi_ssm_set_user_data(subsm, idev); fpi_ssm_start_subsm(ssm, subsm); } @@ -408,7 +408,7 @@ static void interrupt_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); char *interrupt = vdev->interrupt; int error = transfer->status, transferred = transfer->actual_length; @@ -468,7 +468,7 @@ static void receive_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); int transferred = transfer->actual_length, error = transfer->status; @@ -496,7 +496,7 @@ static void wait_interrupt(void *data) { struct fpi_ssm *ssm = data; struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); /* Keep sleeping while this flag is on */ if (vdev->wait_interrupt) @@ -521,8 +521,8 @@ static void scan_completed(void *data) static void activate_ssm(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = idev->udev; - struct vfs_dev_t *vdev = idev->priv; + struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); switch (fpi_ssm_get_cur_state(ssm)) { case SSM_INITIAL_ABORT_1: @@ -674,7 +674,7 @@ static void activate_ssm(struct fpi_ssm *ssm) static void dev_activate_callback(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); vdev->ssm_active = 0; @@ -684,14 +684,14 @@ static void dev_activate_callback(struct fpi_ssm *ssm) /* Activate device */ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) { - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); /* Initialize flags */ vdev->active = 1; vdev->need_report = 1; vdev->ssm_active = 1; - struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, activate_ssm, SSM_STATES); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), activate_ssm, SSM_STATES); fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, dev_activate_callback); return 0; @@ -700,7 +700,7 @@ static int dev_activate(struct fp_img_dev *idev, enum fp_imgdev_state state) /* Deactivate device */ static void dev_deactivate(struct fp_img_dev *idev) { - struct vfs_dev_t *vdev = idev->priv; + struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); if (!vdev->ssm_active) { fpi_imgdev_deactivate_complete(idev); @@ -723,8 +723,10 @@ static void dev_open_callback(struct fpi_ssm *ssm) /* Open device */ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) { + struct vfs_dev_t *vdev; + /* Claim usb interface */ - int error = libusb_claim_interface(idev->udev, 0); + int error = libusb_claim_interface(fpi_imgdev_get_usb_dev(idev), 0); if (error < 0) { /* Interface not claimed, return error */ fp_err("could not claim interface 0"); @@ -732,11 +734,11 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) } /* Initialize private structure */ - struct vfs_dev_t *vdev = g_malloc0(sizeof(struct vfs_dev_t)); - idev->priv = vdev; + vdev = g_malloc0(sizeof(struct vfs_dev_t)); + fpi_imgdev_set_user_data(idev, vdev); /* Clearing previous device state */ - struct fpi_ssm *ssm = fpi_ssm_new(idev->dev, activate_ssm, SSM_STATES); + struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(idev), activate_ssm, SSM_STATES); fpi_ssm_set_user_data(ssm, idev); fpi_ssm_start(ssm, dev_open_callback); return 0; @@ -745,11 +747,14 @@ static int dev_open(struct fp_img_dev *idev, unsigned long driver_data) /* Close device */ static void dev_close(struct fp_img_dev *idev) { + struct vfs_dev_t *vdev; + /* Release private structure */ - g_free(idev->priv); + vdev = fpi_imgdev_get_user_data(idev); + g_free(vdev); /* Release usb interface */ - libusb_release_interface(idev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(idev), 0); /* Notify close complete */ fpi_imgdev_close_complete(idev); diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 764628ae..3304b1f9 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -184,7 +184,7 @@ static int result_code(struct fp_img_dev *dev, int result) return result; /* Return result code */ - if (dev->action == IMG_ACTION_ENROLL) + if (fpi_imgdev_get_action(dev) == IMG_ACTION_ENROLL) return result_codes[0][result]; else return result_codes[1][result]; @@ -201,7 +201,7 @@ static void async_send_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Cleanup transfer */ vdev->transfer = NULL; @@ -245,7 +245,7 @@ out: static void async_send(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); int r; /* Allocation of transfer */ @@ -265,7 +265,7 @@ static void async_send(struct fpi_ssm *ssm) vdev->buffer[1] = byte(1, vdev->seqnum); /* Prepare bulk transfer */ - libusb_fill_bulk_transfer(vdev->transfer, dev->udev, EP_OUT(1), vdev->buffer, vdev->length, async_send_cb, ssm, BULK_TIMEOUT); + libusb_fill_bulk_transfer(vdev->transfer, fpi_imgdev_get_usb_dev(dev), EP_OUT(1), vdev->buffer, vdev->length, async_send_cb, ssm, BULK_TIMEOUT); /* Submit transfer */ r = libusb_submit_transfer(vdev->transfer); @@ -285,7 +285,7 @@ static void async_recv_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Cleanup transfer */ vdev->transfer = NULL; @@ -332,7 +332,7 @@ out: static void async_recv(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); int r; /* Allocation of transfer */ @@ -347,7 +347,7 @@ static void async_recv(struct fpi_ssm *ssm) } /* Prepare bulk transfer */ - libusb_fill_bulk_transfer(vdev->transfer, dev->udev, EP_IN(1), vdev->buffer, 0x0f, async_recv_cb, ssm, BULK_TIMEOUT); + libusb_fill_bulk_transfer(vdev->transfer, fpi_imgdev_get_usb_dev(dev), EP_IN(1), vdev->buffer, 0x0f, async_recv_cb, ssm, BULK_TIMEOUT); /* Submit transfer */ r = libusb_submit_transfer(vdev->transfer); @@ -369,7 +369,7 @@ static void async_load_cb(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Cleanup transfer */ vdev->transfer = NULL; @@ -433,7 +433,7 @@ out: static void async_load(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); unsigned char *buffer; int r; @@ -452,7 +452,7 @@ static void async_load(struct fpi_ssm *ssm) buffer = vdev->buffer + vdev->length; /* Prepare bulk transfer */ - libusb_fill_bulk_transfer(vdev->transfer, dev->udev, EP_IN(2), buffer, VFS_BLOCK_SIZE, async_load_cb, ssm, BULK_TIMEOUT); + libusb_fill_bulk_transfer(vdev->transfer, fpi_imgdev_get_usb_dev(dev), EP_IN(2), buffer, VFS_BLOCK_SIZE, async_load_cb, ssm, BULK_TIMEOUT); /* Submit transfer */ r = libusb_submit_transfer(vdev->transfer); @@ -472,7 +472,7 @@ static void async_sleep_cb(void *data) { struct fpi_ssm *ssm = data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Cleanup timeout */ vdev->timeout = NULL; @@ -484,7 +484,7 @@ static void async_sleep_cb(void *data) static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Add timeout */ vdev->timeout = fpi_timeout_add(msec, async_sleep_cb, ssm); @@ -527,7 +527,7 @@ static void m_swap_state(struct fpi_ssm *ssm) static void m_swap(struct fpi_ssm *ssm, unsigned char *data, size_t length) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *subsm; /* Prepare data for sending */ @@ -536,7 +536,7 @@ static void m_swap(struct fpi_ssm *ssm, unsigned char *data, size_t length) vdev->length = length; /* Start swap ssm */ - subsm = fpi_ssm_new(dev->dev, m_swap_state, M_SWAP_NUM_STATES); + subsm = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_swap_state, M_SWAP_NUM_STATES); fpi_ssm_set_user_data(subsm, dev); fpi_ssm_start_subsm(ssm, subsm); } @@ -626,7 +626,7 @@ static void vfs_get_finger_state(struct fpi_ssm *ssm) static void vfs_img_load(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); G_DEBUG_HERE(); @@ -644,10 +644,10 @@ static void vfs_img_load(struct fpi_ssm *ssm) /* Check if action is completed */ static int action_completed(struct fp_img_dev *dev) { - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); - if ((dev->action == IMG_ACTION_ENROLL) && - (vdev->enroll_stage < fpi_dev_get_nr_enroll_stages(dev->dev))) + if ((fpi_imgdev_get_action(dev) == IMG_ACTION_ENROLL) && + (vdev->enroll_stage < fpi_dev_get_nr_enroll_stages(fpi_imgdev_get_dev(dev)))) /* Enroll not completed, return false */ return FALSE; @@ -757,7 +757,7 @@ static void img_copy(struct vfs101_dev *vdev, struct fp_img *img) static void img_extract(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); struct fp_img *img; /* Screen image to remove noise and find top and bottom line */ @@ -787,28 +787,28 @@ static void img_extract(struct fpi_ssm *ssm) fpi_imgdev_image_captured(dev, img); /* Check captured result */ - if (dev->action_result >= 0 && - dev->action_result != FP_ENROLL_RETRY && - dev->action_result != FP_VERIFY_RETRY) + if (fpi_imgdev_get_action_result(dev) >= 0 && + fpi_imgdev_get_action_result(dev) != FP_ENROLL_RETRY && + fpi_imgdev_get_action_result(dev) != FP_VERIFY_RETRY) { /* Image captured, increase enroll stage */ vdev->enroll_stage++; /* Check if action is completed */ if (!action_completed(dev)) - dev->action_result = FP_ENROLL_PASS; + fpi_imgdev_set_action_result(dev, FP_ENROLL_PASS); } else { /* Image capture failed */ - if (dev->action == IMG_ACTION_ENROLL) + if (fpi_imgdev_get_action(dev) == IMG_ACTION_ENROLL) /* Return retry */ - dev->action_result = result_code(dev, RESULT_RETRY); + fpi_imgdev_set_action_result(dev, result_code(dev, RESULT_RETRY)); else { /* Return no match */ vdev->enroll_stage++; - dev->action_result = FP_VERIFY_NO_MATCH; + fpi_imgdev_set_action_result(dev, FP_VERIFY_NO_MATCH); } } @@ -915,7 +915,7 @@ enum static void m_loop_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Check action state */ if (!vdev->active) @@ -1179,7 +1179,7 @@ enum static void m_init_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Check action state */ if (!vdev->active) @@ -1420,7 +1420,7 @@ static void m_init_state(struct fpi_ssm *ssm) static void m_init_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm_loop; if (!fpi_ssm_get_error(ssm) && vdev->active) @@ -1429,7 +1429,7 @@ static void m_init_complete(struct fpi_ssm *ssm) fpi_imgdev_activate_complete(dev, 0); /* Start loop ssm */ - ssm_loop = fpi_ssm_new(dev->dev, m_loop_state, M_LOOP_NUM_STATES); + ssm_loop = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_loop_state, M_LOOP_NUM_STATES); fpi_ssm_set_user_data(ssm_loop, dev); fpi_ssm_start(ssm_loop, m_loop_complete); } @@ -1441,7 +1441,7 @@ static void m_init_complete(struct fpi_ssm *ssm) /* Activate device */ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); struct fpi_ssm *ssm; /* Check if already active */ @@ -1464,7 +1464,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) vdev->enroll_stage = 0; /* Start init ssm */ - ssm = fpi_ssm_new(dev->dev, m_init_state, M_INIT_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_init_state, M_INIT_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, m_init_complete); @@ -1474,7 +1474,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) /* Deactivate device */ static void dev_deactivate(struct fp_img_dev *dev) { - struct vfs101_dev *vdev = dev->priv; + struct vfs101_dev *vdev = fpi_imgdev_get_user_data(dev); /* Reset active state */ vdev->active = FALSE; @@ -1494,7 +1494,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) int r; /* Claim usb interface */ - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { /* Interface not claimed, return error */ @@ -1505,7 +1505,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) /* Initialize private structure */ vdev = g_malloc0(sizeof(struct vfs101_dev)); vdev->seqnum = -1; - dev->priv = vdev; + fpi_imgdev_set_user_data(dev, vdev); /* Notify open complete */ fpi_imgdev_open_complete(dev, 0); @@ -1516,11 +1516,14 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) /* Close device */ static void dev_close(struct fp_img_dev *dev) { + struct vfs101_dev *vdev; + /* Release private structure */ - g_free(dev->priv); + vdev = fpi_imgdev_get_user_data(dev); + g_free(vdev); /* Release usb interface */ - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); /* Notify close complete */ fpi_imgdev_close_complete(dev); diff --git a/libfprint/drivers/vfs301.c b/libfprint/drivers/vfs301.c index 86c9e600..a34ee31c 100644 --- a/libfprint/drivers/vfs301.c +++ b/libfprint/drivers/vfs301.c @@ -54,7 +54,7 @@ static void async_sleep(unsigned int msec, struct fpi_ssm *ssm) static int submit_image(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - vfs301_dev_t *vdev = dev->priv; + vfs301_dev_t *vdev = fpi_imgdev_get_user_data(dev); int height; struct fp_img *img; @@ -106,11 +106,11 @@ enum static void m_loop_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - vfs301_dev_t *vdev = dev->priv; + vfs301_dev_t *vdev = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case M_REQUEST_PRINT: - vfs301_proto_request_fingerprint(dev->udev, vdev); + vfs301_proto_request_fingerprint(fpi_imgdev_get_usb_dev(dev), vdev); fpi_ssm_next_state(ssm); break; @@ -120,7 +120,7 @@ static void m_loop_state(struct fpi_ssm *ssm) break; case M_CHECK_PRINT: - if (!vfs301_proto_peek_event(dev->udev, vdev)) + if (!vfs301_proto_peek_event(fpi_imgdev_get_usb_dev(dev), vdev)) fpi_ssm_jump_to_state(ssm, M_WAIT_PRINT); else fpi_ssm_next_state(ssm); @@ -128,7 +128,7 @@ static void m_loop_state(struct fpi_ssm *ssm) case M_READ_PRINT_START: fpi_imgdev_report_finger_status(dev, TRUE); - vfs301_proto_process_event_start(dev->udev, vdev); + vfs301_proto_process_event_start(fpi_imgdev_get_usb_dev(dev), vdev); fpi_ssm_next_state(ssm); break; @@ -139,7 +139,7 @@ static void m_loop_state(struct fpi_ssm *ssm) case M_READ_PRINT_POLL: { - int rv = vfs301_proto_process_event_poll(dev->udev, vdev); + int rv = vfs301_proto_process_event_poll(fpi_imgdev_get_usb_dev(dev), vdev); g_assert(rv != VFS301_FAILURE); if (rv == VFS301_ONGOING) fpi_ssm_jump_to_state(ssm, M_READ_PRINT_WAIT); @@ -171,11 +171,11 @@ static void m_loop_complete(struct fpi_ssm *ssm) static void m_init_state(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - vfs301_dev_t *vdev = dev->priv; + vfs301_dev_t *vdev = fpi_imgdev_get_user_data(dev); g_assert(fpi_ssm_get_cur_state(ssm) == 0); - vfs301_proto_init(dev->udev, vdev); + vfs301_proto_init(fpi_imgdev_get_usb_dev(dev), vdev); fpi_ssm_mark_completed(ssm); } @@ -191,7 +191,7 @@ static void m_init_complete(struct fpi_ssm *ssm) fpi_imgdev_activate_complete(dev, 0); /* Start loop ssm */ - ssm_loop = fpi_ssm_new(dev->dev, m_loop_state, M_LOOP_NUM_STATES); + ssm_loop = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_loop_state, M_LOOP_NUM_STATES); fpi_ssm_set_user_data(ssm_loop, dev); fpi_ssm_start(ssm_loop, m_loop_complete); } @@ -206,7 +206,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) struct fpi_ssm *ssm; /* Start init ssm */ - ssm = fpi_ssm_new(dev->dev, m_init_state, 1); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), m_init_state, 1); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, m_init_complete); @@ -225,7 +225,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) int r; /* Claim usb interface */ - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r < 0) { /* Interface not claimed, return error */ fp_err("could not claim interface 0: %s", libusb_error_name(r)); @@ -234,7 +234,7 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) /* Initialize private structure */ vdev = g_malloc0(sizeof(vfs301_dev_t)); - dev->priv = vdev; + fpi_imgdev_set_user_data(dev, vdev); vdev->scanline_buf = malloc(0); vdev->scanline_count = 0; @@ -247,12 +247,15 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) static void dev_close(struct fp_img_dev *dev) { + vfs301_dev_t *vdev; + /* Release private structure */ - free(((vfs301_dev_t*)dev->priv)->scanline_buf); - g_free(dev->priv); + vdev = fpi_imgdev_get_user_data(dev); + free(vdev->scanline_buf); + g_free(vdev); /* Release usb interface */ - libusb_release_interface(dev->udev, 0); + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); /* Notify close complete */ fpi_imgdev_close_complete(dev); diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 4d198223..14799a90 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -196,7 +196,7 @@ static void usbexchange_loop(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, data->device->udev, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(data->device), action->endpoint, action->data, action->size, async_send_cb, ssm, data->timeout); @@ -212,7 +212,7 @@ static void usbexchange_loop(struct fpi_ssm *ssm) fpi_ssm_mark_aborted(ssm, -ENOMEM); return; } - libusb_fill_bulk_transfer(transfer, data->device->udev, + libusb_fill_bulk_transfer(transfer, fpi_imgdev_get_usb_dev(data->device), action->endpoint, data->receive_buf, action->size, async_recv_cb, ssm, data->timeout); @@ -236,7 +236,7 @@ static void usbexchange_loop(struct fpi_ssm *ssm) static void usb_exchange_async(struct fpi_ssm *ssm, struct usbexchange_data *data) { - struct fpi_ssm *subsm = fpi_ssm_new(data->device->dev, + struct fpi_ssm *subsm = fpi_ssm_new(fpi_imgdev_get_dev(data->device), usbexchange_loop, data->stepcount); fpi_ssm_set_user_data(subsm, data); @@ -416,7 +416,9 @@ static void chunk_capture_callback(struct libusb_transfer *transfer) { struct fpi_ssm *ssm = (struct fpi_ssm *)transfer->user_data; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; + + data = fpi_imgdev_get_user_data(dev); if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) || (transfer->status == LIBUSB_TRANSFER_TIMED_OUT)) { @@ -660,10 +662,12 @@ static void activate_loop(struct fpi_ssm *ssm) enum {READ_TIMEOUT = 0}; struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; int r; struct fpi_timeout *timeout; + data = fpi_imgdev_get_user_data(dev); + fp_dbg("main_loop: state %d", fpi_ssm_get_cur_state(ssm)); if (data->deactivating) { @@ -695,7 +699,7 @@ static void activate_loop(struct fpi_ssm *ssm) break; case DEV_ACTIVATE_READ_DATA: - r = capture_chunk_async(data, dev->udev, CAPTURE_LINES, + r = capture_chunk_async(data, fpi_imgdev_get_usb_dev(dev), CAPTURE_LINES, READ_TIMEOUT, ssm); if (r != 0) { fp_err("Failed to capture data"); @@ -733,9 +737,11 @@ static void activate_loop(struct fpi_ssm *ssm) static void activate_loop_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; int r = fpi_ssm_get_error(ssm); + data = fpi_imgdev_get_user_data(dev); + fp_dbg("finishing"); if (data->init_sequence.receive_buf != NULL) g_free(data->init_sequence.receive_buf); @@ -761,7 +767,9 @@ static void activate_loop_complete(struct fpi_ssm *ssm) static void open_loop(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; + + data = fpi_imgdev_get_user_data(dev); switch (fpi_ssm_get_cur_state(ssm)) { case DEV_OPEN_START: @@ -780,8 +788,9 @@ static void open_loop(struct fpi_ssm *ssm) static void open_loop_complete(struct fpi_ssm *ssm) { struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; + data = fpi_imgdev_get_user_data(dev); g_free(data->init_sequence.receive_buf); data->init_sequence.receive_buf = NULL; @@ -798,22 +807,22 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) data = (struct vfs5011_data *)g_malloc0(sizeof(*data)); data->capture_buffer = (unsigned char *)g_malloc0(CAPTURE_LINES * VFS5011_LINE_SIZE); - dev->priv = data; + fpi_imgdev_set_user_data(dev, data); - r = libusb_reset_device(dev->udev); + r = libusb_reset_device(fpi_imgdev_get_usb_dev(dev)); if (r != 0) { fp_err("Failed to reset the device"); return r; } - r = libusb_claim_interface(dev->udev, 0); + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); if (r != 0) { fp_err("Failed to claim interface: %s", libusb_error_name(r)); return r; } struct fpi_ssm *ssm; - ssm = fpi_ssm_new(dev->dev, open_loop, DEV_OPEN_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), open_loop, DEV_OPEN_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fpi_ssm_start(ssm, open_loop_complete); @@ -822,8 +831,9 @@ static int dev_open(struct fp_img_dev *dev, unsigned long driver_data) static void dev_close(struct fp_img_dev *dev) { - libusb_release_interface(dev->udev, 0); - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + libusb_release_interface(fpi_imgdev_get_usb_dev(dev), 0); + struct vfs5011_data *data; + data = fpi_imgdev_get_user_data(dev); if (data != NULL) { g_free(data->capture_buffer); g_slist_free_full(data->rows, g_free); @@ -834,12 +844,13 @@ static void dev_close(struct fp_img_dev *dev) static void start_scan(struct fp_img_dev *dev) { - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; struct fpi_ssm *ssm; + data = fpi_imgdev_get_user_data(dev); data->loop_running = TRUE; fp_dbg("creating ssm"); - ssm = fpi_ssm_new(dev->dev, activate_loop, DEV_ACTIVATE_NUM_STATES); + ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), activate_loop, DEV_ACTIVATE_NUM_STATES); fpi_ssm_set_user_data(ssm, dev); fp_dbg("starting ssm"); fpi_ssm_start(ssm, activate_loop_complete); @@ -848,8 +859,9 @@ static void start_scan(struct fp_img_dev *dev) static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) { - struct vfs5011_data *data = (struct vfs5011_data *)dev->priv; + struct vfs5011_data *data; + data = fpi_imgdev_get_user_data(dev); fp_dbg("device initialized"); data->deactivating = FALSE; @@ -861,7 +873,9 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) static void dev_deactivate(struct fp_img_dev *dev) { int r; - struct vfs5011_data *data = dev->priv; + struct vfs5011_data *data; + + data = fpi_imgdev_get_user_data(dev); if (data->loop_running) { data->deactivating = TRUE; if (data->flying_transfer) { diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index 0bbfde86..c6687a78 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -110,24 +110,16 @@ enum fp_imgdev_verify_state { IMG_VERIFY_STATE_ACTIVATING }; -struct fp_img_dev { - struct fp_dev *dev; - libusb_device_handle *udev; - enum fp_imgdev_action action; - int action_state; - - struct fp_print_data *acquire_data; - struct fp_print_data *enroll_data; - struct fp_img *acquire_img; - int enroll_stage; - int action_result; - - /* FIXME: better place to put this? */ - size_t identify_match_offset; - - void *priv; -}; - +struct fp_img_dev; +libusb_device_handle *fpi_imgdev_get_usb_dev(struct fp_img_dev *dev); +void fpi_imgdev_set_user_data(struct fp_img_dev *imgdev, + void *user_data); +void *fpi_imgdev_get_user_data(struct fp_img_dev *imgdev); +struct fp_dev *fpi_imgdev_get_dev(struct fp_img_dev *imgdev); +enum fp_imgdev_enroll_state fpi_imgdev_get_action_state(struct fp_img_dev *imgdev); +enum fp_imgdev_action fpi_imgdev_get_action(struct fp_img_dev *imgdev); +int fpi_imgdev_get_action_result(struct fp_img_dev *imgdev); +void fpi_imgdev_set_action_result(struct fp_img_dev *imgdev, int action_result); int fpi_imgdev_get_img_width(struct fp_img_dev *imgdev); int fpi_imgdev_get_img_height(struct fp_img_dev *imgdev); diff --git a/libfprint/img.c b/libfprint/img.c index d0ca6fb9..2f195af4 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -536,6 +536,56 @@ API_EXPORTED struct fp_minutia **fp_img_get_minutiae(struct fp_img *img, return img->minutiae->list; } +libusb_device_handle * +fpi_imgdev_get_usb_dev(struct fp_img_dev *dev) +{ + return dev->udev; +} + +void +fpi_imgdev_set_user_data(struct fp_img_dev *imgdev, + void *user_data) +{ + imgdev->priv = user_data; +} + +void * +fpi_imgdev_get_user_data(struct fp_img_dev *imgdev) +{ + return imgdev->priv; +} + +struct fp_dev * +fpi_imgdev_get_dev(struct fp_img_dev *imgdev) +{ + return imgdev->dev; +} + +enum fp_imgdev_enroll_state +fpi_imgdev_get_action_state(struct fp_img_dev *imgdev) +{ + return imgdev->action_state; +} + +enum fp_imgdev_action +fpi_imgdev_get_action(struct fp_img_dev *imgdev) +{ + return imgdev->action; +} + +int +fpi_imgdev_get_action_result(struct fp_img_dev *imgdev) +{ + return imgdev->action_result; +} + +void +fpi_imgdev_set_action_result(struct fp_img_dev *imgdev, + int action_result) +{ + imgdev->action_result = action_result; +} + /* Calculate squared standand deviation */ int fpi_std_sq_dev(const unsigned char *buf, int size) { From 475250ce7180bddf0bb4028140350b30c49d55b9 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:11:19 +0200 Subject: [PATCH 105/141] lib: Split off some polling related functions --- libfprint/drivers_api.h | 8 -------- libfprint/fp_internal.h | 5 ----- 2 files changed, 13 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index c6687a78..a29cd739 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -180,11 +180,6 @@ struct fp_img_driver { #include "drivers_definitions.h" -extern libusb_context *fpi_usb_ctx; -extern GSList *opened_devices; - -void fpi_img_driver_setup(struct fp_img_driver *idriver); - struct fp_dscv_dev { struct libusb_device *udev; struct fp_driver *drv; @@ -291,9 +286,6 @@ struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned /* polling and timeouts */ -void fpi_poll_init(void); -void fpi_poll_exit(void); - typedef void (*fpi_timeout_fn)(void *data); struct fpi_timeout; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 57d1e351..1ddde5fd 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -343,11 +343,6 @@ void fpi_poll_exit(void); typedef void (*fpi_timeout_fn)(void *data); -struct fpi_timeout; -struct fpi_timeout *fpi_timeout_add(unsigned int msec, fpi_timeout_fn callback, - void *data); -void fpi_timeout_cancel(struct fpi_timeout *timeout); - /* async drv <--> lib comms */ struct fpi_ssm; From b7cce4d91db761f6876e6749b0c3b9037a846b93 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:11:52 +0200 Subject: [PATCH 106/141] lib: Make fp_minutiae opaque And fp_minutia private. --- libfprint/drivers_api.h | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index a29cd739..9f955122 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -231,26 +231,7 @@ gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1, enum fp_print_data_type type1, uint16_t driver_id2, uint32_t devtype2, enum fp_print_data_type type2); -struct fp_minutia { - int x; - int y; - int ex; - int ey; - int direction; - double reliability; - int type; - int appearing; - int feature_id; - int *nbrs; - int *ridge_counts; - int num_nbrs; -}; - -struct fp_minutiae { - int alloc; - int num; - struct fp_minutia **list; -}; +struct fp_minutiae; /* bit values for fp_img.flags */ #define FP_IMG_V_FLIPPED (1<<0) From 4547ff0c1902418feec9933f995f8e8e00e89547 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:18:14 +0200 Subject: [PATCH 107/141] lib: Remove a number of data types from drivers API They're unused in drivers. --- libfprint/drivers_api.h | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index 9f955122..63332633 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -180,20 +180,6 @@ struct fp_img_driver { #include "drivers_definitions.h" -struct fp_dscv_dev { - struct libusb_device *udev; - struct fp_driver *drv; - unsigned long driver_data; - uint32_t devtype; -}; - -struct fp_dscv_print { - uint16_t driver_id; - uint32_t devtype; - enum fp_finger finger; - char *path; -}; - enum fp_print_data_type { PRINT_DATA_RAW = 0, /* memset-imposed default */ PRINT_DATA_NBIS_MINUTIAE, @@ -211,19 +197,6 @@ struct fp_print_data { GSList *prints; }; -struct fpi_print_data_fp2 { - char prefix[3]; - uint16_t driver_id; - uint32_t devtype; - unsigned char data_type; - unsigned char data[0]; -} __attribute__((__packed__)); - -struct fpi_print_data_item_fp2 { - uint32_t length; - unsigned char data[0]; -} __attribute__((__packed__)); - void fpi_data_exit(void); struct fp_print_data *fpi_print_data_new(struct fp_dev *dev); struct fp_print_data_item *fpi_print_data_item_new(size_t length); From 0c4e3bb1c44263fe0e37eb6d7254bbbcbabcfdd0 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:21:47 +0200 Subject: [PATCH 108/141] lib: Remove drivers definitions from drivers API --- libfprint/drivers/upeksonly.c | 85 ++++++++++++++++++----------------- libfprint/drivers_api.h | 2 - 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 3827e1fc..9cccb865 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -1328,47 +1328,7 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) return 0; } -static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) -{ - int r; - struct sonly_dev *sdev; - - r = libusb_set_configuration(fpi_imgdev_get_usb_dev(dev), 1); - if (r < 0) { - fp_err("could not set configuration 1"); - return r; - } - - r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); - if (r < 0) { - fp_err("could not claim interface 0: %s", libusb_error_name(r)); - return r; - } - - sdev = g_malloc0(sizeof(struct sonly_dev)); - fpi_imgdev_set_user_data(dev, sdev); - sdev->dev_model = (int)driver_data; - switch (driver_data) { - case UPEKSONLY_1000: - sdev->img_width = IMG_WIDTH_1000; - upeksonly_driver.img_width = IMG_WIDTH_1000; - assembling_ctx.line_width = IMG_WIDTH_1000; - break; - case UPEKSONLY_1001: - sdev->img_width = IMG_WIDTH_1001; - upeksonly_driver.img_width = IMG_WIDTH_1001; - upeksonly_driver.bz3_threshold = 25; - assembling_ctx.line_width = IMG_WIDTH_1001; - break; - case UPEKSONLY_2016: - sdev->img_width = IMG_WIDTH_2016; - upeksonly_driver.img_width = IMG_WIDTH_2016; - assembling_ctx.line_width = IMG_WIDTH_2016; - break; - } - fpi_imgdev_open_complete(dev, 0); - return 0; -} +static int dev_init(struct fp_img_dev *dev, unsigned long driver_data); static void dev_deinit(struct fp_img_dev *dev) { @@ -1422,3 +1382,46 @@ struct fp_img_driver upeksonly_driver = { .deactivate = dev_deactivate, }; +static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) +{ + int r; + struct sonly_dev *sdev; + + r = libusb_set_configuration(fpi_imgdev_get_usb_dev(dev), 1); + if (r < 0) { + fp_err("could not set configuration 1"); + return r; + } + + r = libusb_claim_interface(fpi_imgdev_get_usb_dev(dev), 0); + if (r < 0) { + fp_err("could not claim interface 0: %s", libusb_error_name(r)); + return r; + } + + sdev = g_malloc0(sizeof(struct sonly_dev)); + fpi_imgdev_set_user_data(dev, sdev); + sdev->dev_model = (int)driver_data; + switch (driver_data) { + case UPEKSONLY_1000: + sdev->img_width = IMG_WIDTH_1000; + upeksonly_driver.img_width = IMG_WIDTH_1000; + assembling_ctx.line_width = IMG_WIDTH_1000; + break; + case UPEKSONLY_1001: + sdev->img_width = IMG_WIDTH_1001; + upeksonly_driver.img_width = IMG_WIDTH_1001; + upeksonly_driver.bz3_threshold = 25; + assembling_ctx.line_width = IMG_WIDTH_1001; + break; + case UPEKSONLY_2016: + sdev->img_width = IMG_WIDTH_2016; + upeksonly_driver.img_width = IMG_WIDTH_2016; + assembling_ctx.line_width = IMG_WIDTH_2016; + break; + } + fpi_imgdev_open_complete(dev, 0); + return 0; +} + + diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index 63332633..fb885e71 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -178,8 +178,6 @@ struct fp_img_driver { void (*deactivate)(struct fp_img_dev *dev); }; -#include "drivers_definitions.h" - enum fp_print_data_type { PRINT_DATA_RAW = 0, /* memset-imposed default */ PRINT_DATA_NBIS_MINUTIAE, From 6155068f9e132b99b6b169a4c94cfbfee0497733 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:56:49 +0200 Subject: [PATCH 109/141] lib: Split off some fp_img related functions Some are internal, some are for drivers. --- libfprint/drivers_api.h | 7 ------- libfprint/fp_internal.h | 1 - 2 files changed, 8 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index fb885e71..59c7dc65 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -227,13 +227,6 @@ struct fp_img { struct fp_img *fpi_img_new(size_t length); struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *dev); struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize); -gboolean fpi_img_is_sane(struct fp_img *img); -int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, - struct fp_print_data **ret); -int fpi_img_compare_print_data(struct fp_print_data *enrolled_print, - struct fp_print_data *new_print); -int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, - struct fp_print_data **gallery, int match_threshold, size_t *match_offset); struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor); /* polling and timeouts */ diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 1ddde5fd..4d260eec 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -325,7 +325,6 @@ struct fp_img { }; struct fp_img *fpi_img_new(size_t length); -struct fp_img *fpi_img_new_for_imgdev(struct fp_img_dev *dev); struct fp_img *fpi_img_resize(struct fp_img *img, size_t newsize); gboolean fpi_img_is_sane(struct fp_img *img); int fpi_img_to_print_data(struct fp_img_dev *imgdev, struct fp_img *img, From 1bbdf304abdd913b32a1f5f7d2a904298199d4cd Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:57:50 +0200 Subject: [PATCH 110/141] lib: Remove never defined fpi_ssm_has_completed() --- libfprint/drivers_api.h | 1 - libfprint/fp_internal.h | 1 - 2 files changed, 2 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index 59c7dc65..b13aa671 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -254,7 +254,6 @@ struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, void fpi_ssm_free(struct fpi_ssm *machine); void fpi_ssm_start(struct fpi_ssm *machine, ssm_completed_fn callback); void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child); -int fpi_ssm_has_completed(struct fpi_ssm *machine); /* for drivers */ void fpi_ssm_next_state(struct fpi_ssm *machine); diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 4d260eec..197dc95c 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -370,7 +370,6 @@ struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, void fpi_ssm_free(struct fpi_ssm *machine); void fpi_ssm_start(struct fpi_ssm *machine, ssm_completed_fn callback); void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child); -int fpi_ssm_has_completed(struct fpi_ssm *machine); /* for drivers */ void fpi_ssm_next_state(struct fpi_ssm *machine); From cee061b36367653a5d6844471b96e84209b3bc47 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:58:21 +0200 Subject: [PATCH 111/141] lib: fpi_ssm_start_subsm() is only used in drivers --- libfprint/fp_internal.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 197dc95c..f7b2bc88 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -369,7 +369,6 @@ struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, int nr_states); void fpi_ssm_free(struct fpi_ssm *machine); void fpi_ssm_start(struct fpi_ssm *machine, ssm_completed_fn callback); -void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child); /* for drivers */ void fpi_ssm_next_state(struct fpi_ssm *machine); From 2a4893d9463e09485da995b8c9e0bdcd7078c553 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 16:58:47 +0200 Subject: [PATCH 112/141] lib: fp_imgdev_*() functions are only used in drivers --- libfprint/fp_internal.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index f7b2bc88..b4d43e15 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -399,16 +399,5 @@ void fpi_drvcb_report_capture_result(struct fp_dev *dev, int result, struct fp_img *img); void fpi_drvcb_capture_stopped(struct fp_dev *dev); -/* for image drivers */ -void fpi_imgdev_open_complete(struct fp_img_dev *imgdev, int status); -void fpi_imgdev_close_complete(struct fp_img_dev *imgdev); -void fpi_imgdev_activate_complete(struct fp_img_dev *imgdev, int status); -void fpi_imgdev_deactivate_complete(struct fp_img_dev *imgdev); -void fpi_imgdev_report_finger_status(struct fp_img_dev *imgdev, - gboolean present); -void fpi_imgdev_image_captured(struct fp_img_dev *imgdev, struct fp_img *img); -void fpi_imgdev_abort_scan(struct fp_img_dev *imgdev, int result); -void fpi_imgdev_session_error(struct fp_img_dev *imgdev, int error); - #endif From ef807d9d0e7b376fd81df29dc435a0cabb5fe660 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 28 May 2018 17:04:49 +0200 Subject: [PATCH 113/141] lib: s/array_n_elements/G_N_ELEMENTS/ --- libfprint/drivers/aes1660.c | 4 ++-- libfprint/drivers/aes2660.c | 4 ++-- libfprint/drivers/elan.h | 18 +++++++++--------- libfprint/drivers/upektc.c | 4 ++-- libfprint/drivers/uru4000.c | 6 +++--- libfprint/drivers/vfs5011.c | 6 +++--- libfprint/drivers_api.h | 2 -- 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c index c43ae517..bebbf5aa 100644 --- a/libfprint/drivers/aes1660.c +++ b/libfprint/drivers/aes1660.c @@ -50,9 +50,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) fpi_imgdev_set_user_data(dev, aesdev); aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE); aesdev->init_seqs[0] = aes1660_init_1; - aesdev->init_seqs_len[0] = array_n_elements(aes1660_init_1); + aesdev->init_seqs_len[0] = G_N_ELEMENTS(aes1660_init_1); aesdev->init_seqs[1] = aes1660_init_2; - aesdev->init_seqs_len[1] = array_n_elements(aes1660_init_2); + aesdev->init_seqs_len[1] = G_N_ELEMENTS(aes1660_init_2); aesdev->start_imaging_cmd = (unsigned char *)aes1660_start_imaging_cmd; aesdev->start_imaging_cmd_len = sizeof(aes1660_start_imaging_cmd); aesdev->assembling_ctx = &assembling_ctx; diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c index d4b453aa..99646839 100644 --- a/libfprint/drivers/aes2660.c +++ b/libfprint/drivers/aes2660.c @@ -51,9 +51,9 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) aesdev->buffer = g_malloc0(AES2660_FRAME_SIZE + AESX660_HEADER_SIZE); /* No scaling for AES2660 */ aesdev->init_seqs[0] = aes2660_init_1; - aesdev->init_seqs_len[0] = array_n_elements(aes2660_init_1); + aesdev->init_seqs_len[0] = G_N_ELEMENTS(aes2660_init_1); aesdev->init_seqs[1] = aes2660_init_2; - aesdev->init_seqs_len[1] = array_n_elements(aes2660_init_2); + aesdev->init_seqs_len[1] = G_N_ELEMENTS(aes2660_init_2); aesdev->start_imaging_cmd = (unsigned char *)aes2660_start_imaging_cmd; aesdev->start_imaging_cmd_len = sizeof(aes2660_start_imaging_cmd); aesdev->assembling_ctx = &assembling_ctx; diff --git a/libfprint/drivers/elan.h b/libfprint/drivers/elan.h index 1b47dbc6..c929287a 100644 --- a/libfprint/drivers/elan.h +++ b/libfprint/drivers/elan.h @@ -61,7 +61,7 @@ static const struct elan_cmd get_sensor_dim_cmds[] = { }; static const size_t get_sensor_dim_cmds_len = -array_n_elements(get_sensor_dim_cmds); +G_N_ELEMENTS(get_sensor_dim_cmds); static const struct elan_cmd init_start_cmds[] = { { @@ -76,7 +76,7 @@ static const struct elan_cmd init_start_cmds[] = { }, }; -static const size_t init_start_cmds_len = array_n_elements(init_start_cmds); +static const size_t init_start_cmds_len = G_N_ELEMENTS(init_start_cmds); static const struct elan_cmd read_cmds[] = { /* raw frame sizes are calculated from image dimesions reported by the @@ -88,7 +88,7 @@ static const struct elan_cmd read_cmds[] = { }, }; -const size_t read_cmds_len = array_n_elements(read_cmds); +const size_t read_cmds_len = G_N_ELEMENTS(read_cmds); /* issued after data reads during init and calibration */ static const struct elan_cmd init_end_cmds[] = { @@ -99,7 +99,7 @@ static const struct elan_cmd init_end_cmds[] = { }, }; -static const size_t init_end_cmds_len = array_n_elements(init_end_cmds); +static const size_t init_end_cmds_len = G_N_ELEMENTS(init_end_cmds); /* same command 2 times * original driver may observe return value to determine how many times it @@ -118,7 +118,7 @@ static const struct elan_cmd calibrate_start_cmds[] = { }; static const size_t calibrate_start_cmds_len = -array_n_elements(calibrate_start_cmds); +G_N_ELEMENTS(calibrate_start_cmds); /* issued after data reads during init and calibration */ static const struct elan_cmd calibrate_end_cmds[] = { @@ -130,7 +130,7 @@ static const struct elan_cmd calibrate_end_cmds[] = { }; static const size_t calibrate_end_cmds_len = -array_n_elements(calibrate_end_cmds); +G_N_ELEMENTS(calibrate_end_cmds); static const struct elan_cmd capture_start_cmds[] = { /* led on */ @@ -141,7 +141,7 @@ static const struct elan_cmd capture_start_cmds[] = { }, }; -static size_t capture_start_cmds_len = array_n_elements(capture_start_cmds); +static size_t capture_start_cmds_len = G_N_ELEMENTS(capture_start_cmds); static const struct elan_cmd capture_wait_finger_cmds[] = { /* wait for finger @@ -154,7 +154,7 @@ static const struct elan_cmd capture_wait_finger_cmds[] = { }; static size_t capture_wait_finger_cmds_len = -array_n_elements(capture_wait_finger_cmds); +G_N_ELEMENTS(capture_wait_finger_cmds); static const struct elan_cmd deactivate_cmds[] = { /* led off */ @@ -165,7 +165,7 @@ static const struct elan_cmd deactivate_cmds[] = { }, }; -static const size_t deactivate_cmds_len = array_n_elements(deactivate_cmds); +static const size_t deactivate_cmds_len = G_N_ELEMENTS(deactivate_cmds); static void elan_cmd_cb(struct libusb_transfer *transfer); static void elan_cmd_read(struct fpi_ssm *ssm); diff --git a/libfprint/drivers/upektc.c b/libfprint/drivers/upektc.c index 6097c26c..ffa31f33 100644 --- a/libfprint/drivers/upektc.c +++ b/libfprint/drivers/upektc.c @@ -447,14 +447,14 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) upekdev->ep_in = UPEKTC_EP_IN; upekdev->ep_out = UPEKTC_EP_OUT; upekdev->setup_commands = upektc_setup_commands; - upekdev->setup_commands_len = array_n_elements(upektc_setup_commands); + upekdev->setup_commands_len = G_N_ELEMENTS(upektc_setup_commands); upekdev->sum_threshold = UPEKTC_SUM_THRESHOLD; break; case UPEKTC_3001: upekdev->ep_in = UPEKET_EP_IN; upekdev->ep_out = UPEKET_EP_OUT; upekdev->setup_commands = upeket_setup_commands; - upekdev->setup_commands_len = array_n_elements(upeket_setup_commands); + upekdev->setup_commands_len = G_N_ELEMENTS(upeket_setup_commands); upekdev->sum_threshold = UPEKET_SUM_THRESHOLD; break; default: diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 6ed311d3..080edf72 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -664,7 +664,7 @@ static int calc_dev2(struct uru4k_image *img) uint8_t *b[2] = { NULL, NULL }; int res = 0, mean = 0, i, r, j, idx; - for (i = r = idx = 0; i < array_n_elements(img->block_info) && idx < 2; i++) { + for (i = r = idx = 0; i < G_N_ELEMENTS(img->block_info) && idx < 2; i++) { if (img->block_info[i].flags & BLOCKF_NOT_PRESENT) continue; for (j = 0; j < img->block_info[i].num_lines && idx < 2; j++) @@ -747,7 +747,7 @@ static void imaging_run_state(struct fpi_ssm *ssm) key ^= urudev->img_enc_seed; fp_dbg("encryption id %02x -> key %08x", img->key_number, key); - while (urudev->img_block < array_n_elements(img->block_info) && + while (urudev->img_block < G_N_ELEMENTS(img->block_info) && urudev->img_lines_done < img->num_lines) { flags = img->block_info[urudev->img_block].flags; num_lines = img->block_info[urudev->img_block].num_lines; @@ -785,7 +785,7 @@ static void imaging_run_state(struct fpi_ssm *ssm) fpimg = fpi_img_new_for_imgdev(dev); to = r = 0; - for (i = 0; i < array_n_elements(img->block_info) && r < img->num_lines; i++) { + for (i = 0; i < G_N_ELEMENTS(img->block_info) && r < img->num_lines; i++) { flags = img->block_info[i].flags; num_lines = img->block_info[i].num_lines; if (num_lines == 0) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 14799a90..0c50d995 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -679,7 +679,7 @@ static void activate_loop(struct fpi_ssm *ssm) switch (fpi_ssm_get_cur_state(ssm)) { case DEV_ACTIVATE_REQUEST_FPRINT: data->init_sequence.stepcount = - array_n_elements(vfs5011_initiate_capture); + G_N_ELEMENTS(vfs5011_initiate_capture); data->init_sequence.actions = vfs5011_initiate_capture; data->init_sequence.device = dev; if (data->init_sequence.receive_buf == NULL) @@ -721,7 +721,7 @@ static void activate_loop(struct fpi_ssm *ssm) case DEV_ACTIVATE_PREPARE_NEXT_CAPTURE: data->init_sequence.stepcount = - array_n_elements(vfs5011_initiate_capture); + G_N_ELEMENTS(vfs5011_initiate_capture); data->init_sequence.actions = vfs5011_initiate_capture; data->init_sequence.device = dev; if (data->init_sequence.receive_buf == NULL) @@ -774,7 +774,7 @@ static void open_loop(struct fpi_ssm *ssm) switch (fpi_ssm_get_cur_state(ssm)) { case DEV_OPEN_START: data->init_sequence.stepcount = - array_n_elements(vfs5011_initialization); + G_N_ELEMENTS(vfs5011_initialization); data->init_sequence.actions = vfs5011_initialization; data->init_sequence.device = dev; data->init_sequence.receive_buf = diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index b13aa671..b491a05a 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -37,8 +37,6 @@ #include "assembling.h" #include "drivers/driver_ids.h" -#define array_n_elements(array) G_N_ELEMENTS(array) - #define fp_dbg g_debug #define fp_info g_debug #define fp_warn g_warning From 1a376c1bfaba780ec44b9f7f04bc50cba7211e48 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 29 May 2018 10:45:51 +0200 Subject: [PATCH 114/141] lib: Remove 2 more functions from the drivers API --- libfprint/drivers_api.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h index b491a05a..2bf547a1 100644 --- a/libfprint/drivers_api.h +++ b/libfprint/drivers_api.h @@ -156,8 +156,6 @@ struct fp_driver { int (*capture_stop)(struct fp_dev *dev); }; -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) @@ -193,7 +191,6 @@ struct fp_print_data { GSList *prints; }; -void fpi_data_exit(void); struct fp_print_data *fpi_print_data_new(struct fp_dev *dev); struct fp_print_data_item *fpi_print_data_item_new(size_t length); gboolean fpi_print_data_compatible(uint16_t driver_id1, uint32_t devtype1, From ba4967779477297202b927f3a52dbe62405d0233 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 29 May 2018 13:37:19 +0200 Subject: [PATCH 115/141] vfs0050: Rename "udev" to "usb_dev" To reduce confusion with possible future udev usage. --- libfprint/drivers/vfs0050.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libfprint/drivers/vfs0050.c b/libfprint/drivers/vfs0050.c index c4694e6d..dcf5d693 100644 --- a/libfprint/drivers/vfs0050.c +++ b/libfprint/drivers/vfs0050.c @@ -54,12 +54,12 @@ static void async_write_callback(struct libusb_transfer *transfer) static void async_write(struct fpi_ssm *ssm, void *data, int len) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev); struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); vdev->transfer = libusb_alloc_transfer(0); vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; - libusb_fill_bulk_transfer(vdev->transfer, udev, 0x01, data, len, + libusb_fill_bulk_transfer(vdev->transfer, usb_dev, 0x01, data, len, async_write_callback, ssm, VFS_USB_TIMEOUT); libusb_submit_transfer(vdev->transfer); } @@ -96,7 +96,7 @@ static void async_read_callback(struct libusb_transfer *transfer) static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev); struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); ep |= LIBUSB_ENDPOINT_IN; @@ -106,11 +106,11 @@ static void async_read(struct fpi_ssm *ssm, int ep, void *data, int len) /* 0x83 is the only interrupt endpoint */ if (ep == EP3_IN) - libusb_fill_interrupt_transfer(vdev->transfer, udev, ep, data, + libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, ep, data, len, async_read_callback, ssm, VFS_USB_TIMEOUT); else - libusb_fill_bulk_transfer(vdev->transfer, udev, ep, data, len, + libusb_fill_bulk_transfer(vdev->transfer, usb_dev, ep, data, len, async_read_callback, ssm, VFS_USB_TIMEOUT); libusb_submit_transfer(vdev->transfer); @@ -150,7 +150,7 @@ static void async_abort_callback(struct libusb_transfer *transfer) static void async_abort(struct fpi_ssm *ssm, int ep) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev); struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); int len = VFS_USB_BUFFER_SIZE; @@ -164,11 +164,11 @@ static void async_abort(struct fpi_ssm *ssm, int ep) /* 0x83 is the only interrupt endpoint */ if (ep == EP3_IN) - libusb_fill_interrupt_transfer(vdev->transfer, udev, ep, data, + libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, ep, data, len, async_abort_callback, ssm, VFS_USB_ABORT_TIMEOUT); else - libusb_fill_bulk_transfer(vdev->transfer, udev, ep, data, len, + libusb_fill_bulk_transfer(vdev->transfer, usb_dev, ep, data, len, async_abort_callback, ssm, VFS_USB_ABORT_TIMEOUT); libusb_submit_transfer(vdev->transfer); @@ -521,7 +521,7 @@ static void scan_completed(void *data) static void activate_ssm(struct fpi_ssm *ssm) { struct fp_img_dev *idev = fpi_ssm_get_user_data(ssm); - struct libusb_device_handle *udev = fpi_imgdev_get_usb_dev(idev); + struct libusb_device_handle *usb_dev = fpi_imgdev_get_usb_dev(idev); struct vfs_dev_t *vdev = fpi_imgdev_get_user_data(idev); switch (fpi_ssm_get_cur_state(ssm)) { @@ -577,7 +577,7 @@ static void activate_ssm(struct fpi_ssm *ssm) /* Asyncronously enquire an interrupt */ vdev->transfer = libusb_alloc_transfer(0); vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; - libusb_fill_interrupt_transfer(vdev->transfer, udev, 0x83, + libusb_fill_interrupt_transfer(vdev->transfer, usb_dev, 0x83, vdev->interrupt, VFS_INTERRUPT_SIZE, interrupt_callback, ssm, 0); @@ -627,7 +627,7 @@ static void activate_ssm(struct fpi_ssm *ssm) /* Receive chunk of data */ vdev->transfer = libusb_alloc_transfer(0); vdev->transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; - libusb_fill_bulk_transfer(vdev->transfer, udev, 0x82, + libusb_fill_bulk_transfer(vdev->transfer, usb_dev, 0x82, (void *)vdev->lines_buffer + vdev->bytes, VFS_USB_BUFFER_SIZE, receive_callback, ssm, From db34837d2da30c5cbd4cc63c43a73986c144129f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 26 Apr 2018 16:25:18 +0200 Subject: [PATCH 116/141] lib: Simplify device discovery Use GPtrArray instead of open-coding a NULL terminated array. https://bugs.freedesktop.org/show_bug.cgi?id=106279 --- libfprint/core.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index a5daa300..2c42ad51 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -253,11 +253,9 @@ static struct fp_dscv_dev *discover_dev(libusb_device *udev) */ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) { - GSList *tmplist = NULL; - struct fp_dscv_dev **list; + GPtrArray *tmparray; libusb_device *udev; libusb_device **devs; - int dscv_count = 0; int r; int i = 0; @@ -270,11 +268,10 @@ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) return NULL; } + tmparray = g_ptr_array_new (); + /* Check each device against each driver, temporarily storing successfully - * discovered devices in a GSList. - * - * Quite inefficient but excusable as we'll only be dealing with small - * sets of drivers against small sets of USB devices */ + * discovered devices in a GPtrArray. */ while ((udev = devs[i++]) != NULL) { struct fp_dscv_dev *ddev = discover_dev(udev); if (!ddev) @@ -282,25 +279,14 @@ API_EXPORTED struct fp_dscv_dev **fp_discover_devs(void) /* discover_dev() doesn't hold a reference to the udev, * so increase the reference for ddev to hold this ref */ libusb_ref_device(udev); - tmplist = g_slist_prepend(tmplist, (gpointer) ddev); - dscv_count++; + g_ptr_array_add (tmparray, (gpointer) ddev); } libusb_free_device_list(devs, 1); - /* Convert our temporary GSList into a standard NULL-terminated pointer + /* Convert our temporary array into a standard NULL-terminated pointer * array. */ - list = g_malloc(sizeof(*list) * (dscv_count + 1)); - if (dscv_count > 0) { - GSList *elem = tmplist; - i = 0; - do { - list[i++] = elem->data; - } while ((elem = g_slist_next(elem))); - } - list[dscv_count] = NULL; /* NULL-terminate */ - - g_slist_free(tmplist); - return list; + g_ptr_array_add (tmparray, NULL); + return (struct fp_dscv_dev **) g_ptr_array_free (tmparray, FALSE); } /** From 37bb59df131503b2853427053b20b5c90349e1ed Mon Sep 17 00:00:00 2001 From: Timur Celik Date: Sat, 10 Feb 2018 00:37:33 +0100 Subject: [PATCH 117/141] assembling: Fix assembling of frames for non-reverse stripes Every frame stores the delta from the previous frame, in reverse mode it stores the delta to the next frame. This causes images to use the wrong delta while assembling in forward mode. The broken assembling in forward mode will create a small error for linear motion, because the delta of all frames is approximately the same in this case. But if you move your finger, stop and then continue moving in a single scan, the misplaced frames should be visible in the assembled output. This could result in false positives and verification failing. https://bugs.freedesktop.org/show_bug.cgi?id=105027 --- libfprint/assembling.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index 2c4ccc68..ec37a258 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -280,11 +280,18 @@ struct fp_img *fpi_assemble_frames(struct fpi_frame_asmbl_ctx *ctx, do { fpi_frame = stripe->data; - y += fpi_frame->delta_y; - x += fpi_frame->delta_x; + if(reverse) { + y += fpi_frame->delta_y; + x += fpi_frame->delta_x; + } aes_blit_stripe(ctx, img, fpi_frame, x, y); + if(!reverse) { + y += fpi_frame->delta_y; + x += fpi_frame->delta_x; + } + stripe = g_slist_next(stripe); i++; } while (i < stripes_len); From 0215483fb3f41aea0e2a2b95320fcebc3fbc2bb4 Mon Sep 17 00:00:00 2001 From: Timur Celik Date: Sat, 10 Feb 2018 01:29:04 +0100 Subject: [PATCH 118/141] assembling: Fix assembling of last frame in reverse mode The last image is always misplaced because the sign of the delta vector isn't corrected. This could result in false positives and verification failing. https://bugs.freedesktop.org/show_bug.cgi?id=105027 --- libfprint/assembling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index ec37a258..7b9fb799 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -132,8 +132,8 @@ static unsigned int do_movement_estimation(struct fpi_frame_asmbl_ctx *ctx, if (reverse) { find_overlap(ctx, prev_stripe, cur_stripe, &min_error); - prev_stripe->delta_y = -prev_stripe->delta_y; - prev_stripe->delta_x = -prev_stripe->delta_x; + cur_stripe->delta_y = -cur_stripe->delta_y; + cur_stripe->delta_x = -cur_stripe->delta_x; } else find_overlap(ctx, cur_stripe, prev_stripe, &min_error); From dda6857feef60694dac1493b3860a64e4fa5f8f3 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 30 May 2018 15:11:49 +0200 Subject: [PATCH 119/141] assembling: Add guards to fpi_assemble_lines() With the goal of not crashing when we try to malloc MAXINT bytes of RAM. See https://bugzilla.redhat.com/show_bug.cgi?id=1484812 Closes: #42 --- libfprint/assembling.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfprint/assembling.c b/libfprint/assembling.c index 7b9fb799..de8cb342 100644 --- a/libfprint/assembling.c +++ b/libfprint/assembling.c @@ -365,6 +365,9 @@ struct fp_img *fpi_assemble_lines(struct fpi_line_asmbl_ctx *ctx, unsigned char *output = g_malloc0(ctx->line_width * ctx->max_height); struct fp_img *img; + g_return_val_if_fail (lines != NULL, NULL); + g_return_val_if_fail (lines_len > 0, NULL); + fp_dbg("%"G_GINT64_FORMAT, g_get_real_time()); row1 = lines; From 52f84bee3ce1a0367fedf8782542d1d83d20a3d5 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 30 May 2018 15:14:42 +0200 Subject: [PATCH 120/141] vfs5011: Error out when no lines were captured Which avoids passing zero lines to fpi_assemble_lines() "gmem.c:130: failed to allocate 18446744073709551612 bytes" #3 0x00007fe4f6ef428f in g_log (log_domain=log_domain@entry=0x7fe4f6f3506e "GLib", log_level=log_level@entry=G_LOG_LEVEL_ERROR, format=format@entry=0x7fe4f6f3e610 "%s: failed to allocate %lu bytes") at gmessages.c:1398 #4 0x00007fe4f6ef2ac4 in g_malloc0 (n_bytes=n_bytes@entry=18446744073709551612) at gmem.c:129 #5 0x00007fe4f8052020 in median_filter (filtersize=25, size=-1, data=0x0) at assembling.c:309 #6 fpi_assemble_lines (ctx=ctx@entry=0x7fe4f82ac3c0 , lines=0x0, lines_len=0) at assembling.c:389 #7 0x00007fe4f805f3db in submit_image (ssm=ssm@entry=0x16c3cba360, data=data@entry=0x16c3cb9cc0) at drivers/vfs5011.c:412 See https://bugzilla.redhat.com/show_bug.cgi?id=1484812 Closes: #42 --- libfprint/drivers/vfs5011.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index 0c50d995..8b460acf 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -400,6 +400,14 @@ void submit_image(struct fpi_ssm *ssm, struct vfs5011_data *data) struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm); struct fp_img *img; + if (data->lines_recorded == 0) { + /* == FP_ENROLL_RETRY_TOO_SHORT */ + fpi_imgdev_session_error(dev, FP_VERIFY_RETRY_TOO_SHORT); + return; + } + + g_assert (data->rows != NULL); + data->rows = g_slist_reverse(data->rows); img = fpi_assemble_lines(&assembling_ctx, data->rows, data->lines_recorded); From b3f6ff5a365abc3d4650d47e4fa1e4f0622dd017 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 30 May 2018 17:17:11 +0200 Subject: [PATCH 121/141] lib: Add guard to async functions To avoid having NULL devices being passed dereferenced. --- libfprint/async.c | 60 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/libfprint/async.c b/libfprint/async.c index f469a36f..35da8758 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -47,11 +47,15 @@ void fpi_drvcb_open_complete(struct fp_dev *dev, int status) API_EXPORTED int fp_async_dev_open(struct fp_dscv_dev *ddev, fp_dev_open_cb callback, void *user_data) { - struct fp_driver *drv = ddev->drv; + struct fp_driver *drv; struct fp_dev *dev; libusb_device_handle *udevh; int r; + g_return_val_if_fail(ddev != NULL, -ENODEV); + + drv = ddev->drv; + G_DEBUG_HERE(); r = libusb_open(ddev->udev, &udevh); if (r < 0) { @@ -104,7 +108,11 @@ void fpi_drvcb_close_complete(struct fp_dev *dev) API_EXPORTED void fp_async_dev_close(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; + + g_return_if_fail (dev != NULL); + + drv = dev->drv; if (g_slist_index(opened_devices, (gconstpointer) dev) == -1) fp_err("device %p not in opened list!", dev); @@ -152,9 +160,13 @@ void fpi_drvcb_enroll_started(struct fp_dev *dev, int status) API_EXPORTED int fp_async_enroll_start(struct fp_dev *dev, fp_enroll_stage_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + if (!dev->nr_enroll_stages || !drv->enroll_start) { fp_err("driver %s has 0 enroll stages or no enroll func", drv->name); @@ -214,9 +226,13 @@ void fpi_drvcb_enroll_stopped(struct fp_dev *dev) API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); if (!drv->enroll_start) return -ENOTSUP; @@ -252,9 +268,13 @@ API_EXPORTED int fp_async_enroll_stop(struct fp_dev *dev, API_EXPORTED int fp_async_verify_start(struct fp_dev *dev, struct fp_print_data *data, fp_img_operation_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); if (!drv->verify_start) return -ENOTSUP; @@ -328,10 +348,14 @@ void fpi_drvcb_verify_stopped(struct fp_dev *dev) API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; gboolean iterating = (dev->state == DEV_STATE_VERIFYING); int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_ERROR && dev->state != DEV_STATE_VERIFYING @@ -370,9 +394,13 @@ API_EXPORTED int fp_async_verify_stop(struct fp_dev *dev, API_EXPORTED int fp_async_identify_start(struct fp_dev *dev, struct fp_print_data **gallery, fp_identify_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); if (!drv->identify_start) return -ENOTSUP; @@ -436,10 +464,14 @@ void fpi_drvcb_report_identify_result(struct fp_dev *dev, int result, API_EXPORTED int fp_async_identify_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; gboolean iterating = (dev->state == DEV_STATE_IDENTIFYING); int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_IDENTIFYING && dev->state != DEV_STATE_IDENTIFY_DONE); @@ -488,9 +520,13 @@ void fpi_drvcb_identify_stopped(struct fp_dev *dev) API_EXPORTED int fp_async_capture_start(struct fp_dev *dev, int unconditional, fp_img_operation_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); if (!drv->capture_start) return -ENOTSUP; @@ -563,9 +599,13 @@ void fpi_drvcb_capture_stopped(struct fp_dev *dev) API_EXPORTED int fp_async_capture_stop(struct fp_dev *dev, fp_operation_stop_cb callback, void *user_data) { - struct fp_driver *drv = dev->drv; + struct fp_driver *drv; int r; + g_return_val_if_fail(dev != NULL, -ENODEV); + + drv = dev->drv; + G_DEBUG_HERE(); BUG_ON(dev->state != DEV_STATE_ERROR && dev->state != DEV_STATE_CAPTURING From c91819f551d69e720d55dc326c3e8fbf8f12c645 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 31 May 2018 10:56:46 +0200 Subject: [PATCH 122/141] lib: Remove drv->close absence support in fp_async_dev_close() The driver will at least need to close its hardware resources, and free memory, so it must have had one. This case was never actually used as can be seen from the fact that we would assert in fpi_drvcb_close_complete() if the state was wrong but never set it to the expected value. --- libfprint/async.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libfprint/async.c b/libfprint/async.c index 35da8758..7051ee70 100644 --- a/libfprint/async.c +++ b/libfprint/async.c @@ -114,18 +114,14 @@ API_EXPORTED void fp_async_dev_close(struct fp_dev *dev, drv = dev->drv; + g_return_if_fail (drv->close != NULL); + if (g_slist_index(opened_devices, (gconstpointer) dev) == -1) fp_err("device %p not in opened list!", dev); opened_devices = g_slist_remove(opened_devices, (gconstpointer) dev); dev->close_cb = callback; dev->close_cb_data = user_data; - - if (!drv->close) { - fpi_drvcb_close_complete(dev); - return; - } - dev->state = DEV_STATE_DEINITIALIZING; drv->close(dev); } From 2fbc77955ea7afb661ef818bb8a767dcedb5f797 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 31 May 2018 12:18:17 +0200 Subject: [PATCH 123/141] build: Add CI Barebones, just compiles libfprint. --- .gitlab-ci.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..13fb064e --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,19 @@ +image: fedora:rawhide +stages: + - build + +variables: + DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc + + +before_script: + - dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES + + +build: + stage: build + script: + - meson . _build + - ninja -C _build + - ninja -C _build install + From 92231d984f3f3fd97c942ba6b2185c05db92db04 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 31 May 2018 12:23:30 +0200 Subject: [PATCH 124/141] build: Add some missing build essentials --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 13fb064e..adb75753 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,7 @@ stages: variables: DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc + gcc gcc-c++ glibc-devel before_script: From 79d65c907fad1ab4faae9fdc51e8d437bcf56c0f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 31 May 2018 12:30:48 +0200 Subject: [PATCH 125/141] build: Add missing X11 deps for the examples --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index adb75753..05e83068 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: DEPENDENCIES: libusb1-devel glib2-devel nss-devel pixman-devel systemd meson gtk-doc - gcc gcc-c++ glibc-devel + gcc gcc-c++ glibc-devel libX11-devel libXv-devel before_script: From 31bad8ddd2c9119f36f15f8a073f38dfff9156e4 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 31 May 2018 14:35:16 +0200 Subject: [PATCH 126/141] build: Fix fprint.h install destination Since the port to meson, fprint.h was installing to $includedir instead of $includedir/libfprint/ --- libfprint/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/meson.build b/libfprint/meson.build index f8ea5ff5..eb761896 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -178,7 +178,7 @@ libfprint = library('fprint', libfprint_dep = declare_dependency(link_with: libfprint, include_directories: root_inc) -install_headers(['fprint.h']) +install_headers(['fprint.h'], subdir: 'libfprint') udev_rules = executable('fprint-list-udev-rules', 'fprint-list-udev-rules.c', From aec65777a7f36414a523e63e54742f514ae2a85d Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 3 Jun 2018 00:30:10 +0200 Subject: [PATCH 127/141] nbis: Update links to new website --- libfprint/nbis/bozorth3/bozorth3.c | 2 +- libfprint/nbis/bozorth3/bz_alloc.c | 2 +- libfprint/nbis/bozorth3/bz_drvrs.c | 2 +- libfprint/nbis/bozorth3/bz_gbls.c | 2 +- libfprint/nbis/bozorth3/bz_io.c | 2 +- libfprint/nbis/bozorth3/bz_sort.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libfprint/nbis/bozorth3/bozorth3.c b/libfprint/nbis/bozorth3/bozorth3.c index 12bb0095..54514e73 100644 --- a/libfprint/nbis/bozorth3/bozorth3.c +++ b/libfprint/nbis/bozorth3/bozorth3.c @@ -23,7 +23,7 @@ Do not remove this notice. * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per * the definition in section 734.7(a)(1). * - * For further information, see http://reactivated.net/fprint/US_export_control + * For further information, see https://fprint.freedesktop.org/us-export-control.html */ /******************************************************************************* diff --git a/libfprint/nbis/bozorth3/bz_alloc.c b/libfprint/nbis/bozorth3/bz_alloc.c index 275a1429..5118282a 100644 --- a/libfprint/nbis/bozorth3/bz_alloc.c +++ b/libfprint/nbis/bozorth3/bz_alloc.c @@ -23,7 +23,7 @@ Do not remove this notice. * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per * the definition in section 734.7(a)(1). * - * For further information, see http://reactivated.net/fprint/US_export_control + * For further information, see https://fprint.freedesktop.org/us-export-control.html */ /******************************************************************************* diff --git a/libfprint/nbis/bozorth3/bz_drvrs.c b/libfprint/nbis/bozorth3/bz_drvrs.c index 4ff47570..03f7171c 100644 --- a/libfprint/nbis/bozorth3/bz_drvrs.c +++ b/libfprint/nbis/bozorth3/bz_drvrs.c @@ -23,7 +23,7 @@ Do not remove this notice. * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per * the definition in section 734.7(a)(1). * - * For further information, see http://reactivated.net/fprint/US_export_control + * For further information, see https://fprint.freedesktop.org/us-export-control.html */ /******************************************************************************* diff --git a/libfprint/nbis/bozorth3/bz_gbls.c b/libfprint/nbis/bozorth3/bz_gbls.c index 958c9ee3..0ecd081d 100644 --- a/libfprint/nbis/bozorth3/bz_gbls.c +++ b/libfprint/nbis/bozorth3/bz_gbls.c @@ -23,7 +23,7 @@ Do not remove this notice. * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per * the definition in section 734.7(a)(1). * - * For further information, see http://reactivated.net/fprint/US_export_control + * For further information, see https://fprint.freedesktop.org/us-export-control.html */ /******************************************************************************* diff --git a/libfprint/nbis/bozorth3/bz_io.c b/libfprint/nbis/bozorth3/bz_io.c index 8bb166f2..e5dc3bb9 100644 --- a/libfprint/nbis/bozorth3/bz_io.c +++ b/libfprint/nbis/bozorth3/bz_io.c @@ -23,7 +23,7 @@ Do not remove this notice. * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per * the definition in section 734.7(a)(1). * - * For further information, see http://reactivated.net/fprint/US_export_control + * For further information, see https://fprint.freedesktop.org/us-export-control.html */ /******************************************************************************* diff --git a/libfprint/nbis/bozorth3/bz_sort.c b/libfprint/nbis/bozorth3/bz_sort.c index c7bced36..01371e5b 100644 --- a/libfprint/nbis/bozorth3/bz_sort.c +++ b/libfprint/nbis/bozorth3/bz_sort.c @@ -23,7 +23,7 @@ Do not remove this notice. * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per * the definition in section 734.7(a)(1). * - * For further information, see http://reactivated.net/fprint/US_export_control + * For further information, see https://fprint.freedesktop.org/us-export-control.html */ /******************************************************************************* From b0e4619e0aced0e5c9da71fb6606a20c414e2844 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 3 Jun 2018 00:30:32 +0200 Subject: [PATCH 128/141] docs: Update links to new website --- doc/advanced-topics.xml | 4 ++-- doc/intro.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/advanced-topics.xml b/doc/advanced-topics.xml index 958d2d53..5af6f717 100644 --- a/doc/advanced-topics.xml +++ b/doc/advanced-topics.xml @@ -73,8 +73,8 @@ Each driver is assigned a unique ID by the project maintainer. These assignments are - - documented on the wiki and will never change. + + documented in the sources and will never change. diff --git a/doc/intro.xml b/doc/intro.xml index 5b9e5ece..fa5378af 100644 --- a/doc/intro.xml +++ b/doc/intro.xml @@ -8,7 +8,7 @@ libfprint is an open source library to provide access to fingerprint scanning devices. For more info, see the - libfprint project homepage. + libfprint project homepage. @@ -30,7 +30,7 @@ Feedback on this API and its associated documentation is appreciated. Was anything unclear? Does anything seem unreasonably complicated? Is anything missing? Let us know on the - mailing list. + mailing list. From 878a201bb13d55fb25f5c4bdb8416d4c8d1740e1 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 3 Jun 2018 00:30:52 +0200 Subject: [PATCH 129/141] README: Update links to new website --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 79a1ac9e..c54fb2c9 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ libfprint ========= libfprint is part of the fprint project: -http://www.reactivated.net/fprint +https://fprint.freedesktop.org/ libfprint was originally developed as part of an academic project at the University of Manchester with the aim of hiding differences between different @@ -22,7 +22,7 @@ university computers and the project is not hosted at the university either. For more information on libfprint, supported devices, API documentation, etc., see the homepage: -http://www.reactivated.net/fprint/Libfprint +https://fprint.freedesktop.org/ libfprint is licensed under the GNU LGPL version 2.1. See the COPYING file for the license text. @@ -37,5 +37,5 @@ libfprint includes code from NIST's NBIS software distribution: http://fingerprint.nist.gov/NBIS/index.html We include bozorth3 from the US export controlled distribution. We have determined that it is fine to ship bozorth3 in an open source project, -see http://reactivated.net/fprint/wiki/US_export_control +see https://fprint.freedesktop.org/us-export-control.html From e5393bf46af41a24b98702cb39421e1171f3af4a Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 3 Jun 2018 14:40:34 +0200 Subject: [PATCH 130/141] lib: Add script to print MarkDown page of supported devices --- libfprint/fprint-list-supported-devices.c | 71 +++++++++++++++++++++++ libfprint/meson.build | 13 +++++ 2 files changed, 84 insertions(+) create mode 100644 libfprint/fprint-list-supported-devices.c diff --git a/libfprint/fprint-list-supported-devices.c b/libfprint/fprint-list-supported-devices.c new file mode 100644 index 00000000..8e3c0cef --- /dev/null +++ b/libfprint/fprint-list-supported-devices.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2009 Red Hat + * Copyright (C) 2008 Bastien Nocera + * Copyright (C) 2008 Timo Hoenig , + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "fp_internal.h" + +GHashTable *printed = NULL; + +static void print_driver (struct fp_driver *driver) +{ + int i; + + for (i = 0; driver->id_table[i].vendor != 0; i++) { + char *key; + + key = g_strdup_printf ("%04x:%04x", driver->id_table[i].vendor, driver->id_table[i].product); + + if (g_hash_table_lookup (printed, key) != NULL) { + g_free (key); + continue; + } + + g_hash_table_insert (printed, key, GINT_TO_POINTER (1)); + + g_print ("%s | %s\n", key, driver->full_name); + } +} + +int main (int argc, char **argv) +{ + struct fp_driver **list; + guint i; + + list = fprint_get_drivers (); + + printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + g_print ("# Supported Devices\n"); + g_print ("\n"); + g_print ("## USB devices\n"); + g_print ("\n"); + g_print ("USB ID | Driver\n"); + g_print ("------------ | ------------\n"); + + for (i = 0; list[i] != NULL; i++) { + print_driver (list[i]); + } + + g_hash_table_destroy (printed); + + return 0; +} diff --git a/libfprint/meson.build b/libfprint/meson.build index eb761896..632c815f 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -197,6 +197,19 @@ if get_option('udev_rules') install_dir: udev_rules_dir) endif +supported_devices = executable('fprint-list-supported-devices', + 'fprint-list-supported-devices.c', + include_directories: [ + root_inc, + ], + dependencies: [ deps, libfprint_dep ], + install: false) + +configure_file(input: 'drivers_arrays.h', + output: 'supported-devices.md', + capture: true, + command: [ supported_devices.full_path() ]) + # MOSTLYCLEANFILES = $(udev_rules_DATA) # EXTRA_DIST = \ From 14e34e1d15520070b1310b0ad0abefd058c1ae09 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sun, 3 Jun 2018 14:41:02 +0200 Subject: [PATCH 131/141] build: Remove ported Makefile.am snippet --- libfprint/meson.build | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/libfprint/meson.build b/libfprint/meson.build index 632c815f..49cb5dce 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -209,15 +209,3 @@ configure_file(input: 'drivers_arrays.h', output: 'supported-devices.md', capture: true, command: [ supported_devices.full_path() ]) - -# MOSTLYCLEANFILES = $(udev_rules_DATA) - -# EXTRA_DIST = \ -# 60-fprint-autosuspend.rules - -# udev_rules_DATA = 60-fprint-autosuspend.rules - -# if ENABLE_UDEV_RULES -# $(udev_rules_DATA): fprint-list-udev-rules -# $(builddir)/fprint-list-udev-rules > $@ -#endif From 549a6694d200ea7bd1251347576873a665691f75 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 4 Jun 2018 16:13:08 +0200 Subject: [PATCH 132/141] build: Disable supported-devices.md generation for now As added in e5393bf46af41a24b98702cb39421e1171f3af4a It fails currently. --- libfprint/meson.build | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libfprint/meson.build b/libfprint/meson.build index 49cb5dce..c0701bc3 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -205,7 +205,7 @@ supported_devices = executable('fprint-list-supported-devices', dependencies: [ deps, libfprint_dep ], install: false) -configure_file(input: 'drivers_arrays.h', - output: 'supported-devices.md', - capture: true, - command: [ supported_devices.full_path() ]) +# configure_file(input: 'drivers_arrays.h', +# output: 'supported-devices.md', +# capture: true, +# command: [ supported_devices.full_path() ]) From c5cdfcb12024371ad2bade075ea53537a7f8fb2c Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 7 Jun 2018 17:39:04 +0200 Subject: [PATCH 133/141] lib: Sort supported devices list --- libfprint/fprint-list-supported-devices.c | 28 +++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/libfprint/fprint-list-supported-devices.c b/libfprint/fprint-list-supported-devices.c index 8e3c0cef..9401f156 100644 --- a/libfprint/fprint-list-supported-devices.c +++ b/libfprint/fprint-list-supported-devices.c @@ -25,7 +25,8 @@ GHashTable *printed = NULL; -static void print_driver (struct fp_driver *driver) +static GList *insert_driver (GList *list, + struct fp_driver *driver) { int i; @@ -41,19 +42,27 @@ static void print_driver (struct fp_driver *driver) g_hash_table_insert (printed, key, GINT_TO_POINTER (1)); - g_print ("%s | %s\n", key, driver->full_name); + list = g_list_prepend (list, g_strdup_printf ("%s | %s\n", key, driver->full_name)); } + + return list; } int main (int argc, char **argv) { - struct fp_driver **list; + struct fp_driver **driver_list; guint i; + GList *list, *l; - list = fprint_get_drivers (); + driver_list = fprint_get_drivers (); printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_print ("%% Fingerprint reader support\n"); + g_print ("%% Bastien Nocera, Daniel Drake\n"); + g_print ("%% 2018\n"); + g_print ("\n"); + g_print ("# Supported Devices\n"); g_print ("\n"); g_print ("## USB devices\n"); @@ -61,10 +70,15 @@ int main (int argc, char **argv) g_print ("USB ID | Driver\n"); g_print ("------------ | ------------\n"); - for (i = 0; list[i] != NULL; i++) { - print_driver (list[i]); - } + list = NULL; + for (i = 0; driver_list[i] != NULL; i++) + list = insert_driver (list, driver_list[i]); + list = g_list_sort (list, (GCompareFunc) g_strcmp0); + for (l = list; l != NULL; l = l->next) + g_print ("%s", (char *) l->data); + + g_list_free_full (list, g_free); g_hash_table_destroy (printed); return 0; From 5e24000799295b547cdefc95bb7d172408dce8f0 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 7 Jun 2018 17:39:36 +0200 Subject: [PATCH 134/141] build: Remove unused meson rule We're generating the supported-devices.md file in the website CI now. --- libfprint/meson.build | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libfprint/meson.build b/libfprint/meson.build index c0701bc3..8689c9f2 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -204,8 +204,3 @@ supported_devices = executable('fprint-list-supported-devices', ], dependencies: [ deps, libfprint_dep ], install: false) - -# configure_file(input: 'drivers_arrays.h', -# output: 'supported-devices.md', -# capture: true, -# command: [ supported_devices.full_path() ]) From dd0a0134a6910f7643e9626617d850a84e107d10 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 7 Jun 2018 17:46:08 +0200 Subject: [PATCH 135/141] lib: Fix supported devices page title --- libfprint/fprint-list-supported-devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libfprint/fprint-list-supported-devices.c b/libfprint/fprint-list-supported-devices.c index 9401f156..720cfc55 100644 --- a/libfprint/fprint-list-supported-devices.c +++ b/libfprint/fprint-list-supported-devices.c @@ -58,7 +58,7 @@ int main (int argc, char **argv) printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_print ("%% Fingerprint reader support\n"); + g_print ("%% lifprint — Supported Devices\n"); g_print ("%% Bastien Nocera, Daniel Drake\n"); g_print ("%% 2018\n"); g_print ("\n"); From b62e67401ca4695a41128afaea38bea22e508a9e Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Fri, 8 Jun 2018 16:23:35 +0200 Subject: [PATCH 136/141] lib: Fix supported devices page title again We need to call setlocale() so we run in UTF-8 mode, and can print that sweet sweet em dash. --- libfprint/fprint-list-supported-devices.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfprint/fprint-list-supported-devices.c b/libfprint/fprint-list-supported-devices.c index 720cfc55..172991cb 100644 --- a/libfprint/fprint-list-supported-devices.c +++ b/libfprint/fprint-list-supported-devices.c @@ -20,6 +20,7 @@ #include #include +#include #include "fp_internal.h" @@ -54,6 +55,8 @@ int main (int argc, char **argv) guint i; GList *list, *l; + setlocale (LC_ALL, ""); + driver_list = fprint_get_drivers (); printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); From 40f486b10871a1caf10ea52a953cbedac8a09ea9 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 12 Jun 2018 11:06:26 +0200 Subject: [PATCH 137/141] HACKING: Update hacking file --- HACKING | 96 ------------------------------------------------------ HACKING.md | 52 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 96 deletions(-) delete mode 100644 HACKING create mode 100644 HACKING.md diff --git a/HACKING b/HACKING deleted file mode 100644 index 43bf4e79..00000000 --- a/HACKING +++ /dev/null @@ -1,96 +0,0 @@ -Copyright notices -================= - -If you make a contribution substantial enough to add or update a copyright -notice on a file, such notice must be mirrored in the AUTHORS file. This is -to make it easy for people to comply to section 6 of the LGPL, which states -that a "work that uses the Library" must include copyright notices from -this library. By providing them all in one place, hopefully we save such -users some time. - - -USB -=== - -At the time of development, there are no known consumer fingerprint readers -which do not operate over the USB bus. Therefore the library is designed around -the fact that each driver drivers USB devices, and each device is a USB device. -If we were to ever support a non-USB device, some rearchitecting would be -needed, but this would not be a substantial task. - - -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. - - -Two-faced-ness -============== - -Like any decent library, this one is designed to provide a stable and -documented API to it's users: applications. Clear distinction is made between -data available internally in the library, and data/functions available to -the applications. - -This library is confused a little by the fact that there is another 'interface' -at hand: the internal interface provided to drivers. So, we effectively end -up with 2 APIs: - - 1. The external-facing API for applications - 2. The internal API for fingerprint drivers - -Non-static functions which are intended for internal use only are prepended -with the "fpi_" prefix. - - -API stability -============= - -No API stability has been promised to anyone: go wild, there's no issue with -breaking APIs at this point in time. - - -Portability -=========== - -libfprint is primarily written for Linux. However, I'm interested in -supporting efforts to port this to other operating systems too. - -You should ensure code is portable wherever possible. Try and use GLib rather -than OS-specific features. - -Endianness must be considered in all code. libfprint must support both big- -and little-endian systems. - - -Coding Style -============ - -This project follows Linux kernel coding style but with a tab width of 4. - - -Documentation -============= - -All additions of public API functions must be accompanied with doxygen -comments. - -All changes which potentially change the behaviour of the public API must -be reflected by updating the appropriate doxygen comments. - - -Contributing -============ - -Patches should be sent to the fprint bugzilla: -https://bugs.freedesktop.org/enter_bug.cgi?product=libfprint - -Information about libfprint development repositories can be found here: -http://www.freedesktop.org/wiki/Software/fprint/libfprint - -If you're looking for ideas for things to work on, look at the TODO file or -grep the source code for FIXMEs. - diff --git a/HACKING.md b/HACKING.md new file mode 100644 index 00000000..e43cbf2b --- /dev/null +++ b/HACKING.md @@ -0,0 +1,52 @@ +# Contributing to libfprint + +## 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. + +## Two-faced-ness + +Like any decent library, this one is designed to provide a stable and +documented API to its users: applications. Clear distinction is made between +data available internally in the library, and data/functions available to +the applications. + +This library is confused a little by the fact that there is another 'interface' +at hand: the internal interface provided to drivers. So, we effectively end +up with 2 APIs: + + 1. The [external-facing API for applications](libfprint/fprint.h) + 2. The [internal API for fingerprint drivers](libfprint/drivers_api.h) + +Non-static functions which are intended for internal use only are prepended +with the "fpi_" prefix. + +## Documentation + +All additions of public API functions must be accompanied with gtk-doc +comments. + +All changes which potentially change the behaviour of the public API must +be reflected by updating the appropriate gtk-doc comments. + + +## Contributing + +Patches should be sent as merge requests to the gitlab page: +https://gitlab.freedesktop.org/libfprint/libfprint/merge_requests + +Drivers are not usually written by libfprint developers, but when they +are, we require: +- 3 stand-alone devices. Not in a laptop or another embedded device, as + space is scarce, unless the device has special integration with that + hardware. +- specifications of the protocol. + +If you are an end-user, you can file a feature request with the "Driver Request" +tag on [libfprint's issue page](https://gitlab.freedesktop.org/libfprint/libfprint/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=Driver%20Request), +or subscribe to an existing feature request there. + +If you are an enterprising hacker, please file a new merge request with +the driver patches integrated. From ac1f97e2eb455b618c28bdbc9a57026c52d709c8 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 12 Jun 2018 12:46:19 +0200 Subject: [PATCH 138/141] lib: Supported devices list is for master, not stable --- libfprint/fprint-list-supported-devices.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libfprint/fprint-list-supported-devices.c b/libfprint/fprint-list-supported-devices.c index 172991cb..ed49ee69 100644 --- a/libfprint/fprint-list-supported-devices.c +++ b/libfprint/fprint-list-supported-devices.c @@ -68,6 +68,8 @@ int main (int argc, char **argv) g_print ("# Supported Devices\n"); g_print ("\n"); + g_print ("This is a list of supported devices in libfprint's development version. Those drivers might not all be available in the stable, released version. If in doubt, contact your distribution or systems integrator for details.\n"); + g_print ("\n"); g_print ("## USB devices\n"); g_print ("\n"); g_print ("USB ID | Driver\n"); From 74b5c9278723e90f7b196a971da66b9fbef1d6f6 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 12 Jun 2018 15:42:22 +0200 Subject: [PATCH 139/141] 0.8.0 --- NEWS | 22 ++++++++++++++++++++++ meson.build | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 815edc6d..e4a2ef8e 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,28 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2018-06-12: v0.8.0 release +- Port to meson as the build system +- Port documentation to gtk-doc + +* Drivers: + - Add Elan driver + - Increase threshold to detect encryption on URU4000 devices + - Remove already replaced UPEKE2 driver + - Fix possible crash caused by vfs5011 when no lines were captured + +* Library: + - Fix a number of memory and file descriptor leaks and warnings + - Make NSS (and URU4000) driver optional + - Fix assembling of frames for non-reverse and non reverse stripes + - Split internal private header to clarify drivers API + - Simplify logging system, now all the builds can be used to output + debug information + - Mark fp_dscv_print functions as deprecated + +* Udev rules: + - Add some unsupported devices to the whitelist + 2017-05-14: v0.7.0 release * Drivers: - Add VFS0050 driver diff --git a/meson.build b/meson.build index ca705dd5..a5d2a94f 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('libfprint', [ 'c', 'cpp' ], - version: '0.7.0', + version: '0.8.0', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized', From e1d85fb6362031e69abf088b1037a0b5dcaa5a05 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 12 Jun 2018 16:03:34 +0200 Subject: [PATCH 140/141] build: Install udev rules in correct directory The udevdir variable in udev.pc might not have a trailing slash. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index a5d2a94f..62e69e63 100644 --- a/meson.build +++ b/meson.build @@ -95,7 +95,7 @@ if get_option('udev_rules') if udev_rules_dir == 'auto' udev_dep = dependency('udev') - udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + 'rules.d' + udev_rules_dir = udev_dep.get_pkgconfig_variable('udevdir') + '/rules.d' endif endif From 6f6127cbb640a8549eb971aa73d6fe8543d3c40b Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 12 Jun 2018 16:05:45 +0200 Subject: [PATCH 141/141] 0.8.1 --- NEWS | 4 ++++ meson.build | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index e4a2ef8e..9291089b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2018-06-12: v0.8.1 release +- Brown paperbag release to install the udev rules file in the correct + directory if the udev pkg-config file doesn't have a trailing slash + 2018-06-12: v0.8.0 release - Port to meson as the build system - Port documentation to gtk-doc diff --git a/meson.build b/meson.build index 62e69e63..088bd112 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('libfprint', [ 'c', 'cpp' ], - version: '0.8.0', + version: '0.8.1', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized',