mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2025-11-15 07:38:12 +00:00
Compare commits
34 Commits
wip/hadess
...
benzea/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b137807420 | ||
|
|
0936fc3597 | ||
|
|
b7f436e8de | ||
|
|
4f0b0fa526 | ||
|
|
f0abefa9fa | ||
|
|
7f58556011 | ||
|
|
cecb01bcb9 | ||
|
|
b95402bc72 | ||
|
|
484743f652 | ||
|
|
a5cfc1644f | ||
|
|
b3565b83e1 | ||
|
|
8f46de0a60 | ||
|
|
b3c5fe4b82 | ||
|
|
4cf5f92a52 | ||
|
|
297236b51a | ||
|
|
8626c64831 | ||
|
|
e4f9935706 | ||
|
|
8ba29606bb | ||
|
|
1b74813adf | ||
|
|
07ff03970f | ||
|
|
25ab4849a4 | ||
|
|
840bcc77a5 | ||
|
|
a464f602ca | ||
|
|
ad17011e68 | ||
|
|
744a71ce08 | ||
|
|
422fc5facf | ||
|
|
6d542edf8a | ||
|
|
8d4d56b1f1 | ||
|
|
6e30a1ee45 | ||
|
|
87c3b9c5ba | ||
|
|
0a08a6a7c0 | ||
|
|
9db89e00d0 | ||
|
|
3ad65b9589 | ||
|
|
48aa6d0252 |
@@ -48,6 +48,11 @@ build:
|
||||
<<: *build_one_driver
|
||||
<<: *build
|
||||
# <<: *check_abi
|
||||
artifacts:
|
||||
expose_as: "HTML Documentation"
|
||||
paths:
|
||||
- _build/doc/html/
|
||||
expire_in: 1 week
|
||||
|
||||
test:
|
||||
stage: test
|
||||
@@ -75,13 +80,32 @@ test_valgrind:
|
||||
- ninja -C _build
|
||||
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
|
||||
|
||||
test_scan_build:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
allow_failure: true
|
||||
script:
|
||||
- meson -Ddrivers=all . _build
|
||||
# This is ugly, the wrapper disables the malloc checker
|
||||
- SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build ninja -C _build scan-build
|
||||
# Check that the directory is empty
|
||||
- "! ls -A _build/meson-logs/scanbuild | grep -q ."
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/meson-logs
|
||||
expire_in: 1 week
|
||||
|
||||
test_indent:
|
||||
stage: check-source
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
script:
|
||||
- scripts/uncrustify.sh --check
|
||||
- scripts/uncrustify.sh
|
||||
- git diff
|
||||
- "! git status -s | grep -q ."
|
||||
|
||||
.flatpak_script_template: &flatpak_script
|
||||
script:
|
||||
|
||||
@@ -24,3 +24,4 @@
|
||||
umockdev
|
||||
uncrustify
|
||||
valgrind
|
||||
clang-analyzer
|
||||
|
||||
4
.gitlab-ci/scan-build
Executable file
4
.gitlab-ci/scan-build
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This wrapper just disables the malloc checker
|
||||
exec /usr/bin/scan-build -disable-checker unix.Malloc "$@"
|
||||
13
MAINTAINERS
Normal file
13
MAINTAINERS
Normal file
@@ -0,0 +1,13 @@
|
||||
Current maintainers of libfprint are:
|
||||
|
||||
* Benjamin Berg <bberg@redhat.com>
|
||||
* Marco Trevisan (Treviño) <mail@3v1n0.net>
|
||||
|
||||
Many drivers are not actively maintained and may not be fully functional.
|
||||
We are happy to receive contributions, but the support we can give is
|
||||
limitted unfortunately. For many drivers we may not even have test devices.
|
||||
|
||||
Maintained drivers are:
|
||||
* synaptics:
|
||||
Contributed and maintained by Synaptics Inc.
|
||||
Contact: Vincent Huang <vincent.huang@tw.synaptics.com>
|
||||
@@ -175,7 +175,7 @@ fpi_image_resize
|
||||
|
||||
<SECTION>
|
||||
<FILE>fpi-image-device</FILE>
|
||||
<TITLE>FpImageDevice</TITLE>
|
||||
<TITLE>Internal FpImageDevice</TITLE>
|
||||
FpiImageDeviceState
|
||||
FpImageDeviceClass
|
||||
fpi_image_device_session_error
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script can be used together with the virtual_imgdev to simulate an
|
||||
# image based fingerprint reader.
|
||||
#
|
||||
# To use, set the FP_VIRTUAL_IMAGE environment variable for both the
|
||||
# libfprint using program (e.g. fprintd) and this script.
|
||||
#
|
||||
# Usually this would work by adding it into the systemd unit file. The
|
||||
# best way of doing so is to create
|
||||
# /etc/systemd/system/fprintd.service.d/fprintd-test.conf
|
||||
#
|
||||
# [Service]
|
||||
# RuntimeDirectory=fprint
|
||||
# Environment=FP_VIRTUAL_DEVICE=/run/fprint/virtdev_sock
|
||||
# Environment=G_MESSAGES_DEBUG=all
|
||||
# ReadWritePaths=$RUNTIME_DIR
|
||||
#
|
||||
# After that run:
|
||||
#
|
||||
# systemctl daemon-reload
|
||||
# systemctl restart fprintd.service
|
||||
#
|
||||
# You may also need to disable selinux.
|
||||
#
|
||||
# Then run this script with e.g.
|
||||
# FP_VIRTUAL_DEVICE=/run/fprint/virtdev_sock ./sendvirtimg.py "ADD <username> <finger> <success|failure>"
|
||||
|
||||
|
||||
|
||||
import cairo
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
import struct
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
sys.stderr.write('You need to pass commands!\n')
|
||||
sys.stderr.write('Usage: ./sendvirtimg.py "ADD <finger> <username> <success|failure>"\n')
|
||||
sys.exit(1)
|
||||
|
||||
command = sys.argv[1]
|
||||
|
||||
# Send image through socket
|
||||
sockaddr = os.environ['FP_VIRTUAL_DEVICE']
|
||||
if not sockaddr:
|
||||
sockaddr = os.environ['FP_VIRTUAL_DEVICE_IDENT']
|
||||
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
sock.connect(sockaddr)
|
||||
|
||||
sock.sendall(command.encode('utf-8'))
|
||||
|
||||
@@ -614,6 +614,7 @@ capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
self->strips = g_slist_reverse (self->strips);
|
||||
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||
img->flags |= FPI_IMAGE_PARTIAL;
|
||||
|
||||
g_slist_free_full (self->strips, g_free);
|
||||
self->strips = NULL;
|
||||
|
||||
@@ -458,6 +458,7 @@ capture_read_strip_cb (FpiUsbTransfer *transfer, FpDevice *_dev,
|
||||
fpi_do_movement_estimation (&assembling_ctx, self->strips);
|
||||
img = fpi_assemble_frames (&assembling_ctx,
|
||||
self->strips);
|
||||
img->flags |= FPI_IMAGE_PARTIAL;
|
||||
g_slist_free_full (self->strips, g_free);
|
||||
self->strips = NULL;
|
||||
self->strips_len = 0;
|
||||
|
||||
@@ -230,6 +230,7 @@ capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
|
||||
|
||||
self->strips = g_slist_reverse (self->strips);
|
||||
img = fpi_assemble_frames (&assembling_ctx, self->strips);
|
||||
img->flags |= FPI_IMAGE_PARTIAL;
|
||||
g_slist_free_full (self->strips, g_free);
|
||||
self->strips = NULL;
|
||||
self->strips_len = 0;
|
||||
|
||||
@@ -331,6 +331,7 @@ capture_set_idle_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
|
||||
priv->strips = g_slist_reverse (priv->strips);
|
||||
img = fpi_assemble_frames (cls->assembling_ctx, priv->strips);
|
||||
img->flags |= FPI_IMAGE_PARTIAL;
|
||||
g_slist_foreach (priv->strips, (GFunc) g_free, NULL);
|
||||
g_slist_free (priv->strips);
|
||||
priv->strips = NULL;
|
||||
|
||||
@@ -207,6 +207,7 @@ elan_save_img_frame (FpiDeviceElan *elandev)
|
||||
|
||||
unsigned int frame_size = elandev->frame_width * elandev->frame_height;
|
||||
unsigned short *frame = g_malloc (frame_size * sizeof (short));
|
||||
|
||||
elan_save_frame (elandev, frame);
|
||||
unsigned int sum = 0;
|
||||
|
||||
@@ -244,6 +245,7 @@ elan_process_frame_linear (unsigned short *raw_frame,
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
unsigned short min = 0xffff, max = 0;
|
||||
|
||||
for (int i = 0; i < frame_size; i++)
|
||||
{
|
||||
if (raw_frame[i] < min)
|
||||
@@ -255,6 +257,7 @@ elan_process_frame_linear (unsigned short *raw_frame,
|
||||
g_assert (max != min);
|
||||
|
||||
unsigned short px;
|
||||
|
||||
for (int i = 0; i < frame_size; i++)
|
||||
{
|
||||
px = raw_frame[i];
|
||||
@@ -278,6 +281,7 @@ elan_process_frame_thirds (unsigned short *raw_frame,
|
||||
|
||||
unsigned short lvl0, lvl1, lvl2, lvl3;
|
||||
unsigned short *sorted = g_malloc (frame_size * sizeof (short));
|
||||
|
||||
memcpy (sorted, raw_frame, frame_size * sizeof (short));
|
||||
qsort (sorted, frame_size, sizeof (short), cmp_short);
|
||||
lvl0 = sorted[0];
|
||||
@@ -287,6 +291,7 @@ elan_process_frame_thirds (unsigned short *raw_frame,
|
||||
g_free (sorted);
|
||||
|
||||
unsigned short px;
|
||||
|
||||
for (int i = 0; i < frame_size; i++)
|
||||
{
|
||||
px = raw_frame[i];
|
||||
@@ -320,6 +325,7 @@ elan_submit_image (FpImageDevice *dev)
|
||||
g_slist_foreach (raw_frames, (GFunc) self->process_frame, &frames);
|
||||
fpi_do_movement_estimation (&assembling_ctx, frames);
|
||||
img = fpi_assemble_frames (&assembling_ctx, frames);
|
||||
img->flags |= FPI_IMAGE_PARTIAL;
|
||||
|
||||
g_slist_free_full (frames, g_free);
|
||||
|
||||
@@ -509,6 +515,7 @@ elan_stop_capture (FpDevice *dev)
|
||||
|
||||
FpiSsm *ssm =
|
||||
fpi_ssm_new (dev, stop_capture_run_state, STOP_CAPTURE_NUM_STATES);
|
||||
|
||||
fpi_ssm_start (ssm, stop_capture_complete);
|
||||
}
|
||||
|
||||
@@ -619,6 +626,7 @@ elan_capture (FpDevice *dev)
|
||||
elan_dev_reset_state (self);
|
||||
FpiSsm *ssm =
|
||||
fpi_ssm_new (dev, capture_run_state, CAPTURE_NUM_STATES);
|
||||
|
||||
fpi_ssm_start (ssm, capture_complete);
|
||||
}
|
||||
|
||||
@@ -797,6 +805,7 @@ elan_calibrate (FpDevice *dev)
|
||||
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), calibrate_run_state,
|
||||
CALIBRATE_NUM_STATES);
|
||||
|
||||
fpi_ssm_start (ssm, calibrate_complete);
|
||||
}
|
||||
|
||||
@@ -892,6 +901,7 @@ elan_activate (FpImageDevice *dev)
|
||||
FpiSsm *ssm =
|
||||
fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
|
||||
ACTIVATE_NUM_STATES);
|
||||
|
||||
fpi_ssm_start (ssm, activate_complete);
|
||||
}
|
||||
|
||||
@@ -988,7 +998,7 @@ static void
|
||||
elan_change_state_async (FpDevice *dev,
|
||||
void *data)
|
||||
{
|
||||
g_message ("state change dev: %p", dev);
|
||||
fp_dbg ("state change dev: %p", dev);
|
||||
elan_change_state (FP_IMAGE_DEVICE (dev));
|
||||
}
|
||||
|
||||
|
||||
@@ -206,6 +206,7 @@ parse_get_enrolled_users_report (bmkt_msg_resp_t *msg_resp, bmkt_response_t *res
|
||||
get_enroll_templates_resp->query_sequence = extract8 (msg_resp->payload, &offset);
|
||||
|
||||
int n = 0;
|
||||
|
||||
for (n = 0; n < BMKT_MAX_NUM_TEMPLATES_INTERNAL_FLASH; n++)
|
||||
{
|
||||
if (offset >= msg_resp->payload_len)
|
||||
|
||||
@@ -310,6 +310,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
fp_dbg ("Image size is %lu\n",
|
||||
self->image_size);
|
||||
img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
img->flags |= FPI_IMAGE_PARTIAL;
|
||||
memcpy (img->data, self->image_bits,
|
||||
IMAGE_SIZE);
|
||||
fpi_image_device_image_captured (dev, img);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#define TIMEOUT 5000
|
||||
|
||||
#define MSG_READ_BUF_SIZE 0x40
|
||||
#define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
|
||||
|
||||
struct _FpiDeviceUpekts
|
||||
{
|
||||
@@ -236,12 +235,18 @@ __handle_incoming_msg (FpDevice *device,
|
||||
{
|
||||
GError *error = NULL;
|
||||
guint8 *buf = udata->buffer;
|
||||
guint16 len = ((buf[5] & 0xf) << 8) | buf[6];
|
||||
guint16 computed_crc = udf_crc (buf + 4, len + 3);
|
||||
guint16 msg_crc = (buf[len + 8] << 8) | buf[len + 7];
|
||||
unsigned char *retdata = NULL;
|
||||
guint16 len;
|
||||
guint16 computed_crc;
|
||||
guint16 msg_crc;
|
||||
unsigned char code_a, code_b;
|
||||
|
||||
g_assert (udata->buflen >= 6);
|
||||
len = ((buf[5] & 0xf) << 8) | buf[6];
|
||||
|
||||
g_assert (udata->buflen >= len + 9);
|
||||
computed_crc = udf_crc (buf + 4, len + 3);
|
||||
msg_crc = (buf[len + 8] << 8) | buf[len + 7];
|
||||
|
||||
if (computed_crc != msg_crc)
|
||||
{
|
||||
fp_err ("CRC failed, got %04x expected %04x", msg_crc, computed_crc);
|
||||
@@ -267,12 +272,7 @@ __handle_incoming_msg (FpDevice *device,
|
||||
return;
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
retdata = g_malloc (len);
|
||||
memcpy (retdata, buf + 7, len);
|
||||
}
|
||||
udata->callback (device, READ_MSG_CMD, code_a, 0, retdata, len,
|
||||
udata->callback (device, READ_MSG_CMD, code_a, 0, buf + 7, len,
|
||||
udata->user_data, NULL);
|
||||
goto done;
|
||||
}
|
||||
@@ -309,14 +309,8 @@ __handle_incoming_msg (FpDevice *device,
|
||||
innerlen = 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 (device, READ_MSG_RESPONSE, code_b, _subcmd,
|
||||
retdata, innerlen, udata->user_data, NULL);
|
||||
g_free (retdata);
|
||||
innerbuf + 6, innerlen, udata->user_data, NULL);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
@@ -358,7 +352,8 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
gpointer user_data, GError *error)
|
||||
{
|
||||
struct read_msg_data *udata = user_data;
|
||||
guint16 len;
|
||||
guint16 payload_len;
|
||||
gsize packet_len;
|
||||
|
||||
if (error)
|
||||
{
|
||||
@@ -383,14 +378,15 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
goto err;
|
||||
}
|
||||
|
||||
len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
|
||||
payload_len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
|
||||
packet_len = payload_len + 9;
|
||||
if (transfer->actual_length != MSG_READ_BUF_SIZE &&
|
||||
(len + 9) > transfer->actual_length)
|
||||
packet_len > 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, (gint) transfer->actual_length);
|
||||
(gint) packet_len, (gint) transfer->actual_length);
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"Packet from device didn't include data");
|
||||
goto err;
|
||||
@@ -399,14 +395,14 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
/* 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)
|
||||
if (packet_len > MSG_READ_BUF_SIZE)
|
||||
{
|
||||
int needed = len - MAX_DATA_IN_READ_BUF;
|
||||
int needed = packet_len - MSG_READ_BUF_SIZE;
|
||||
FpiUsbTransfer *etransfer = fpi_usb_transfer_new (device);
|
||||
|
||||
fp_dbg ("didn't fit in buffer, need to extend by %d bytes", needed);
|
||||
udata->buffer = g_realloc ((gpointer) udata->buffer, len);
|
||||
udata->buflen = len;
|
||||
udata->buffer = g_realloc ((gpointer) udata->buffer, packet_len);
|
||||
udata->buflen = packet_len;
|
||||
|
||||
fpi_usb_transfer_fill_bulk_full (etransfer, EP_IN,
|
||||
udata->buffer + MSG_READ_BUF_SIZE,
|
||||
@@ -700,7 +696,7 @@ initsm_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||
break;
|
||||
|
||||
case SEND_RESP03:;
|
||||
transfer = alloc_send_cmd28_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
|
||||
transfer = alloc_send_cmdresponse_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
|
||||
transfer->ssm = ssm;
|
||||
transfer->short_is_error = TRUE;
|
||||
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
|
||||
@@ -856,21 +852,14 @@ dev_init (FpDevice *dev)
|
||||
fpi_ssm_start (ssm, initsm_done);
|
||||
}
|
||||
|
||||
static void
|
||||
deinitsm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
{
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, NULL);
|
||||
|
||||
fpi_device_close_complete (dev, error);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_exit (FpDevice *dev)
|
||||
{
|
||||
FpiSsm *ssm;
|
||||
GError *error = NULL;
|
||||
|
||||
ssm = fpi_ssm_new (dev, deinitsm_state_handler, DEINITSM_NUM_STATES);
|
||||
fpi_ssm_start (ssm, deinitsm_done);
|
||||
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, &error);
|
||||
|
||||
fpi_device_close_complete (dev, error);
|
||||
}
|
||||
|
||||
static const unsigned char enroll_init[] = {
|
||||
@@ -983,7 +972,9 @@ enroll_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
if (error)
|
||||
fp_warn ("Error deinitializing: %s", error->message);
|
||||
|
||||
fpi_device_enroll_complete (dev, data->print, data->error);
|
||||
fpi_device_enroll_complete (dev,
|
||||
g_steal_pointer (&data->print),
|
||||
g_steal_pointer (&data->error));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -992,7 +983,7 @@ do_enroll_stop (FpDevice *dev, FpPrint *print, GError *error)
|
||||
EnrollStopData *data = g_new0 (EnrollStopData, 1);
|
||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||
|
||||
data->print = g_object_ref (print);
|
||||
data->print = print;
|
||||
data->error = error;
|
||||
|
||||
fpi_ssm_start (ssm, enroll_stop_deinit_cb);
|
||||
@@ -1127,6 +1118,7 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
|
||||
data_len - sizeof (scan_comp),
|
||||
1);
|
||||
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
g_object_set (print, "fpi-data", fp_data, NULL);
|
||||
g_object_ref (print);
|
||||
}
|
||||
@@ -1245,11 +1237,11 @@ verify_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
||||
fp_warn ("Error deinitializing: %s", error->message);
|
||||
|
||||
if (data->error)
|
||||
fpi_device_verify_complete (dev, data->error);
|
||||
fpi_device_verify_complete (dev, g_steal_pointer (&data->error));
|
||||
else
|
||||
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
||||
|
||||
g_error_free (error);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1259,7 +1251,7 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
|
||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||
|
||||
/* Report the error immediately if possible, otherwise delay it. */
|
||||
if (!error && error->domain != FP_DEVICE_RETRY)
|
||||
if (error && error->domain == FP_DEVICE_RETRY)
|
||||
fpi_device_verify_report (dev, res, NULL, error);
|
||||
else
|
||||
data->error = error;
|
||||
@@ -1301,7 +1293,7 @@ verify_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||
|
||||
case VERIFY_INIT:
|
||||
fpi_device_get_verify_data (dev, &print);
|
||||
g_object_get (dev, "fpi-data", &fp_data, NULL);
|
||||
g_object_get (print, "fpi-data", &fp_data, NULL);
|
||||
|
||||
data = g_variant_get_fixed_array (fp_data, &data_len, 1);
|
||||
|
||||
|
||||
@@ -156,6 +156,8 @@ async_abort (FpDevice *dev, FpiSsm *ssm, int ep)
|
||||
else
|
||||
fpi_usb_transfer_fill_bulk (transfer, ep, VFS_USB_BUFFER_SIZE);
|
||||
|
||||
transfer->ssm = ssm;
|
||||
|
||||
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
|
||||
async_abort_callback, NULL);
|
||||
}
|
||||
@@ -240,6 +242,7 @@ prepare_image (FpDeviceVfs0050 *vdev)
|
||||
|
||||
/* Building GSList */
|
||||
GSList *lines = NULL;
|
||||
|
||||
for (int i = height - 1; i >= 0; --i)
|
||||
lines = g_slist_prepend (lines, vdev->lines_buffer + i);
|
||||
|
||||
@@ -464,8 +467,8 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
|
||||
/* Check if fingerprint data is over */
|
||||
if (transfer->actual_length == 0)
|
||||
/* Capture is done when there is no more data to transfer or device timed out */
|
||||
if (transfer->actual_length <= 0)
|
||||
{
|
||||
fpi_ssm_next_state (transfer->ssm);
|
||||
}
|
||||
@@ -473,7 +476,7 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
|
||||
{
|
||||
self->bytes += transfer->actual_length;
|
||||
|
||||
/* We need more data */
|
||||
/* Try reading more data */
|
||||
fpi_ssm_jump_to_state (transfer->ssm,
|
||||
fpi_ssm_get_cur_state (transfer->ssm));
|
||||
}
|
||||
@@ -595,8 +598,7 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||
/* Receive chunk of data */
|
||||
transfer = fpi_usb_transfer_new (dev);
|
||||
fpi_usb_transfer_fill_bulk_full (transfer, 0x82,
|
||||
(guint8 *)
|
||||
(self->lines_buffer + self->bytes),
|
||||
(guint8 *) self->lines_buffer + self->bytes,
|
||||
VFS_USB_BUFFER_SIZE, NULL);
|
||||
transfer->ssm = ssm;
|
||||
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
|
||||
@@ -668,6 +670,7 @@ dev_activate (FpImageDevice *idev)
|
||||
self->ssm_active = 1;
|
||||
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
|
||||
|
||||
fpi_ssm_start (ssm, dev_activate_callback);
|
||||
}
|
||||
|
||||
@@ -711,6 +714,7 @@ dev_open (FpImageDevice *idev)
|
||||
|
||||
/* Clearing previous device state */
|
||||
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (idev), activate_ssm, SSM_STATES);
|
||||
|
||||
fpi_ssm_start (ssm, dev_open_callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,7 @@ translate_str (const char **srcL, gssize *len)
|
||||
src_len += tmp;
|
||||
}
|
||||
|
||||
g_assert (src_len >= 2);
|
||||
*len = src_len / 2;
|
||||
res = g_malloc0 (*len);
|
||||
dst = res;
|
||||
|
||||
@@ -381,9 +381,8 @@ submit_image (FpiSsm *ssm,
|
||||
{
|
||||
FpImage *img;
|
||||
|
||||
if (self->lines_recorded == 0)
|
||||
if (self->lines_recorded < VFS5011_IMAGE_WIDTH)
|
||||
{
|
||||
/* == FP_ENROLL_RETRY_TOO_SHORT */
|
||||
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,456 +0,0 @@
|
||||
/*
|
||||
* Virtual driver for "simple" device debugging
|
||||
*
|
||||
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
|
||||
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a virtual driver to debug the non-image based drivers. A small
|
||||
* python script is provided to connect to it via a socket, allowing
|
||||
* prints to registered programmatically.
|
||||
* Using this, it is possible to test libfprint and fprintd.
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "virtual_device"
|
||||
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include "../fpi-device.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixsocketaddress.h>
|
||||
|
||||
#define MAX_LINE_LEN 1024
|
||||
|
||||
enum {
|
||||
VIRTUAL_DEVICE,
|
||||
VIRTUAL_DEVICE_IDENT
|
||||
};
|
||||
|
||||
struct _FpDeviceVirtualDevice
|
||||
{
|
||||
FpDevice parent;
|
||||
|
||||
GSocketListener *listener;
|
||||
GSocketConnection *connection;
|
||||
GCancellable *cancellable;
|
||||
|
||||
gint socket_fd;
|
||||
gint client_fd;
|
||||
guint line[MAX_LINE_LEN];
|
||||
|
||||
GHashTable *pending_prints; /* key: finger+username value: gboolean */
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP, DEVICE_VIRTUAL_DEVICE, FpDevice)
|
||||
G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE)
|
||||
|
||||
static void start_listen (FpDeviceVirtualDevice *self);
|
||||
|
||||
#define ADD_CMD_PREFIX "ADD "
|
||||
|
||||
static FpFinger
|
||||
str_to_finger (const char *str)
|
||||
{
|
||||
g_autoptr(GEnumClass) eclass;
|
||||
GEnumValue *value;
|
||||
|
||||
eclass = g_type_class_ref (FP_TYPE_FINGER);
|
||||
value = g_enum_get_value_by_nick (eclass, str);
|
||||
|
||||
if (value == NULL)
|
||||
return FP_FINGER_UNKNOWN;
|
||||
|
||||
return value->value;
|
||||
}
|
||||
|
||||
static const char *
|
||||
finger_to_str (FpFinger finger)
|
||||
{
|
||||
GEnumClass *eclass;
|
||||
GEnumValue *value;
|
||||
|
||||
eclass = g_type_class_ref (FP_TYPE_FINGER);
|
||||
value = g_enum_get_value (eclass, finger);
|
||||
g_type_class_unref (eclass);
|
||||
|
||||
if (value == NULL)
|
||||
return NULL;
|
||||
|
||||
return value->value_nick;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_code (const char *str)
|
||||
{
|
||||
if (g_strcmp0 (str, "1") == 0 ||
|
||||
g_strcmp0 (str, "success") == 0 ||
|
||||
g_strcmp0 (str, "SUCCESS") == 0 ||
|
||||
g_strcmp0 (str, "FPI_MATCH_SUCCESS") == 0)
|
||||
return FPI_MATCH_SUCCESS;
|
||||
|
||||
return FPI_MATCH_FAIL;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_command_line (FpDeviceVirtualDevice *self,
|
||||
const char *line)
|
||||
{
|
||||
if (g_str_has_prefix (line, ADD_CMD_PREFIX))
|
||||
{
|
||||
g_auto(GStrv) elems;
|
||||
FpPrint *print;
|
||||
FpFinger finger;
|
||||
gboolean success;
|
||||
g_autofree char *description = NULL;
|
||||
char *key;
|
||||
|
||||
/* Syntax: ADD <finger> <username> <error when used> */
|
||||
elems = g_strsplit (line + strlen (ADD_CMD_PREFIX), " ", 3);
|
||||
if (g_strv_length (elems) != 3)
|
||||
{
|
||||
g_warning ("Malformed command: %s", line);
|
||||
return;
|
||||
}
|
||||
finger = str_to_finger (elems[0]);
|
||||
if (finger == FP_FINGER_UNKNOWN)
|
||||
{
|
||||
g_warning ("Unknown finger '%s'", elems[0]);
|
||||
return;
|
||||
}
|
||||
print = fp_print_new (FP_DEVICE (self));
|
||||
fp_print_set_finger (print, finger);
|
||||
fp_print_set_username (print, elems[1]);
|
||||
description = g_strdup_printf ("Fingerprint finger '%s' for user '%s'",
|
||||
elems[0], elems[1]);
|
||||
fp_print_set_description (print, description);
|
||||
success = parse_code (elems[2]);
|
||||
|
||||
key = g_strdup_printf ("%s-%s", elems[0], elems[1]);
|
||||
g_hash_table_insert (self->pending_prints,
|
||||
key, GINT_TO_POINTER (success));
|
||||
|
||||
fp_dbg ("Added pending print %s for user %s (code: %s)",
|
||||
elems[0], elems[1], success ? "FPI_MATCH_SUCCESS" : "FPI_MATCH_FAIL");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Unhandled command sent: '%s'", line);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recv_instruction_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceVirtualDevice *self;
|
||||
gboolean success;
|
||||
gsize bytes;
|
||||
|
||||
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
|
||||
|
||||
if (!success || bytes == 0)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
|
||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
|
||||
return;
|
||||
g_warning ("Error receiving instruction data: %s", error->message);
|
||||
}
|
||||
|
||||
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
|
||||
handle_command_line (self, (const char *) self->line);
|
||||
|
||||
out:
|
||||
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
|
||||
g_clear_object (&self->connection);
|
||||
|
||||
start_listen (self);
|
||||
}
|
||||
|
||||
static void
|
||||
recv_instruction (FpDeviceVirtualDevice *self,
|
||||
GInputStream *stream)
|
||||
{
|
||||
memset (&self->line, 0, sizeof (self->line));
|
||||
g_input_stream_read_all_async (stream,
|
||||
self->line,
|
||||
sizeof (self->line),
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
recv_instruction_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
new_connection_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GSocketConnection) connection = NULL;
|
||||
GInputStream *stream;
|
||||
FpDeviceVirtualDevice *self = user_data;
|
||||
|
||||
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
|
||||
res,
|
||||
NULL,
|
||||
&error);
|
||||
if (!connection)
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
g_warning ("Error accepting a new connection: %s", error->message);
|
||||
start_listen (self);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always further connections (but we disconnect them immediately
|
||||
* if we already have a connection). */
|
||||
if (self->connection)
|
||||
{
|
||||
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
|
||||
start_listen (self);
|
||||
return;
|
||||
}
|
||||
|
||||
self->connection = g_steal_pointer (&connection);
|
||||
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
|
||||
|
||||
recv_instruction (self, stream);
|
||||
|
||||
fp_dbg ("Got a new connection!");
|
||||
}
|
||||
|
||||
static void
|
||||
start_listen (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
fp_dbg ("Starting a new listener");
|
||||
g_socket_listener_accept_async (self->listener,
|
||||
self->cancellable,
|
||||
new_connection_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_init (FpDevice *dev)
|
||||
{
|
||||
fpi_device_open_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_verify (FpDevice *dev)
|
||||
{
|
||||
FpPrint *print;
|
||||
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
gboolean success;
|
||||
|
||||
fpi_device_get_verify_data (dev, &print);
|
||||
g_object_get (print, "fpi-data", &data, NULL);
|
||||
success = g_variant_get_boolean (data);
|
||||
|
||||
fpi_device_verify_report (dev,
|
||||
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
||||
NULL, NULL);
|
||||
fpi_device_verify_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_enroll (FpDevice *dev)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||
gpointer success_ptr;
|
||||
FpPrint *print = NULL;
|
||||
g_autofree char *key = NULL;
|
||||
|
||||
fpi_device_get_enroll_data (dev, &print);
|
||||
key = g_strdup_printf ("%s-%s",
|
||||
finger_to_str (fp_print_get_finger (print)),
|
||||
fp_print_get_username (print));
|
||||
|
||||
if (g_hash_table_lookup_extended (self->pending_prints, key, NULL, &success_ptr))
|
||||
{
|
||||
gboolean success = GPOINTER_TO_INT (success_ptr);
|
||||
GVariant *fp_data;
|
||||
|
||||
fp_data = g_variant_new_boolean (success);
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
if (fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT)
|
||||
fpi_print_set_device_stored (print, TRUE);
|
||||
g_object_set (print, "fpi-data", fp_data, NULL);
|
||||
fpi_device_enroll_complete (dev, g_object_ref (print), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
fpi_device_enroll_complete (dev, NULL,
|
||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||
"No pending result for this username/finger combination"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dev_deinit (FpDevice *dev)
|
||||
{
|
||||
fpi_device_close_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dev_supports_identify (FpDevice *dev)
|
||||
{
|
||||
return fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT;
|
||||
}
|
||||
|
||||
static void
|
||||
dev_identify (FpDevice *dev)
|
||||
{
|
||||
GPtrArray *templates;
|
||||
FpPrint *result = NULL;
|
||||
guint i;
|
||||
|
||||
g_assert (fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT);
|
||||
|
||||
fpi_device_get_identify_data (dev, &templates);
|
||||
|
||||
for (i = 0; i < templates->len; i++)
|
||||
{
|
||||
FpPrint *template = g_ptr_array_index (templates, i);
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
gboolean success;
|
||||
|
||||
g_object_get (dev, "fpi-data", &template, NULL);
|
||||
success = g_variant_get_boolean (data);
|
||||
if (success)
|
||||
{
|
||||
result = template;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
fpi_device_identify_report (dev, result, NULL, NULL);
|
||||
fpi_device_identify_complete (dev, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_finalize (GObject *object)
|
||||
{
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
|
||||
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_object (&self->listener);
|
||||
g_clear_object (&self->connection);
|
||||
g_hash_table_destroy (self->pending_prints);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_constructed (GObject *object)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GSocketListener) listener = NULL;
|
||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
|
||||
const char *env;
|
||||
g_autoptr(GSocketAddress) addr = NULL;
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
self->client_fd = -1;
|
||||
|
||||
env = fpi_device_get_virtual_env (FP_DEVICE (self));
|
||||
|
||||
listener = g_socket_listener_new ();
|
||||
g_socket_listener_set_backlog (listener, 1);
|
||||
|
||||
/* Remove any left over socket. */
|
||||
g_unlink (env);
|
||||
|
||||
addr = g_unix_socket_address_new (env);
|
||||
|
||||
if (!g_socket_listener_add_address (listener,
|
||||
addr,
|
||||
G_SOCKET_TYPE_STREAM,
|
||||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||
|
||||
fpi_device_open_complete (FP_DEVICE (self), g_steal_pointer (&error));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self->listener = g_steal_pointer (&listener);
|
||||
self->cancellable = g_cancellable_new ();
|
||||
self->pending_prints = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
NULL);
|
||||
|
||||
if (G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->constructed (object);
|
||||
|
||||
start_listen (self);
|
||||
}
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_init (FpDeviceVirtualDevice *self)
|
||||
{
|
||||
}
|
||||
|
||||
static const FpIdEntry driver_ids[] = {
|
||||
{ .virtual_envvar = "FP_VIRTUAL_DEVICE", .driver_data = VIRTUAL_DEVICE },
|
||||
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_IDENT", .driver_data = VIRTUAL_DEVICE_IDENT },
|
||||
{ .virtual_envvar = NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
|
||||
{
|
||||
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = fpi_device_virtual_device_constructed;
|
||||
object_class->finalize = fpi_device_virtual_device_finalize;
|
||||
|
||||
dev_class->id = FP_COMPONENT;
|
||||
dev_class->full_name = "Virtual device for debugging";
|
||||
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
|
||||
dev_class->id_table = driver_ids;
|
||||
dev_class->nr_enroll_stages = 5;
|
||||
|
||||
dev_class->open = dev_init;
|
||||
dev_class->close = dev_deinit;
|
||||
dev_class->verify = dev_verify;
|
||||
dev_class->enroll = dev_enroll;
|
||||
|
||||
dev_class->identify = dev_identify;
|
||||
dev_class->supports_identify = dev_supports_identify;
|
||||
}
|
||||
@@ -215,7 +215,6 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
|
||||
|
||||
g_warning ("Error accepting a new connection: %s", error->message);
|
||||
start_listen (dev);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Always further connections (but we disconnect them immediately
|
||||
@@ -253,6 +252,7 @@ dev_init (FpImageDevice *dev)
|
||||
g_autoptr(GSocketListener) listener = NULL;
|
||||
FpDeviceVirtualImage *self = FPI_DEVICE_VIRTUAL_IMAGE (dev);
|
||||
const char *env;
|
||||
|
||||
g_autoptr(GSocketAddress) addr = NULL;
|
||||
G_DEBUG_HERE ();
|
||||
|
||||
@@ -278,7 +278,7 @@ dev_init (FpImageDevice *dev)
|
||||
{
|
||||
g_warning ("Could not listen on unix socket: %s", error->message);
|
||||
|
||||
fpi_image_device_open_complete (dev, g_steal_pointer (&error));
|
||||
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -24,16 +24,11 @@
|
||||
#include "fp-device-private.h"
|
||||
|
||||
/**
|
||||
* SECTION: fpi-device
|
||||
* @title: Internal FpDevice
|
||||
* @short_description: Internal device routines
|
||||
* SECTION: fp-device
|
||||
* @title: FpDevice
|
||||
* @short_description: Fingerpint device routines
|
||||
*
|
||||
* The methods that are available for drivers to manipulate a device. See
|
||||
* #FpDeviceClass for more information. Also note that most of these are
|
||||
* not relevant for image based devices, see #FpImageDeviceClass in that
|
||||
* case.
|
||||
*
|
||||
* Also see the public #FpDevice routines.
|
||||
* These are the public #FpDevice routines.
|
||||
*/
|
||||
|
||||
static void fp_device_async_initable_iface_init (GAsyncInitableIface *iface);
|
||||
@@ -507,9 +502,6 @@ fp_device_supports_identify (FpDevice *device)
|
||||
|
||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||
|
||||
if (cls->supports_identify != NULL)
|
||||
return cls->supports_identify (device);
|
||||
|
||||
return cls->identify != NULL;
|
||||
}
|
||||
|
||||
@@ -949,13 +941,6 @@ fp_device_identify (FpDevice *device,
|
||||
if (g_task_return_error_if_cancelled (task))
|
||||
return;
|
||||
|
||||
if (!fp_device_supports_identify (device))
|
||||
{
|
||||
g_task_return_error (task,
|
||||
fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!priv->is_open)
|
||||
{
|
||||
g_task_return_error (task,
|
||||
|
||||
@@ -281,6 +281,7 @@ fp_image_detect_minutiae_thread_func (GTask *task,
|
||||
gint map_w, map_h;
|
||||
gint bw, bh, bd;
|
||||
gint r;
|
||||
g_autofree LFSPARMS *lfsparms;
|
||||
|
||||
/* Normalize the image first */
|
||||
if (data->flags & FPI_IMAGE_H_FLIPPED)
|
||||
@@ -294,12 +295,15 @@ fp_image_detect_minutiae_thread_func (GTask *task,
|
||||
|
||||
data->flags &= ~(FPI_IMAGE_H_FLIPPED | FPI_IMAGE_V_FLIPPED | FPI_IMAGE_COLORS_INVERTED);
|
||||
|
||||
lfsparms = g_memdup (&g_lfsparms_V2, sizeof (LFSPARMS));
|
||||
lfsparms->remove_perimeter_pts = data->flags & FPI_IMAGE_PARTIAL ? TRUE : FALSE;
|
||||
|
||||
timer = g_timer_new ();
|
||||
r = get_minutiae (&minutiae, &quality_map, &direction_map,
|
||||
&low_contrast_map, &low_flow_map, &high_curve_map,
|
||||
&map_w, &map_h, &bdata, &bw, &bh, &bd,
|
||||
data->image, data->width, data->height, 8,
|
||||
data->ppmm, &g_lfsparms_V2);
|
||||
data->ppmm, lfsparms);
|
||||
g_timer_stop (timer);
|
||||
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
|
||||
|
||||
|
||||
@@ -822,7 +822,7 @@ fp_print_deserialize (const guchar *data,
|
||||
fpi_print_set_type (result, FPI_PRINT_NBIS);
|
||||
for (i = 0; i < g_variant_n_children (prints); i++)
|
||||
{
|
||||
g_autofree struct xyt_struct *xyt = g_new0 (struct xyt_struct, 1);
|
||||
g_autofree struct xyt_struct *xyt = NULL;
|
||||
const gint32 *xcol, *ycol, *thetacol;
|
||||
gsize xlen, ylen, thetalen;
|
||||
g_autoptr(GVariant) xyt_data = NULL;
|
||||
@@ -848,6 +848,7 @@ fp_print_deserialize (const guchar *data,
|
||||
if (xlen > G_N_ELEMENTS (xyt->xcol))
|
||||
goto invalid_format;
|
||||
|
||||
xyt = g_new0 (struct xyt_struct, 1);
|
||||
xyt->nrows = xlen;
|
||||
memcpy (xyt->xcol, xcol, sizeof (xcol[0]) * xlen);
|
||||
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
|
||||
|
||||
@@ -912,6 +912,20 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
|
||||
{
|
||||
if (FP_IS_PRINT (print))
|
||||
{
|
||||
FpiPrintType print_type;
|
||||
|
||||
g_object_get (print, "fpi-type", &print_type, NULL);
|
||||
if (print_type == FPI_PRINT_UNDEFINED)
|
||||
{
|
||||
g_warning ("Driver did not set the type on the returned print!");
|
||||
g_clear_object (&print);
|
||||
|
||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
||||
"Driver provided incorrect print data!");
|
||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
||||
return;
|
||||
}
|
||||
|
||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_OBJECT, print);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -79,7 +79,6 @@ struct _FpIdEntry
|
||||
* @delete: Delete a print from the device
|
||||
* @cancel: Called on cancellation, this is a convenience to not need to handle
|
||||
* the #GCancellable directly by using fpi_device_get_cancellable().
|
||||
* @supports_identify: Whether identify operations are supported.
|
||||
*
|
||||
* NOTE: If your driver is image based, then you should subclass #FpImageDevice
|
||||
* instead. #FpImageDevice based drivers use a different way of interacting
|
||||
@@ -129,9 +128,7 @@ struct _FpDeviceClass
|
||||
void (*list) (FpDevice *device);
|
||||
void (*delete) (FpDevice * device);
|
||||
|
||||
void (*cancel) (FpDevice *device);
|
||||
|
||||
gboolean (*supports_identify) (FpDevice *device);
|
||||
void (*cancel) (FpDevice *device);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,12 +24,11 @@
|
||||
#include "fp-image-device.h"
|
||||
|
||||
/**
|
||||
* SECTION: fpi-image
|
||||
* @title: Internal FpImage
|
||||
* @short_description: Internal image handling routines
|
||||
* SECTION: fpi-image-device
|
||||
* @title: Internal FpImageDevice
|
||||
* @short_description: Internal image device functions
|
||||
*
|
||||
* Internal image handling routines. Also see the public <ulink
|
||||
* url="libfprint-FpImage.html">FpImage routines</ulink>.
|
||||
* Internal image device functions. See #FpImageDevice for public routines.
|
||||
*/
|
||||
|
||||
/* Manually redefine what G_DEFINE_* macro does */
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
* @title: Internal FpImage
|
||||
* @short_description: Internal image handling routines
|
||||
*
|
||||
* Internal image handling routines. Also see the public <ulink
|
||||
* url="libfprint-FpImage.html">FpImage routines</ulink>.
|
||||
* Internal image handling routines. See #FpImage for public routines.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef enum {
|
||||
FPI_IMAGE_V_FLIPPED = 1 << 0,
|
||||
FPI_IMAGE_H_FLIPPED = 1 << 1,
|
||||
FPI_IMAGE_COLORS_INVERTED = 1 << 2,
|
||||
FPI_IMAGE_PARTIAL = 1 << 3,
|
||||
} FpiImageFlags;
|
||||
|
||||
/**
|
||||
|
||||
@@ -155,9 +155,6 @@ foreach driver: drivers
|
||||
if driver == 'virtual_image'
|
||||
drivers_sources += [ 'drivers/virtual-image.c' ]
|
||||
endif
|
||||
if driver == 'virtual_device'
|
||||
drivers_sources += [ 'drivers/virtual-device.c' ]
|
||||
endif
|
||||
if driver == 'synaptics'
|
||||
drivers_sources += [
|
||||
'drivers/synaptics/synaptics.c',
|
||||
|
||||
57
libfprint/nbis/fix-scan-build-reports.patch
Normal file
57
libfprint/nbis/fix-scan-build-reports.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
diff --git a/libfprint/nbis/mindtct/contour.c b/libfprint/nbis/mindtct/contour.c
|
||||
index 3e9416c..31f32d0 100644
|
||||
--- mindtct/contour.c
|
||||
+++ mindtct/contour.c
|
||||
@@ -440,6 +440,8 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
|
||||
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
|
||||
int i, j, ret;
|
||||
|
||||
+ g_assert (half_contour > 0);
|
||||
+
|
||||
/* Compute maximum length of complete contour */
|
||||
/* (2 half contours + feature point). */
|
||||
max_contour = (half_contour<<1) + 1;
|
||||
diff --git a/libfprint/nbis/mindtct/minutia.c b/libfprint/nbis/mindtct/minutia.c
|
||||
index 0b29aa0..77cf09d 100644
|
||||
--- mindtct/minutia.c
|
||||
+++ mindtct/minutia.c
|
||||
@@ -1625,7 +1625,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae,
|
||||
dmapval, bdata, iw, ih, lfsparms);
|
||||
|
||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
||||
- if(ret == IGNORE)
|
||||
+ if(ret != 0)
|
||||
/* Deallocate the minutia. */
|
||||
free_minutia(minutia);
|
||||
|
||||
@@ -1776,7 +1776,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae,
|
||||
dmapval, bdata, iw, ih, lfsparms);
|
||||
|
||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
||||
- if(ret == IGNORE)
|
||||
+ if(ret != 0)
|
||||
/* Deallocate the minutia. */
|
||||
free_minutia(minutia);
|
||||
|
||||
diff --git a/libfprint/nbis/mindtct/ridges.c b/libfprint/nbis/mindtct/ridges.c
|
||||
index f0d9cd3..9902585 100644
|
||||
--- mindtct/ridges.c
|
||||
+++ mindtct/ridges.c
|
||||
@@ -147,6 +147,8 @@ int count_minutia_ridges(const int first, MINUTIAE *minutiae,
|
||||
{
|
||||
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
|
||||
|
||||
+ g_assert (lfsparms->max_nbrs > 0);
|
||||
+
|
||||
/* Find up to the maximum number of qualifying neighbors. */
|
||||
nbr_list = NULL;
|
||||
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
||||
@@ -407,6 +409,8 @@ int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
|
||||
{
|
||||
int i;
|
||||
|
||||
+ g_assert (pos >= 0);
|
||||
+
|
||||
/* If the desired insertion position is beyond one passed the last */
|
||||
/* neighbor in the lists OR greater than equal to the maximum ... */
|
||||
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
||||
@@ -260,6 +260,8 @@ typedef struct g_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;
|
||||
@@ -609,6 +611,9 @@ typedef struct g_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 *****/
|
||||
|
||||
@@ -1123,6 +1128,9 @@ extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
|
||||
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
|
||||
unsigned char *, const int, const int,
|
||||
int *, const int, const int, const LFSPARMS *);
|
||||
extern int remove_perimeter_pts(MINUTIAE *minutiae,
|
||||
unsigned char *bdata, const int iw, const int ih,
|
||||
const LFSPARMS *lfsparms);
|
||||
|
||||
/* results.c */
|
||||
extern int write_text_results(char *, const int, const int, const int,
|
||||
|
||||
@@ -440,6 +440,8 @@ int get_centered_contour(int **ocontour_x, int **ocontour_y,
|
||||
int *contour_x, *contour_y, *contour_ex, *contour_ey, ncontour;
|
||||
int i, j, ret;
|
||||
|
||||
g_assert (half_contour > 0);
|
||||
|
||||
/* Compute maximum length of complete contour */
|
||||
/* (2 half contours + feature point). */
|
||||
max_contour = (half_contour<<1) + 1;
|
||||
|
||||
@@ -150,6 +150,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,
|
||||
@@ -234,6 +236,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,
|
||||
|
||||
@@ -1625,7 +1625,7 @@ int process_horizontal_scan_minutia_V2(MINUTIAE *minutiae,
|
||||
dmapval, bdata, iw, ih, lfsparms);
|
||||
|
||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
||||
if(ret == IGNORE)
|
||||
if(ret != 0)
|
||||
/* Deallocate the minutia. */
|
||||
free_minutia(minutia);
|
||||
|
||||
@@ -1776,7 +1776,7 @@ int process_vertical_scan_minutia_V2(MINUTIAE *minutiae,
|
||||
dmapval, bdata, iw, ih, lfsparms);
|
||||
|
||||
/* If minuitia IGNORED and not added to the minutia list ... */
|
||||
if(ret == IGNORE)
|
||||
if(ret != 0)
|
||||
/* Deallocate the minutia. */
|
||||
free_minutia(minutia);
|
||||
|
||||
|
||||
@@ -195,6 +195,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);
|
||||
}
|
||||
|
||||
@@ -1329,6 +1334,159 @@ int remove_pointing_invblock_V2(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
|
||||
**************************************************************************/
|
||||
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_overlaps - Takes a list of true and false minutiae and
|
||||
|
||||
@@ -147,6 +147,8 @@ int count_minutia_ridges(const int first, MINUTIAE *minutiae,
|
||||
{
|
||||
int i, ret, *nbr_list, *nbr_nridges, nnbrs;
|
||||
|
||||
g_assert (lfsparms->max_nbrs > 0);
|
||||
|
||||
/* Find up to the maximum number of qualifying neighbors. */
|
||||
nbr_list = NULL;
|
||||
if((ret = find_neighbors(&nbr_list, &nnbrs, lfsparms->max_nbrs,
|
||||
@@ -407,6 +409,8 @@ int insert_neighbor(const int pos, const int nbr_index, const double nbr_dist2,
|
||||
{
|
||||
int i;
|
||||
|
||||
g_assert (pos >= 0);
|
||||
|
||||
/* If the desired insertion position is beyond one passed the last */
|
||||
/* neighbor in the lists OR greater than equal to the maximum ... */
|
||||
/* NOTE: pos is zero-oriented while nnbrs and max_nbrs are 1-oriented. */
|
||||
|
||||
231
libfprint/nbis/remove-perimeter-pts.patch
Normal file
231
libfprint/nbis/remove-perimeter-pts.patch
Normal file
@@ -0,0 +1,231 @@
|
||||
diff --git nbis/include/lfs.h nbis/include/lfs.h
|
||||
index f4f38d7..8b12e73 100644
|
||||
--- nbis/include/lfs.h
|
||||
+++ nbis/include/lfs.h
|
||||
@@ -260,6 +260,8 @@ typedef struct g_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;
|
||||
@@ -609,6 +611,9 @@ typedef struct g_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 *****/
|
||||
|
||||
@@ -1123,6 +1128,9 @@ extern int remove_or_adjust_side_minutiae(MINUTIAE *, unsigned char *,
|
||||
extern int remove_or_adjust_side_minutiae_V2(MINUTIAE *,
|
||||
unsigned char *, const int, const int,
|
||||
int *, const int, const int, const LFSPARMS *);
|
||||
+extern int remove_perimeter_pts(MINUTIAE *minutiae,
|
||||
+ unsigned char *bdata, const int iw, const int ih,
|
||||
+ const LFSPARMS *lfsparms);
|
||||
|
||||
/* results.c */
|
||||
extern int write_text_results(char *, const int, const int, const int,
|
||||
diff --git nbis/mindtct/globals.c nbis/mindtct/globals.c
|
||||
index da10c15..79bc583 100644
|
||||
--- nbis/mindtct/globals.c
|
||||
+++ nbis/mindtct/globals.c
|
||||
@@ -150,6 +150,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,
|
||||
@@ -234,6 +236,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 nbis/mindtct/remove.c nbis/mindtct/remove.c
|
||||
index af5ab7d..7311f1c 100644
|
||||
--- nbis/mindtct/remove.c
|
||||
+++ nbis/mindtct/remove.c
|
||||
@@ -195,6 +195,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);
|
||||
}
|
||||
|
||||
@@ -1329,6 +1334,159 @@ int remove_pointing_invblock_V2(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
|
||||
+**************************************************************************/
|
||||
+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_overlaps - Takes a list of true and false minutiae and
|
||||
@@ -192,3 +192,9 @@ spatch --sp-file remove-global-y.cocci bozorth3/* include/bozorth.h --in-place
|
||||
# The above leaves an unused variable around, triggering a warning
|
||||
# remove it.
|
||||
patch -p0 < glib-mem-warning.patch
|
||||
|
||||
# Also fix some scan-build warnings, mostly by adding assertions
|
||||
patch -p0 < fix-scan-build-reports.patch
|
||||
|
||||
# Add pass to remove perimeter points
|
||||
patch -p0 < remove-perimeter-pts.patch
|
||||
|
||||
@@ -88,7 +88,7 @@ cairo_dep = dependency('cairo', required: false)
|
||||
|
||||
# Drivers
|
||||
drivers = get_option('drivers').split(',')
|
||||
virtual_drivers = [ 'virtual_image', 'virtual_device' ]
|
||||
virtual_drivers = [ 'virtual_image' ]
|
||||
default_drivers = [
|
||||
'upektc_img',
|
||||
'vfs5011',
|
||||
|
||||
@@ -100,7 +100,10 @@ fpi_device_fake_enroll (FpDevice *device)
|
||||
fpi_device_get_enroll_data (device, (FpPrint **) &fake_dev->action_data);
|
||||
|
||||
if (!print && !fake_dev->ret_error)
|
||||
fpi_device_get_enroll_data (device, &print);
|
||||
{
|
||||
fpi_device_get_enroll_data (device, &print);
|
||||
fpi_print_set_type (print, FPI_PRINT_RAW);
|
||||
}
|
||||
|
||||
fpi_device_enroll_complete (device,
|
||||
print ? g_object_ref (print) : NULL,
|
||||
|
||||
@@ -49,7 +49,7 @@ test_context_has_virtual_device (void)
|
||||
GPtrArray *devices;
|
||||
unsigned int i;
|
||||
|
||||
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
fpt_setup_virtual_device_environment ();
|
||||
|
||||
context = fp_context_new ();
|
||||
devices = fp_context_get_devices (context);
|
||||
@@ -70,7 +70,7 @@ test_context_has_virtual_device (void)
|
||||
|
||||
g_assert_true (FP_IS_DEVICE (virtual_device));
|
||||
|
||||
fpt_teardown_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
fpt_teardown_virtual_device_environment ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -81,7 +81,7 @@ test_context_enumerates_new_devices (void)
|
||||
|
||||
context = fp_context_new ();
|
||||
|
||||
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
fpt_setup_virtual_device_environment ();
|
||||
|
||||
fp_context_enumerate (context);
|
||||
devices = fp_context_get_devices (context);
|
||||
@@ -89,7 +89,7 @@ test_context_enumerates_new_devices (void)
|
||||
g_assert_nonnull (devices);
|
||||
g_assert_cmpuint (devices->len, ==, 1);
|
||||
|
||||
fpt_teardown_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
fpt_teardown_virtual_device_environment ();
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -36,7 +36,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
||||
static void
|
||||
test_device_open_async (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||
|
||||
@@ -59,7 +59,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
||||
static void
|
||||
test_device_close_async (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||
while (!tctx->user_data)
|
||||
@@ -76,7 +76,7 @@ static void
|
||||
test_device_open_sync (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
@@ -97,7 +97,7 @@ static void
|
||||
test_device_open_sync_notify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
@@ -109,7 +109,7 @@ static void
|
||||
test_device_close_sync (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
@@ -131,7 +131,7 @@ static void
|
||||
test_device_close_sync_notify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
|
||||
@@ -144,7 +144,7 @@ test_device_close_sync_notify (void)
|
||||
static void
|
||||
test_device_get_driver (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
|
||||
@@ -153,7 +153,7 @@ test_device_get_driver (void)
|
||||
static void
|
||||
test_device_get_device_id (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
|
||||
@@ -162,7 +162,7 @@ test_device_get_device_id (void)
|
||||
static void
|
||||
test_device_get_name (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
||||
@@ -172,7 +172,7 @@ test_device_get_name (void)
|
||||
static void
|
||||
test_device_get_scan_type (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
|
||||
@@ -181,7 +181,7 @@ test_device_get_scan_type (void)
|
||||
static void
|
||||
test_device_get_nr_enroll_stages (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
||||
@@ -190,7 +190,7 @@ test_device_get_nr_enroll_stages (void)
|
||||
static void
|
||||
test_device_supports_identify (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_supports_identify (tctx->device));
|
||||
@@ -199,7 +199,7 @@ test_device_supports_identify (void)
|
||||
static void
|
||||
test_device_supports_capture (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_supports_capture (tctx->device));
|
||||
@@ -208,7 +208,7 @@ test_device_supports_capture (void)
|
||||
static void
|
||||
test_device_has_storage (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_false (fp_device_has_storage (tctx->device));
|
||||
|
||||
@@ -81,6 +81,8 @@ test_frame_assembling (void)
|
||||
ctx.frame_height = 20;
|
||||
ctx.image_width = width;
|
||||
|
||||
g_assert (height > ctx.frame_height);
|
||||
|
||||
offset = 10;
|
||||
test_height = height - (height - ctx.frame_height) % offset;
|
||||
|
||||
|
||||
@@ -541,6 +541,24 @@ test_driver_enroll_error_no_print (void)
|
||||
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
|
||||
g_assert_null (out_print);
|
||||
g_assert_null (fake_dev->ret_print);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
|
||||
"*Driver did not set the type on the returned print*");
|
||||
|
||||
fake_dev->ret_error = NULL;
|
||||
fake_dev->ret_print = fp_print_new (device); /* Type not set. */
|
||||
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
|
||||
(gpointer) (&fake_dev->ret_print));
|
||||
out_print =
|
||||
fp_device_enroll_sync (device, fp_print_new (device), NULL, NULL, NULL, &error);
|
||||
|
||||
g_test_assert_expected_messages ();
|
||||
g_assert (fake_dev->last_called_function == dev_class->enroll);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
|
||||
g_assert_null (out_print);
|
||||
g_assert_null (fake_dev->ret_print);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@@ -635,7 +653,7 @@ test_driver_enroll_progress (void)
|
||||
{
|
||||
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
|
||||
g_autoptr(FpAutoCloseDevice) device = NULL;
|
||||
g_autoptr(FpPrint) enrolled_print = NULL;
|
||||
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
|
||||
ExpectedEnrollData expected_enroll_data = {0};
|
||||
FpiDeviceFake *fake_dev;
|
||||
|
||||
@@ -1355,7 +1373,7 @@ test_driver_identify_report_no_callback (void)
|
||||
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
|
||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(FpAutoCloseDevice) device = NULL;
|
||||
g_autoptr(FpPrint) enrolled_print = NULL;
|
||||
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
|
||||
g_autoptr(FpPrint) print = NULL;
|
||||
g_autoptr(FpPrint) match = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
@@ -1493,6 +1511,7 @@ test_driver_list (void)
|
||||
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
|
||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||
|
||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
unsigned int i;
|
||||
|
||||
@@ -1515,6 +1534,7 @@ test_driver_list_error (void)
|
||||
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
|
||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||
|
||||
g_autoptr(GPtrArray) prints = NULL;
|
||||
|
||||
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
|
||||
@@ -1891,7 +1911,7 @@ test_driver_action_error_all (void)
|
||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||
FpiDeviceFake *fake_dev;
|
||||
|
||||
fake_dev = FPI_DEVICE_FAKE (device);
|
||||
fake_dev->return_action_error = TRUE;
|
||||
@@ -1962,7 +1982,7 @@ test_driver_action_error_fallback_all (void)
|
||||
g_autoptr(GPtrArray) prints = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||
FpiDeviceFake *fake_dev;
|
||||
|
||||
fake_dev = FPI_DEVICE_FAKE (device);
|
||||
fake_dev->return_action_error = TRUE;
|
||||
|
||||
@@ -200,7 +200,7 @@ test_ssm_new_full (void)
|
||||
static void
|
||||
test_ssm_new_no_handler (void)
|
||||
{
|
||||
g_autoptr(FpiSsm) ssm = NULL;
|
||||
G_GNUC_UNUSED g_autoptr(FpiSsm) ssm = NULL;
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*BUG:*handler*");
|
||||
@@ -211,7 +211,7 @@ test_ssm_new_no_handler (void)
|
||||
static void
|
||||
test_ssm_new_wrong_states (void)
|
||||
{
|
||||
g_autoptr(FpiSsm) ssm = NULL;
|
||||
G_GNUC_UNUSED g_autoptr(FpiSsm) ssm = NULL;
|
||||
|
||||
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||
"*BUG:*nr_states*");
|
||||
@@ -1172,6 +1172,7 @@ test_ssm_subssm_start (void)
|
||||
g_autoptr(FpiSsm) subssm =
|
||||
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
||||
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
||||
|
||||
g_autoptr(FpiSsmTestData) subdata =
|
||||
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
||||
|
||||
@@ -1262,6 +1263,7 @@ test_ssm_subssm_start_with_started (void)
|
||||
g_autoptr(FpiSsm) subssm =
|
||||
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
||||
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
||||
|
||||
g_autoptr(FpiSsmTestData) subdata =
|
||||
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
||||
|
||||
@@ -1305,6 +1307,7 @@ test_ssm_subssm_start_with_delayed (void)
|
||||
g_autoptr(FpiSsm) subssm =
|
||||
ssm_test_new_full (FPI_TEST_SSM_STATE_NUM, "FPI_TEST_SUB_SSM");
|
||||
FpiSsmTestData *data = fpi_ssm_get_data (ssm);
|
||||
|
||||
g_autoptr(FpiSsmTestData) subdata =
|
||||
fpi_ssm_test_data_ref (fpi_ssm_get_data (subssm));
|
||||
gpointer timeout_tracker = GUINT_TO_POINTER (TRUE);
|
||||
|
||||
@@ -22,60 +22,41 @@
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
struct
|
||||
{
|
||||
const char *envvar;
|
||||
const char *driver_id;
|
||||
const char *device_id;
|
||||
} devtype_vars[FPT_NUM_VIRTUAL_DEVICE_TYPES] = {
|
||||
{ "FP_VIRTUAL_IMAGE", "virtual_image", "virtual_image" }, /* FPT_VIRTUAL_DEVICE_IMAGE */
|
||||
{ "FP_VIRTUAL_DEVICE", "virtual_device", "virtual_device" }, /* FPT_VIRTUAL_DEVICE */
|
||||
{ "FP_VIRTUAL_DEVICE_IDENT", "virtual_device", "virtual_device_ident" } /* FPT_VIRTUAL_DEVICE_IDENT */
|
||||
};
|
||||
|
||||
void
|
||||
fpt_teardown_virtual_device_environment (FptVirtualDeviceType devtype)
|
||||
fpt_teardown_virtual_device_environment (void)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
path = g_getenv (devtype_vars[devtype].envvar);
|
||||
const char *path = g_getenv ("FP_VIRTUAL_IMAGE");
|
||||
|
||||
if (path)
|
||||
{
|
||||
g_autofree char *temp_dir = g_path_get_dirname (path);
|
||||
|
||||
g_unsetenv (devtype_vars[devtype].envvar);
|
||||
g_unsetenv ("FP_VIRTUAL_IMAGE");
|
||||
g_unlink (path);
|
||||
g_rmdir (temp_dir);
|
||||
}
|
||||
}
|
||||
|
||||
static FptVirtualDeviceType global_devtype;
|
||||
|
||||
static void
|
||||
on_signal_event (int sig)
|
||||
{
|
||||
fpt_teardown_virtual_device_environment (global_devtype);
|
||||
fpt_teardown_virtual_device_environment ();
|
||||
}
|
||||
|
||||
void
|
||||
fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype)
|
||||
fpt_setup_virtual_device_environment (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autofree char *temp_dir = NULL;
|
||||
g_autofree char *temp_path = NULL;
|
||||
g_autofree char *filename = NULL;
|
||||
|
||||
g_assert_null (g_getenv (devtype_vars[devtype].envvar));
|
||||
g_assert_null (g_getenv ("FP_VIRTUAL_IMAGE"));
|
||||
|
||||
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
filename = g_strdup_printf ("%s.socket", devtype_vars[devtype].device_id);
|
||||
temp_path = g_build_filename (temp_dir, filename, NULL);
|
||||
g_setenv (devtype_vars[devtype].envvar, temp_path, TRUE);
|
||||
|
||||
global_devtype = devtype;
|
||||
temp_path = g_build_filename (temp_dir, "virtual-image.socket", NULL);
|
||||
g_setenv ("FP_VIRTUAL_IMAGE", temp_path, TRUE);
|
||||
|
||||
signal (SIGKILL, on_signal_event);
|
||||
signal (SIGABRT, on_signal_event);
|
||||
@@ -97,16 +78,13 @@ fpt_context_new (void)
|
||||
}
|
||||
|
||||
FptContext *
|
||||
fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||
fpt_context_new_with_virtual_imgdev (void)
|
||||
{
|
||||
FptContext *tctx;
|
||||
GPtrArray *devices;
|
||||
unsigned int i;
|
||||
|
||||
g_assert_true (devtype >= FPT_VIRTUAL_DEVICE_IMAGE &&
|
||||
devtype < FPT_NUM_VIRTUAL_DEVICE_TYPES);
|
||||
|
||||
fpt_setup_virtual_device_environment (devtype);
|
||||
fpt_setup_virtual_device_environment ();
|
||||
|
||||
tctx = fpt_context_new ();
|
||||
devices = fp_context_get_devices (tctx->fp_context);
|
||||
@@ -118,7 +96,7 @@ fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||
{
|
||||
FpDevice *device = devices->pdata[i];
|
||||
|
||||
if (g_strcmp0 (fp_device_get_driver (device), devtype_vars[devtype].driver_id) == 0)
|
||||
if (g_strcmp0 (fp_device_get_driver (device), "virtual_image") == 0)
|
||||
{
|
||||
tctx->device = device;
|
||||
break;
|
||||
@@ -127,7 +105,6 @@ fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||
|
||||
g_assert_true (FP_IS_DEVICE (tctx->device));
|
||||
g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device);
|
||||
g_object_set_data (G_OBJECT (tctx->fp_context), "devtype", GUINT_TO_POINTER (devtype));
|
||||
|
||||
return tctx;
|
||||
}
|
||||
@@ -135,10 +112,6 @@ fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
|
||||
void
|
||||
fpt_context_free (FptContext *tctx)
|
||||
{
|
||||
FptVirtualDeviceType devtype;
|
||||
|
||||
devtype = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tctx->fp_context), "devtype"));
|
||||
|
||||
if (tctx->device && fp_device_is_open (tctx->device))
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
@@ -150,5 +123,5 @@ fpt_context_free (FptContext *tctx)
|
||||
g_clear_object (&tctx->fp_context);
|
||||
g_free (tctx);
|
||||
|
||||
fpt_teardown_virtual_device_environment (devtype);
|
||||
fpt_teardown_virtual_device_environment ();
|
||||
}
|
||||
|
||||
@@ -19,15 +19,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef enum {
|
||||
FPT_VIRTUAL_DEVICE_IMAGE = 0,
|
||||
FPT_VIRTUAL_DEVICE,
|
||||
FPT_VIRTUAL_DEVICE_IDENTIFY,
|
||||
FPT_NUM_VIRTUAL_DEVICE_TYPES
|
||||
} FptVirtualDeviceType;
|
||||
|
||||
void fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype);
|
||||
void fpt_teardown_virtual_device_environment (FptVirtualDeviceType devtype);
|
||||
void fpt_setup_virtual_device_environment (void);
|
||||
void fpt_teardown_virtual_device_environment (void);
|
||||
|
||||
typedef struct _FptContext
|
||||
{
|
||||
@@ -37,7 +30,7 @@ typedef struct _FptContext
|
||||
} FptContext;
|
||||
|
||||
FptContext * fpt_context_new (void);
|
||||
FptContext * fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype);
|
||||
FptContext * fpt_context_new_with_virtual_imgdev (void);
|
||||
|
||||
void fpt_context_free (FptContext *test_context);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user