Compare commits

..

5 Commits

Author SHA1 Message Date
Benjamin Berg
788fd9ca7a elan: Do not leak converted frames
The elan driver converts frames into a different format. These frames
are only needed to assemable the image and should be free'ed afterwards.

Fixes: #213
2019-12-16 11:41:22 +01:00
Benjamin Berg
8c5eede914 examples: Fix double device closing in manage-prints
The manage-prints command would close the device twice when the user
hits an invalid number or 'n' and no prints need to be deleted.

Simply remove the erroneous call to fix the issue.
2019-12-16 11:41:22 +01:00
Benjamin Berg
07c8481bf6 tests: Ensure objects are free'ed at the end of tests
The objects may not be garbage collected otherwise.
2019-12-16 11:41:22 +01:00
Benjamin Berg
d435fc7c2c synaptics: Use local variable rather than re-fetching usb device 2019-12-16 11:41:22 +01:00
Benjamin Berg
dc3b5e52ac meson: Add missing dependency on fp-enum.h for private library
The private library needs to indirectly include fp-enum.h. This
dependency was not listed anyway, resulting in a race condition during
the build process.
2019-12-16 11:39:18 +01:00
105 changed files with 1068 additions and 3932 deletions

23
.gitignore vendored
View File

@@ -1,3 +1,24 @@
ltmain.sh
missing
stamp-h1
libtool
*.la
*.lo
*.o
*.swp
_build
Makefile
Makefile.in
config.h*
aclocal.m4
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
.deps
.libs
compile
ChangeLog

View File

@@ -1,22 +1,20 @@
variables:
FEDORA_TAG: rawhide
FEDORA_VERSION: rawhide
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FEDORA_VERSION:$FEDORA_TAG"
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
include:
- local: '.gitlab-ci/libfprint-templates.yaml'
- project: 'wayland/ci-templates'
ref: master
file: '/templates/fedora.yml'
variables:
extends: .libfprint_common_variables
FDO_DISTRIBUTION_TAG: latest
FDO_DISTRIBUTION_VERSION: rawhide
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
stages:
- check-source
- build
- test
- flatpak
- flatpack
image: "$FEDORA_IMAGE"
@@ -48,11 +46,6 @@ build:
<<: *build_one_driver
<<: *build
# <<: *check_abi
artifacts:
expose_as: "HTML Documentation"
paths:
- _build/doc/html/
expire_in: 1 week
test:
stage: test
@@ -64,7 +57,6 @@ test:
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3
- ninja -C _build coverage
- cat _build/meson-logs/coverage.txt
artifacts:
paths:
- _build/meson-logs
@@ -80,32 +72,13 @@ 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
- git diff
- "! git status -s | grep -q ."
- scripts/uncrustify.sh --check
.flatpak_script_template: &flatpak_script
script:
@@ -132,7 +105,10 @@ test_indent:
.flatpak_master_template: &flatpak_master
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32
stage: flatpak
stage: flatpack
except:
variables:
- $CI_PIPELINE_SOURCE == "schedule"
variables:
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
# From demo/org.freedesktop.libfprint.Demo.json
@@ -152,19 +128,40 @@ flatpak-manual master:
<<: *flatpak_master
when: manual
except:
refs:
- tags
- master
variables:
- $CI_PIPELINE_SOURCE == "schedule"
- tags
- master
# CONTAINERS creation stage
container_fedora_build:
extends: .fdo.container-build@fedora
extends: .fedora@container-build
only:
variables:
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
variables:
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
# a list of packages to install
FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES
FEDORA_RPMS:
doxygen
flatpak-builder
gcc
gcc-c++
gcovr
git
glib2-devel
glibc-devel
gobject-introspection-devel
gtk-doc
gtk3-devel
libabigail
libgusb-devel
libX11-devel
libXv-devel
meson
nss-devel
pixman-devel
python3-cairo
python3-gobject
systemd
umockdev
uncrustify
valgrind

View File

@@ -1,27 +0,0 @@
.libfprint_common_variables:
LIBFPRINT_DEPENDENCIES:
doxygen
flatpak-builder
gcc
gcc-c++
gcovr
git
glib2-devel
glibc-devel
gobject-introspection-devel
gtk-doc
gtk3-devel
libabigail
libgusb-devel
libX11-devel
libXv-devel
meson
nss-devel
pixman-devel
python3-cairo
python3-gobject
systemd
umockdev
uncrustify
valgrind
clang-analyzer

View File

@@ -1,4 +0,0 @@
#!/bin/sh
# This wrapper just disables the malloc checker
exec /usr/bin/scan-build -disable-checker unix.Malloc "$@"

View File

@@ -1,13 +0,0 @@
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>

35
NEWS
View File

@@ -1,41 +1,6 @@
This file lists notable changes in each release. For the full history of all
changes, see ChangeLog.
2019-11-20: v1.90.1 release
This release fixes a lot of the regressions introduced in 1.90.0. Please note
that both the driver and external APIs have changed, as both the verify and
the identify functions now have early reporting mechanisms.
The soname for the library, as well as a number of file locations have also
changed. While this allows installation in parallel with the 1.0 version of
libfprint, we recommend installing only one, and migrating from version 1.0 to
version 2.0 alongside its main consumer (fprintd).
Only major changes are listed below. A lot of other cleanup work and small
fixes have also been merged.
* Library:
- Add support to run tests in gdb/valgrind
- Allow testing on all architectures
- Avoid image device AWAIT_FINGER_ON to deactivate state transitions
- Fix verify/identify error propagation to library user
- Correctly read image device information from class data
- Continue enroll after an image driver reported a retry error
- Change external API to allow reporting match results early
- A lot of new unit tests and integration tests have been added
* Drivers API
- Support variadic arguments in error functions
- Various re-definitions of ownership handling
- Add convenience API to change state after a timeout
- Add unit tests for all the drivers API
* Drivers:
- elan: Ensure correct deactivation of device
- uru4000: Fix IRQ handler registration and internal state handling
- uru4000: Fix control transfer request type
- synaptics: Ensure errors are only reported after finger removal
2019-11-20: v1.90.0 release
This release updates the core of the library to use GLib routines and Gio

View File

@@ -26,7 +26,6 @@ FpDeviceError
fp_device_retry_quark
fp_device_error_quark
FpEnrollProgress
FpMatchCb
fp_device_get_driver
fp_device_get_device_id
fp_device_get_name
@@ -130,7 +129,7 @@ fpi_get_driver_types
<FILE>fpi-device</FILE>
FpDeviceClass
FpTimeoutFunc
FpiDeviceAction
FpDeviceAction
FpIdEntry
fpi_device_get_usb_device
fpi_device_get_virtual_env
@@ -160,8 +159,6 @@ fpi_device_identify_complete
fpi_device_capture_complete
fpi_device_delete_complete
fpi_device_enroll_progress
fpi_device_verify_report
fpi_device_identify_report
</SECTION>
<SECTION>
@@ -175,8 +172,8 @@ fpi_image_resize
<SECTION>
<FILE>fpi-image-device</FILE>
<TITLE>Internal FpImageDevice</TITLE>
FpiImageDeviceState
<TITLE>FpImageDevice</TITLE>
FpImageDeviceState
FpImageDeviceClass
fpi_image_device_session_error
fpi_image_device_open_complete
@@ -200,15 +197,13 @@ BUG
<SECTION>
<FILE>fpi-print</FILE>
FpiPrintType
FpPrintType
FpiMatchResult
fpi_print_add_print
fpi_print_set_type
fpi_print_set_device_stored
fpi_print_add_from_image
fpi_print_bz3_match
fpi_print_generate_user_id
fpi_print_fill_from_user_id
</SECTION>
<SECTION>

View File

@@ -90,7 +90,7 @@ fp_image_get_width
<TITLE>Base class for image devices</TITLE>
FpImageDevice
FpImageDeviceClass
FpiImageDeviceState
FpImageDeviceState
</SECTION>
<SECTION>
@@ -114,3 +114,5 @@ FpUsbTransferCallback
FP_USB_ENDPOINT_IN
FP_USB_ENDPOINT_OUT
</SECTION>

View File

@@ -4,6 +4,7 @@ private_headers = [
'config.h',
'nbis-helpers.h',
'fprint.h',
'fp_internal.h',
# Subdirectories to ignore
'drivers',
@@ -23,13 +24,16 @@ 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(versioned_libname,
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,
ignore_headers: private_headers,
scan_args: [
#'--rebuild-sections',
'--ignore-headers=' + ' '.join(private_headers),
],
fixxref_args: [
'--html-dir=@0@'.format(docpath),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),

View File

@@ -1,8 +1,8 @@
ent_conf = configuration_data()
ent_conf.set('PACKAGE', versioned_libname)
ent_conf.set('PACKAGE', 'libfprint')
ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/libfprint/libfprint/issues')
ent_conf.set('PACKAGE_NAME', versioned_libname)
ent_conf.set('PACKAGE_STRING', versioned_libname)
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://fprint.freedesktop.org/')
ent_conf.set('PACKAGE_VERSION', meson.project_version())

View File

@@ -1,6 +1,6 @@
/*
* Example fingerprint enrollment program
* Enrolls your chosen finger and saves the print to disk
* Enrolls your choosen finger and saves the print to disk
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
*
@@ -19,29 +19,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-enroll"
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct _EnrollData
{
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger;
int ret_value;
GMainLoop *loop;
FpFinger finger;
int ret_value;
} EnrollData;
static void
enroll_data_free (EnrollData *enroll_data)
{
g_clear_handle_id (&enroll_data->sigint_handler, g_source_remove);
g_clear_object (&enroll_data->cancellable);
g_main_loop_unref (enroll_data->loop);
g_free (enroll_data);
}
@@ -142,22 +135,11 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
printf ("Scan your finger now.\n");
print_template = print_create_template (dev, enroll_data->finger);
fp_device_enroll (dev, print_template, enroll_data->cancellable,
on_enroll_progress, NULL, NULL,
(GAsyncReadyCallback) on_enroll_completed,
fp_device_enroll (dev, print_template, NULL, on_enroll_progress, NULL,
NULL, (GAsyncReadyCallback) on_enroll_completed,
enroll_data);
}
static gboolean
sigint_cb (void *user_data)
{
EnrollData *enroll_data = user_data;
g_cancellable_cancel (enroll_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
@@ -204,15 +186,8 @@ main (void)
enroll_data->finger = finger;
enroll_data->ret_value = EXIT_FAILURE;
enroll_data->loop = g_main_loop_new (NULL, FALSE);
enroll_data->cancellable = g_cancellable_new ();
enroll_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
enroll_data,
NULL);
fp_device_open (dev, enroll_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
enroll_data);
g_main_loop_run (enroll_data->loop);

View File

@@ -18,8 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-mange-prints"
#include <stdio.h>
#include <libfprint/fprint.h>

View File

@@ -19,10 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-storage"
#include <libfprint/fprint.h>
#include <libfprint/fpi-compat.h>
#include "storage.h"
#include <errno.h>
@@ -60,7 +57,7 @@ load_data (void)
{
GVariantDict *res;
GVariant *var;
gchar *contents = NULL;
g_autofree gchar *contents = NULL;
gsize length = 0;
if (!g_file_get_contents (STORAGE_FILE, &contents, &length, NULL))
@@ -69,12 +66,7 @@ load_data (void)
return g_variant_dict_new (NULL);
}
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT,
contents,
length,
FALSE,
g_free,
contents);
var = g_variant_new_from_data (G_VARIANT_TYPE_VARDICT, contents, length, FALSE, NULL, NULL);
res = g_variant_dict_new (var);
g_variant_unref (var);
@@ -137,7 +129,7 @@ print_data_load (FpDevice *dev, FpFinger finger)
g_autoptr(GVariant) val = NULL;
g_autoptr(GVariantDict) dict = NULL;
const guchar *stored_data = NULL;
g_autofree guchar *stored_data = NULL;
gsize stored_len;
dict = load_data ();
@@ -148,7 +140,7 @@ print_data_load (FpDevice *dev, FpFinger finger)
FpPrint *print;
g_autoptr(GError) error = NULL;
stored_data = (const guchar *) g_variant_get_fixed_array (val, &stored_len, 1);
stored_data = (guchar *) g_variant_get_fixed_array (val, &stored_len, 1);
print = fp_print_deserialize (stored_data, stored_len, &error);
if (error)
@@ -164,8 +156,8 @@ FpPrint *
print_create_template (FpDevice *dev, FpFinger finger)
{
g_autoptr(GDateTime) datetime = NULL;
g_autoptr(GDate) date = NULL;
FpPrint *template = NULL;
GDate *date = NULL;
gint year, month, day;
template = fp_print_new (dev);
@@ -175,6 +167,7 @@ print_create_template (FpDevice *dev, FpFinger finger)
g_date_time_get_ymd (datetime, &year, &month, &day);
date = g_date_new_dmy (day, month, year);
fp_print_set_enroll_date (template, date);
g_date_free (date);
return template;
}
@@ -220,7 +213,7 @@ save_image_to_pgm (FpImage *img, const char *path)
gboolean
print_image_save (FpPrint *print, const char *path)
{
FpImage *img = NULL;
g_autoptr(FpImage) img = NULL;
g_return_val_if_fail (FP_IS_PRINT (print), FALSE);
g_return_val_if_fail (path != NULL, FALSE);

View File

@@ -18,7 +18,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __STORAGE_H
#define __STORAGE_H
int print_data_save (FpPrint *print,
FpFinger finger);
@@ -28,3 +30,5 @@ FpPrint * print_create_template (FpDevice *dev,
FpFinger finger);
gboolean print_image_save (FpPrint *print,
const char *path);
#endif /* __STORAGE_H */

View File

@@ -18,8 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-utilities"
#include <libfprint/fprint.h>
#include <stdio.h>
@@ -109,19 +107,29 @@ finger_to_string (FpFinger finger)
FpFinger
finger_chooser (void)
{
int i = FP_FINGER_UNKNOWN;
int i;
const FpFinger all_fingers[] = {
FP_FINGER_LEFT_THUMB,
FP_FINGER_LEFT_INDEX,
FP_FINGER_LEFT_MIDDLE,
FP_FINGER_LEFT_RING,
FP_FINGER_LEFT_LITTLE,
FP_FINGER_RIGHT_THUMB,
FP_FINGER_RIGHT_INDEX,
FP_FINGER_RIGHT_MIDDLE,
FP_FINGER_RIGHT_RING,
FP_FINGER_RIGHT_LITTLE,
};
for (i = FP_FINGER_FIRST; i <= FP_FINGER_LAST; ++i)
g_print (" [%d] %s\n", (i - FP_FINGER_FIRST), finger_to_string (i));
for (i = all_fingers[0]; i <= G_N_ELEMENTS (all_fingers); ++i)
g_print (" [%d] %s\n", (i - all_fingers[0]), finger_to_string (i));
g_print ("> ");
if (!scanf ("%d%*c", &i))
return FP_FINGER_UNKNOWN;
i += FP_FINGER_FIRST;
if (i < FP_FINGER_FIRST || i > FP_FINGER_LAST)
if (i < 0 || i >= G_N_ELEMENTS (all_fingers))
return FP_FINGER_UNKNOWN;
return i;
return all_fingers[i];
}

View File

@@ -18,8 +18,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __UTILITIES_H
#define __UTILITIES_H
FpDevice * discover_device (GPtrArray *devices);
FpFinger finger_chooser (void);
const char * finger_to_string (FpFinger finger);
#endif /* __UTILITIES_H */

View File

@@ -19,29 +19,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FP_COMPONENT "example-verify"
#include <stdio.h>
#include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h"
#include "utilities.h"
typedef struct _VerifyData
{
GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger;
int ret_value;
GMainLoop *loop;
FpFinger finger;
int ret_value;
} VerifyData;
static void
verify_data_free (VerifyData *verify_data)
{
g_clear_handle_id (&verify_data->sigint_handler, g_source_remove);
g_clear_object (&verify_data->cancellable);
g_main_loop_unref (verify_data->loop);
g_free (verify_data);
}
@@ -62,19 +55,6 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
g_main_loop_quit (verify_data->loop);
}
static void
verify_quit (FpDevice *dev,
VerifyData *verify_data)
{
if (!fp_device_is_open (dev))
{
g_main_loop_quit (verify_data->loop);
return;
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, verify_data);
}
static void start_verification (FpDevice *dev,
VerifyData *verify_data);
@@ -91,65 +71,35 @@ on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
{
g_warning ("Failed to verify print: %s", error->message);
verify_data->ret_value = EXIT_FAILURE;
g_main_loop_quit (verify_data->loop);
return;
}
if (error->domain != FP_DEVICE_RETRY)
{
verify_quit (dev, verify_data);
return;
}
if (match)
{
g_print ("MATCH!\n");
if (fp_device_supports_capture (dev) &&
print_image_save (print, "verify.pgm"))
g_print ("Print image saved as verify.pgm");
verify_data->ret_value = EXIT_SUCCESS;
}
else
{
g_print ("NO MATCH!\n");
verify_data->ret_value = EXIT_FAILURE;
}
g_print ("Verify again? [Y/n]? ");
if (fgets (buffer, sizeof (buffer), stdin) &&
(buffer[0] == 'Y' || buffer[0] == 'y' || buffer[0] == '\n'))
(buffer[0] == 'Y' || buffer[0] == 'y'))
{
start_verification (dev, verify_data);
return;
}
verify_quit (dev, verify_data);
}
static void
on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
gpointer user_data, GError *error)
{
VerifyData *verify_data = user_data;
if (error)
{
g_warning ("Match report: Finger not matched, retry error reported: %s",
error->message);
return;
}
if (print && fp_device_supports_capture (dev) &&
print_image_save (print, "verify.pgm"))
g_print ("Print image saved as verify.pgm\n");
if (match)
{
char date_str[128];
verify_data->ret_value = EXIT_SUCCESS;
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
fp_print_get_enroll_date (match));
g_debug ("Match report: device %s matched finger %s successifully "
"with print %s, enrolled on date %s by user %s",
fp_device_get_name (dev),
finger_to_string (fp_print_get_finger (match)),
fp_print_get_description (match), date_str,
fp_print_get_username (match));
g_print ("MATCH!\n");
}
else
{
g_debug ("Match report: Finger not matched");
g_print ("NO MATCH!\n");
}
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
verify_data);
}
static void
@@ -193,7 +143,7 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
{
g_warning ("Did you remember to enroll your %s finger first?",
finger_to_string (verify_data->finger));
verify_quit (dev, verify_data);
g_main_loop_quit (verify_data->loop);
return;
}
@@ -201,32 +151,28 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
fp_print_get_description (verify_print));
g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, verify_data->cancellable,
on_match_cb, verify_data, NULL,
fp_device_verify (dev, verify_print, NULL,
(GAsyncReadyCallback) on_verify_completed,
verify_data);
}
else
{
g_warning ("Loading prints failed with error %s", error->message);
verify_quit (dev, verify_data);
g_main_loop_quit (verify_data->loop);
}
}
static void
start_verification (FpDevice *dev, VerifyData *verify_data)
{
if (verify_data->finger == FP_FINGER_UNKNOWN)
{
g_print ("Choose the finger to verify:\n");
verify_data->finger = finger_chooser ();
}
g_print ("Choose the finger to verify:\n");
verify_data->finger = finger_chooser ();
if (verify_data->finger == FP_FINGER_UNKNOWN)
{
g_warning ("Unknown finger selected");
verify_data->ret_value = EXIT_FAILURE;
verify_quit (dev, verify_data);
g_main_loop_quit (verify_data->loop);
return;
}
@@ -250,13 +196,12 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
g_warning ("Failed to load fingerprint data");
g_warning ("Did you remember to enroll your %s finger first?",
finger_to_string (verify_data->finger));
verify_quit (dev, verify_data);
g_main_loop_quit (verify_data->loop);
return;
}
g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, verify_data->cancellable,
NULL, NULL, NULL,
fp_device_verify (dev, verify_print, NULL,
(GAsyncReadyCallback) on_verify_completed,
verify_data);
}
@@ -272,7 +217,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
if (!fp_device_open_finish (dev, res, &error))
{
g_warning ("Failed to open device: %s", error->message);
verify_quit (dev, verify_data);
g_main_loop_quit (verify_data->loop);
return;
}
@@ -281,16 +226,6 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
start_verification (dev, verify_data);
}
static gboolean
sigint_cb (void *user_data)
{
VerifyData *verify_data = user_data;
g_cancellable_cancel (verify_data->cancellable);
return G_SOURCE_CONTINUE;
}
int
main (void)
{
@@ -321,14 +256,8 @@ main (void)
verify_data = g_new0 (VerifyData, 1);
verify_data->ret_value = EXIT_FAILURE;
verify_data->loop = g_main_loop_new (NULL, FALSE);
verify_data->cancellable = g_cancellable_new ();
verify_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
verify_data,
NULL);
fp_device_open (dev, verify_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
verify_data);
g_main_loop_run (verify_data->loop);

View File

@@ -138,7 +138,7 @@ generic_read_ignore_data (FpiSsm *ssm, FpDevice *dev,
unsigned char *data;
data = g_malloc (bytes);
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, bytes, g_free);
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, data, bytes, NULL);
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
@@ -614,7 +614,6 @@ 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;

View File

@@ -18,7 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __AES1660_H
#define __AES1660_H
#define AES1660_FRAME_SIZE 0x244
@@ -1985,3 +1986,5 @@ static const unsigned char aes1660_start_imaging_cmd[] = {
0x55, 0x07, 0x00, 0x80, 0x42, 0x00, 0x7f, 0x00, 0x00, 0x14,
0x49, 0x03, 0x00, 0x20, 0x00, 0xc8
};
#endif

View File

@@ -458,7 +458,6 @@ 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;

View File

@@ -19,7 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __AES2501_H
#define __AES2501_H
enum aes2501_regs {
AES2501_REG_CTRL1 = 0x80,
@@ -171,3 +172,5 @@ enum aes2501_sensor_gain2 {
#define AES2501_SUM_HIGH_THRESH 1000
#define AES2501_SUM_LOW_THRESH 700
#endif /* __AES2501_H */

View File

@@ -230,7 +230,6 @@ 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;

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __AES2550_H
#define __AES2550_H
/* Registers bits */
@@ -109,3 +110,5 @@ enum aes2550_cmds {
#define AES2550_HEARTBEAT_MAGIC 0xdb
#define AES2550_EP_IN_BUF_SIZE 8192
#endif

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __AES2660_H
#define __AES2660_H
#define AES2660_FRAME_SIZE 0x354
@@ -1959,3 +1960,5 @@ static const unsigned char aes2660_start_imaging_cmd[] = {
0x55, 0x07, 0x00, 0x80, 0x42, 0x00, 0xbf, 0x00, 0x00, 0x18,
0x49, 0x03, 0x00, 0x20, 0x08, 0xc8
};
#endif

View File

@@ -19,11 +19,13 @@
#define FP_COMPONENT "aeslib"
#include "drivers_api.h"
#include "fp_internal.h"
#include <errno.h>
#include <string.h>
#include "fpi-usb-transfer.h"
#include "fpi-assembling.h"
#include "aeslib.h"
#define MAX_REGWRITES_PER_REQUEST 16

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __AESLIB_H__
#define __AESLIB_H__
#include <fprint.h>
@@ -44,3 +45,5 @@ unsigned char aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *frame,
unsigned int x,
unsigned int y);
#endif

View File

@@ -331,7 +331,6 @@ 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;

View File

@@ -73,18 +73,18 @@ struct _FpiDeviceElan
/* end commands */
/* state */
gboolean deactivating;
FpiImageDeviceState dev_state;
FpiImageDeviceState dev_state_next;
unsigned char *last_read;
unsigned char calib_atts_left;
unsigned char calib_status;
unsigned short *background;
unsigned char frame_width;
unsigned char frame_height;
unsigned char raw_frame_height;
int num_frames;
GSList *frames;
gboolean deactivating;
FpImageDeviceState dev_state;
FpImageDeviceState dev_state_next;
unsigned char *last_read;
unsigned char calib_atts_left;
unsigned char calib_status;
unsigned short *background;
unsigned char frame_width;
unsigned char frame_height;
unsigned char raw_frame_height;
int num_frames;
GSList *frames;
/* end state */
};
G_DECLARE_FINAL_TYPE (FpiDeviceElan, fpi_device_elan, FPI, DEVICE_ELAN,
@@ -207,7 +207,6 @@ 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;
@@ -245,7 +244,6 @@ 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)
@@ -257,7 +255,6 @@ 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];
@@ -281,7 +278,6 @@ 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];
@@ -291,7 +287,6 @@ 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];
@@ -325,7 +320,6 @@ 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);
@@ -487,7 +481,7 @@ stop_capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
/* The device is inactive at this point. */
self->dev_state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
if (self->deactivating)
{
@@ -515,7 +509,6 @@ 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);
}
@@ -545,7 +538,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
break;
case CAPTURE_READ_DATA:
self->dev_state = FPI_IMAGE_DEVICE_STATE_CAPTURE;
self->dev_state = FP_IMAGE_DEVICE_STATE_CAPTURE;
/* 0x55 - finger present
* 0xff - device not calibrated (probably) */
@@ -556,11 +549,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
}
else
{
/* XXX: The timeout is emulated incorrectly, resulting in a zero byte read. */
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
fpi_ssm_mark_completed (ssm);
else
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
}
break;
@@ -592,6 +581,8 @@ capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
G_DEBUG_HERE ();
/* XXX: cancellation was specially handled by doing nothing! */
/* either max frames captured or timed out waiting for the next frame */
if (!error ||
(g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) &&
@@ -626,7 +617,6 @@ 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);
}
@@ -741,7 +731,7 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
fp_dbg ("calibration failed");
fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Calibration failed!"));
"Callibration failed!"));
}
break;
@@ -783,7 +773,7 @@ calibrate_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
if (error)
{
self->dev_state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
fpi_image_device_session_error (FP_IMAGE_DEVICE (dev), error);
}
else
@@ -805,7 +795,6 @@ elan_calibrate (FpDevice *dev)
FpiSsm *ssm = fpi_ssm_new (FP_DEVICE (dev), calibrate_run_state,
CALIBRATE_NUM_STATES);
fpi_ssm_start (ssm, calibrate_complete);
}
@@ -901,7 +890,6 @@ elan_activate (FpImageDevice *dev)
FpiSsm *ssm =
fpi_ssm_new (FP_DEVICE (dev), activate_run_state,
ACTIVATE_NUM_STATES);
fpi_ssm_start (ssm, activate_complete);
}
@@ -963,7 +951,7 @@ elan_change_state (FpImageDevice *idev)
{
FpDevice *dev = FP_DEVICE (idev);
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
FpiImageDeviceState next_state = self->dev_state_next;
FpImageDeviceState next_state = self->dev_state_next;
if (self->dev_state == next_state)
{
@@ -977,18 +965,18 @@ elan_change_state (FpImageDevice *idev)
switch (next_state)
{
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
/* activation completed or another enroll stage started */
self->dev_state = FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
self->dev_state = FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
elan_calibrate (dev);
break;
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
case FP_IMAGE_DEVICE_STATE_CAPTURE:
/* not used */
break;
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
elan_stop_capture (dev);
break;
}
@@ -998,12 +986,12 @@ static void
elan_change_state_async (FpDevice *dev,
void *data)
{
fp_dbg ("state change dev: %p", dev);
g_message ("state change dev: %p", dev);
elan_change_state (FP_IMAGE_DEVICE (dev));
}
static void
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
{
FpiDeviceElan *self = FPI_DEVICE_ELAN (dev);
GSource *timeout;
@@ -1011,17 +999,17 @@ dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
G_DEBUG_HERE ();
/* Inactive and await finger off are equivalent for the elan driver. */
if (state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
if (state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
state = FP_IMAGE_DEVICE_STATE_INACTIVE;
if (self->dev_state_next == state)
fp_dbg ("change to state %d already queued", state);
switch (state)
{
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: {
case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: {
char *name;
/* schedule state change instead of calling it directly to allow all actions
@@ -1038,7 +1026,7 @@ dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
break;
}
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
case FP_IMAGE_DEVICE_STATE_CAPTURE:
/* TODO MAYBE: split capture ssm into smaller ssms and use this state */
self->dev_state = state;
self->dev_state_next = state;
@@ -1056,7 +1044,7 @@ dev_deactivate (FpImageDevice *dev)
G_DEBUG_HERE ();
if (self->dev_state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
if (self->dev_state == FP_IMAGE_DEVICE_STATE_INACTIVE)
{
/* The device is inactive already, complete the operation immediately. */
fpi_image_device_deactivate_complete (dev, NULL);
@@ -1067,7 +1055,7 @@ dev_deactivate (FpImageDevice *dev)
* need to signal back deactivation) and then ensure we will change
* to the inactive state eventually. */
self->deactivating = TRUE;
dev_change_state (dev, FPI_IMAGE_DEVICE_STATE_INACTIVE);
dev_change_state (dev, FP_IMAGE_DEVICE_STATE_INACTIVE);
}
}

View File

@@ -18,7 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __ELAN_H
#define __ELAN_H
#include <glib.h>
@@ -221,5 +222,7 @@ static void elan_cmd_read (FpiSsm *ssm,
static void elan_calibrate (FpDevice *dev);
static void elan_capture (FpDevice *dev);
static void dev_change_state (FpImageDevice *dev,
FpiImageDeviceState state);
static void dev_change_state (FpImageDevice *dev,
FpImageDeviceState state);
#endif

View File

@@ -859,29 +859,21 @@ m_capture_state (FpiSsm *ssm, FpDevice *dev)
}
else
{
FpImage *img;
unsigned int img_size;
/* Remove empty parts 2 times for the 2 frames */
process_removefpi_end (self);
process_removefpi_end (self);
if (self->fp_height >= FE_WIDTH)
{
FpImage *img = fp_image_new (FE_WIDTH, self->fp_height);
unsigned int img_size = self->fp_height * FE_WIDTH;
/* Images received are white on black, so invert it. */
/* TODO detect sweep direction */
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
img->height = self->fp_height;
process_4to8_bpp (self->fp, img_size / 2, img->data);
fp_dbg ("Sending the raw fingerprint image (%dx%d)",
img->width, img->height);
fpi_image_device_image_captured (idev, img);
}
else
{
fpi_image_device_retry_scan (idev, FP_DEVICE_RETRY_TOO_SHORT);
}
img_size = self->fp_height * FE_WIDTH;
img = fp_image_new (FE_WIDTH, self->fp_height);
/* Images received are white on black, so invert it. */
/* TODO detect sweep direction */
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
img->height = self->fp_height;
process_4to8_bpp (self->fp, img_size / 2, img->data);
fp_dbg ("Sending the raw fingerprint image (%dx%d)",
img->width, img->height);
fpi_image_device_image_captured (idev, img);
fpi_image_device_report_finger_status (idev, FALSE);
fpi_ssm_mark_completed (ssm);
}

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef _BMKT_H_
#define _BMKT_H_
/**< User ID maximum length allowed */
#define BMKT_MAX_USER_ID_LEN 100
@@ -227,3 +228,5 @@ typedef struct bmkt_user_id
#ifdef __cplusplus
}
#endif
#endif /* _BMKT_H_ */

View File

@@ -206,7 +206,6 @@ 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)

View File

@@ -16,7 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef BMKT_MESSAGE_H_
#define BMKT_MESSAGE_H_
#define BMKT_MESSAGE_HEADER_ID 0xFE
#define BMKT_MESSAGE_HEADER_LEN (4)
@@ -87,3 +90,4 @@ int bmkt_parse_message_header (uint8_t *resp_buf,
bmkt_msg_resp_t *msg_resp);
int bmkt_parse_message_payload (bmkt_msg_resp_t *msg_resp,
bmkt_response_t *resp);
#endif /* BMKT_MESSAGE_H_ */

View File

@@ -17,7 +17,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef _BMKT_RESPONSE_H_
#define _BMKT_RESPONSE_H_
#include "bmkt.h"
@@ -316,7 +318,7 @@ typedef struct bmkt_init_resp
*/
typedef struct bmkt_enroll_resp
{
int progress; /**< Shows current progress status [0-100] */
int progress; /**< Shows current progress stutus [0-100] */
uint8_t finger_id; /**< User's finger id [1-10] */
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
} bmkt_enroll_resp_t;
@@ -483,3 +485,5 @@ typedef struct bmkt_response
int complete; /**< Operation completion status 1: complete / 0: not completed */
bmkt_response_data_t response; /**< Operation specific response union */
} bmkt_response_t;
#endif /* _BMKT_RESPONSE_H_ */

View File

@@ -16,7 +16,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef _SENSOR_H_
#define _SENSOR_H_
#include "usb_transport.h"
#define BMKT_MAX_PENDING_SESSIONS 2
@@ -83,3 +84,4 @@ int bmkt_sensor_handle_response (bmkt_sensor_t *sensor,
bmkt_msg_resp_t *msg_resp);
int bmkt_sensor_send_async_read_command (bmkt_sensor_t *sensor);
#endif /* _SENSOR_H_ */

View File

@@ -35,7 +35,7 @@ static const FpIdEntry id_table[] = {
static void
cmd_receive_cb (FpiUsbTransfer *transfer,
cmd_recieve_cb (FpiUsbTransfer *transfer,
FpDevice *device,
gpointer user_data,
GError *error)
@@ -234,7 +234,7 @@ synaptics_cmd_run_state (FpiSsm *ssm,
fpi_usb_transfer_submit (transfer,
5000,
NULL,
cmd_receive_cb,
cmd_recieve_cb,
fpi_ssm_get_data (ssm));
break;
@@ -279,10 +279,17 @@ cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
self->cmd_ssm = NULL;
/* Notify about the SSM failure from here instead. */
if (error || self->cmd_complete_on_removal)
callback (self, NULL, error);
if (error)
{
callback (self, NULL, error);
}
else if (self->cmd_complete_on_removal)
{
callback (self, NULL, self->cmd_complete_error);
self->cmd_complete_error = NULL;
}
self->cmd_complete_on_removal = FALSE;
g_clear_pointer (&self->cmd_complete_error, g_error_free);
}
static void
@@ -321,7 +328,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
g_assert (payload || payload_len == 0);
/* seq_num of 0 means a normal command, -1 means the current commands
* sequence number should not be updated (i.e. second async command which
* sequence number should not be udpated (i.e. second async command which
* may only be a cancellation currently). */
if (seq_num <= 0)
{
@@ -510,12 +517,45 @@ list_msg_cb (FpiDeviceSynaptics *self,
get_enroll_templates_resp->templates[n].finger_id,
uid);
fpi_print_set_type (print, FPI_PRINT_RAW);
fpi_print_set_type (print, FP_PRINT_RAW);
fpi_print_set_device_stored (print, TRUE);
g_object_set (print, "fpi-data", data, NULL);
g_object_set (print, "fp-data", data, NULL);
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
fpi_print_fill_from_user_id (print, userid);
/* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (userid, "FP1-") && strlen (userid) >= 24 &&
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
{
g_autofree gchar *copy = g_strdup (userid);
gint32 date_ymd;
GDate *date = NULL;
gint32 finger;
gchar *username;
/* Try to parse information from the string. */
copy[12] = '\0';
date_ymd = g_ascii_strtod (copy + 4, NULL);
if (date_ymd > 0)
date = g_date_new_dmy (date_ymd % 100,
(date_ymd / 100) % 100,
date_ymd / 10000);
else
date = g_date_new ();
fp_print_set_enroll_date (print, date);
g_date_free (date);
copy[14] = '\0';
finger = g_ascii_strtoll (copy + 13, NULL, 16);
fp_print_set_finger (print, finger);
/* We ignore the next chunk, it is just random data.
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
}
g_ptr_array_add (self->list_result, g_object_ref_sink (print));
}
@@ -542,22 +582,6 @@ list (FpDevice *device)
synaptics_sensor_cmd (self, 0, BMKT_CMD_GET_TEMPLATE_RECORDS, NULL, 0, list_msg_cb);
}
static void
verify_complete_after_finger_removal (FpiDeviceSynaptics *self)
{
FpDevice *device = FP_DEVICE (self);
if (self->finger_on_sensor)
{
fp_dbg ("delaying verify report until after finger removal!");
self->cmd_complete_on_removal = TRUE;
}
else
{
fpi_device_verify_complete (device, NULL);
}
}
static void
verify_msg_cb (FpiDeviceSynaptics *self,
bmkt_response_t *resp,
@@ -568,13 +592,16 @@ verify_msg_cb (FpiDeviceSynaptics *self,
if (error)
{
fpi_device_verify_complete (device, error);
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
return;
}
if (resp == NULL && self->cmd_complete_on_removal)
{
fpi_device_verify_complete (device, NULL);
fpi_device_verify_complete (device,
GPOINTER_TO_INT (self->cmd_complete_data),
NULL,
error);
return;
}
@@ -593,40 +620,39 @@ verify_msg_cb (FpiDeviceSynaptics *self,
break;
case BMKT_RSP_VERIFY_FAIL:
if (resp->result == BMKT_SENSOR_STIMULUS_ERROR)
if(resp->result == BMKT_SENSOR_STIMULUS_ERROR)
{
fp_info ("Match error occurred");
fpi_device_verify_report (device, FPI_MATCH_ERROR, NULL,
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
verify_complete_after_finger_removal (self);
fp_dbg ("delaying retry error until after finger removal!");
self->cmd_complete_on_removal = TRUE;
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_ERROR);
self->cmd_complete_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
}
else if (resp->result == BMKT_FP_NO_MATCH)
{
fp_info ("Print didn't match");
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, NULL);
verify_complete_after_finger_removal (self);
fp_dbg ("delaying match failure until after finger removal!");
self->cmd_complete_on_removal = TRUE;
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_FAIL);
self->cmd_complete_error = NULL;
}
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
else if (BMKT_FP_DATABASE_NO_RECORD_EXISTS)
{
fp_info ("Print is not in database");
fpi_device_verify_complete (device,
FPI_MATCH_ERROR,
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
}
else
{
fp_warn ("Verify has failed: %d", resp->result);
fpi_device_verify_complete (device,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Unexpected result from device %d",
resp->result));
fpi_device_verify_complete (device, FPI_MATCH_FAIL, NULL, NULL);
}
break;
case BMKT_RSP_VERIFY_OK:
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, NULL);
fpi_device_verify_complete (device, NULL);
fpi_device_verify_complete (device, FPI_MATCH_SUCCESS, NULL, NULL);
break;
}
}
@@ -644,11 +670,13 @@ verify (FpDevice *device)
fpi_device_get_verify_data (device, &print);
g_object_get (print, "fpi-data", &data, NULL);
g_object_get (print, "fp-data", &data, NULL);
g_debug ("data is %p", data);
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
{
fpi_device_verify_complete (device,
FPI_MATCH_ERROR,
NULL,
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
return;
}
@@ -698,7 +726,7 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
if (enroll_resp->progress < 100)
done_stages = MIN (done_stages, ENROLL_SAMPLES - 1);
/* Emit a retry error if there has been no discernible
/* Emit a retry error if there has been no discernable
* progress. Some firmware revisions report more required
* touches. */
if (self->enroll_stage == done_stages)
@@ -763,6 +791,8 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
}
}
#define TEMPLATE_ID_SIZE 20
static void
enroll (FpDevice *device)
{
@@ -770,21 +800,52 @@ enroll (FpDevice *device)
FpPrint *print = NULL;
GVariant *data = NULL;
GVariant *uid = NULL;
const gchar *username;
guint finger;
g_autofree gchar *user_id = NULL;
gssize user_id_len;
g_autofree guint8 *payload = NULL;
const GDate *date;
gint y, m, d;
gint32 rand_id = 0;
fpi_device_get_enroll_data (device, &print);
G_DEBUG_HERE ();
user_id = fpi_print_generate_user_id (print);
date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
else
{
y = 0;
m = 0;
d = 0;
}
username = fp_print_get_username (print);
if (!username)
username = "nobody";
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
fp_print_get_finger (print),
rand_id,
username);
user_id_len = strlen (user_id);
user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len);
/* We currently always use finger 1 from the devices point of view */
/* We currently always use finger 1 from the devices piont of view */
finger = 1;
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
@@ -795,9 +856,9 @@ enroll (FpDevice *device)
finger,
uid);
fpi_print_set_type (print, FPI_PRINT_RAW);
fpi_print_set_type (print, FP_PRINT_RAW);
fpi_print_set_device_stored (print, TRUE);
g_object_set (print, "fpi-data", data, NULL);
g_object_set (print, "fp-data", data, NULL);
g_object_set (print, "description", user_id, NULL);
g_debug ("user_id: %s, finger: %d", user_id, finger);
@@ -866,7 +927,7 @@ delete_print (FpDevice *device)
fpi_device_get_delete_data (device, &print);
g_object_get (print, "fpi-data", &data, NULL);
g_object_get (print, "fp-data", &data, NULL);
g_debug ("data is %p", data);
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
{
@@ -964,7 +1025,7 @@ dev_probe (FpDevice *device)
if (!read_ok)
{
g_warning ("Transfer in response to version query was too short");
g_warning ("Transfer in response to verison query was too short");
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close;
}

View File

@@ -16,7 +16,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __synaptics_h__
#define __synaptics_h__
#include "fpi-device.h"
#include "fpi-ssm.h"
@@ -110,6 +111,8 @@ struct _FpiDeviceSynaptics
FpiSsm *cmd_ssm;
FpiUsbTransfer *cmd_pending_transfer;
gboolean cmd_complete_on_removal;
GError *cmd_complete_error;
void *cmd_complete_data;
bmkt_sensor_version_t mis_version;
@@ -123,3 +126,5 @@ struct _FpiDeviceSynaptics
struct syna_enroll_resp_data enroll_resp_data;
syna_state_t state;
};
#endif //__synaptics_h__

View File

@@ -19,7 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __UPEKTC_H
#define __UPEKTC_H
#define UPEKTC_CMD_LEN 0x40
#define IMAGE_WIDTH 208
@@ -1935,3 +1936,5 @@ static const unsigned char scan_cmd[0x40] = {
0x05, 0x90, 0xf6, 0x77, 0x84, 0xf5, 0x2f, 0x01,
0x05, 0x90, 0xf6, 0x00, 0xc8, 0x00, 0xec, 0x00
};
#endif

View File

@@ -310,7 +310,6 @@ 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);

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __UPEKTC_IMG_H
#define __UPEKTC_IMG_H
static const unsigned char upek2020_init_1[] = {
'C', 'i', 'a', 'o',
@@ -139,3 +140,5 @@ static const unsigned char upek2020_ack_frame[] = {
0x30,
0xac, 0x5b /* CRC */
};
#endif

View File

@@ -35,6 +35,7 @@
#define TIMEOUT 5000
#define MSG_READ_BUF_SIZE 0x40
#define MAX_DATA_IN_READ_BUF (MSG_READ_BUF_SIZE - 9)
struct _FpiDeviceUpekts
{
@@ -235,18 +236,12 @@ __handle_incoming_msg (FpDevice *device,
{
GError *error = NULL;
guint8 *buf = udata->buffer;
guint16 len;
guint16 computed_crc;
guint16 msg_crc;
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;
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);
@@ -272,7 +267,12 @@ __handle_incoming_msg (FpDevice *device,
return;
}
udata->callback (device, READ_MSG_CMD, code_a, 0, buf + 7, len,
if (len > 0)
{
retdata = g_malloc (len);
memcpy (retdata, buf + 7, len);
}
udata->callback (device, READ_MSG_CMD, code_a, 0, retdata, len,
udata->user_data, NULL);
goto done;
}
@@ -309,8 +309,14 @@ __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,
innerbuf + 6, innerlen, udata->user_data, NULL);
retdata, innerlen, udata->user_data, NULL);
g_free (retdata);
goto done;
}
else
@@ -352,8 +358,7 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
struct read_msg_data *udata = user_data;
guint16 payload_len;
gsize packet_len;
guint16 len;
if (error)
{
@@ -378,15 +383,14 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
goto err;
}
payload_len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
packet_len = payload_len + 9;
len = ((udata->buffer[5] & 0xf) << 8) | udata->buffer[6];
if (transfer->actual_length != MSG_READ_BUF_SIZE &&
packet_len > transfer->actual_length)
(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",
(gint) packet_len, (gint) transfer->actual_length);
len + 9, (gint) transfer->actual_length);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Packet from device didn't include data");
goto err;
@@ -395,14 +399,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 (packet_len > MSG_READ_BUF_SIZE)
if (len > MAX_DATA_IN_READ_BUF)
{
int needed = packet_len - MSG_READ_BUF_SIZE;
int needed = len - MAX_DATA_IN_READ_BUF;
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, packet_len);
udata->buflen = packet_len;
udata->buffer = g_realloc ((gpointer) udata->buffer, len);
udata->buflen = len;
fpi_usb_transfer_fill_bulk_full (etransfer, EP_IN,
udata->buffer + MSG_READ_BUF_SIZE,
@@ -696,7 +700,7 @@ initsm_run_state (FpiSsm *ssm, FpDevice *dev)
break;
case SEND_RESP03:;
transfer = alloc_send_cmdresponse_transfer (dev, ++upekdev->seq, init_resp03, sizeof (init_resp03));
transfer = alloc_send_cmd28_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);
@@ -853,15 +857,22 @@ dev_init (FpDevice *dev)
}
static void
dev_exit (FpDevice *dev)
deinitsm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
{
GError *error = NULL;
g_usb_device_release_interface (fpi_device_get_usb_device (dev), 0, 0, &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;
ssm = fpi_ssm_new (dev, deinitsm_state_handler, DEINITSM_NUM_STATES);
fpi_ssm_start (ssm, deinitsm_done);
}
static const unsigned char enroll_init[] = {
0x02, 0xc0, 0xd4, 0x01, 0x00, 0x04, 0x00, 0x08
};
@@ -891,10 +902,8 @@ enroll_start_sm_cb_msg28 (FpDevice *dev,
FpiSsm *ssm = user_data;
if (error)
{
fpi_ssm_mark_failed (ssm, error);
}
else if (type != READ_MSG_RESPONSE)
fpi_ssm_mark_failed (ssm, error);
if (type != READ_MSG_RESPONSE)
{
fp_err ("expected response, got %d seq=%x", type, seq);
fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
@@ -972,9 +981,7 @@ enroll_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
if (error)
fp_warn ("Error deinitializing: %s", error->message);
fpi_device_enroll_complete (dev,
g_steal_pointer (&data->print),
g_steal_pointer (&data->error));
fpi_device_enroll_complete (dev, data->print, data->error);
}
static void
@@ -983,7 +990,7 @@ do_enroll_stop (FpDevice *dev, FpPrint *print, GError *error)
EnrollStopData *data = g_new0 (EnrollStopData, 1);
FpiSsm *ssm = deinitsm_new (dev, data);
data->print = print;
data->print = g_object_ref (print);
data->error = error;
fpi_ssm_start (ssm, enroll_stop_deinit_cb);
@@ -1110,6 +1117,7 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
else
{
GVariant *fp_data;
print = fp_print_new (dev);
fpi_device_get_enroll_data (dev, &print);
@@ -1118,8 +1126,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_set (print, "fp-data", fp_data, NULL);
g_object_ref (print);
}
@@ -1218,7 +1225,8 @@ enroll (FpDevice *dev)
typedef struct
{
GError *error;
FpiMatchResult res;
GError *error;
} VerifyStopData;
static void
@@ -1236,12 +1244,7 @@ verify_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
if (error)
fp_warn ("Error deinitializing: %s", error->message);
if (data->error)
fpi_device_verify_complete (dev, g_steal_pointer (&data->error));
else
fpi_device_verify_complete (dev, g_steal_pointer (&error));
g_clear_error (&error);
fpi_device_verify_complete (dev, data->res, NULL, data->error);
}
static void
@@ -1250,11 +1253,8 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
VerifyStopData *data = g_new0 (VerifyStopData, 1);
FpiSsm *ssm = deinitsm_new (dev, data);
/* Report the error immediately if possible, otherwise delay it. */
if (error && error->domain == FP_DEVICE_RETRY)
fpi_device_verify_report (dev, res, NULL, error);
else
data->error = error;
data->res = res;
data->error = error;
fpi_ssm_start (ssm, verify_stop_deinit_cb);
fpi_ssm_set_data (ssm, data, (GDestroyNotify) verify_stop_data_free);
@@ -1293,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 (print, "fpi-data", &fp_data, NULL);
g_object_get (dev, "fp-data", &fp_data, NULL);
data = g_variant_get_fixed_array (fp_data, &data_len, 1);

View File

@@ -122,7 +122,7 @@ struct _FpiDeviceUru4000
const struct uru4k_dev_profile *profile;
uint8_t interface;
FpiImageDeviceState activate_state;
FpImageDeviceState activate_state;
unsigned char last_reg_rd[16];
unsigned char last_hwstat;
@@ -408,16 +408,16 @@ change_state_write_reg_cb (FpiUsbTransfer *transfer,
}
static void
dev_change_state (FpImageDevice *dev, FpiImageDeviceState state)
dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
{
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
switch (state)
{
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
case FP_IMAGE_DEVICE_STATE_CAPTURE:
break;
default:
@@ -773,7 +773,7 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
fpimg->flags |= FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
fpi_image_device_image_captured (dev, fpimg);
if (self->activate_state == FPI_IMAGE_DEVICE_STATE_CAPTURE)
if (self->activate_state == FP_IMAGE_DEVICE_STATE_CAPTURE)
fpi_ssm_jump_to_state (ssm, IMAGING_CAPTURE);
else
fpi_ssm_mark_completed (ssm);
@@ -1176,7 +1176,7 @@ deactivate_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *dev,
static void
dev_deactivate (FpImageDevice *dev)
{
dev_change_state (dev, FPI_IMAGE_DEVICE_STATE_INACTIVE);
dev_change_state (dev, FP_IMAGE_DEVICE_STATE_INACTIVE);
}
static void
@@ -1187,7 +1187,7 @@ execute_state_change (FpImageDevice *dev)
switch (self->activate_state)
{
case FPI_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_INACTIVE:
fp_dbg ("deactivating");
self->irq_cb = NULL;
self->irq_cb_data = NULL;
@@ -1195,7 +1195,7 @@ execute_state_change (FpImageDevice *dev)
deactivate_write_reg_cb, NULL);
break;
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
fp_dbg ("wait finger on");
if (!IRQ_HANDLER_IS_RUNNING (self))
{
@@ -1209,7 +1209,7 @@ execute_state_change (FpImageDevice *dev)
change_state_write_reg_cb, NULL);
break;
case FPI_IMAGE_DEVICE_STATE_CAPTURE:
case FP_IMAGE_DEVICE_STATE_CAPTURE:
fp_dbg ("starting capture");
self->irq_cb = NULL;
@@ -1229,7 +1229,7 @@ execute_state_change (FpImageDevice *dev)
change_state_write_reg_cb, NULL);
break;
case FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
fp_dbg ("await finger off");
if (!IRQ_HANDLER_IS_RUNNING (self))
{

View File

@@ -119,7 +119,7 @@ async_abort_callback (FpiUsbTransfer *transfer, FpDevice *device,
/* In normal case endpoint is empty */
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT))
{
g_error_free (error);
g_free (error);
fpi_ssm_next_state (transfer->ssm);
return;
}
@@ -156,8 +156,6 @@ 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);
}
@@ -242,7 +240,6 @@ 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);
@@ -467,8 +464,8 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
if (error)
g_error_free (error);
/* Capture is done when there is no more data to transfer or device timed out */
if (transfer->actual_length <= 0)
/* Check if fingerprint data is over */
if (transfer->actual_length == 0)
{
fpi_ssm_next_state (transfer->ssm);
}
@@ -476,7 +473,7 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
{
self->bytes += transfer->actual_length;
/* Try reading more data */
/* We need more data */
fpi_ssm_jump_to_state (transfer->ssm,
fpi_ssm_get_cur_state (transfer->ssm));
}
@@ -598,7 +595,8 @@ 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,
@@ -670,7 +668,6 @@ 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);
}
@@ -714,7 +711,6 @@ 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);
}

View File

@@ -177,7 +177,6 @@ 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;

View File

@@ -381,8 +381,9 @@ submit_image (FpiSsm *ssm,
{
FpImage *img;
if (self->lines_recorded < VFS5011_IMAGE_WIDTH)
if (self->lines_recorded == 0)
{
/* == FP_ENROLL_RETRY_TOO_SHORT */
fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_TOO_SHORT);
return;
}

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __VFS5011_PROTO_H
#define __VFS5011_PROTO_H
#define VFS5011_LINE_SIZE 240
#define VFS5011_IMAGE_WIDTH 160
@@ -6181,3 +6182,5 @@ static unsigned char vfs5011_prepare_04[] = { /* 2903 B */
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
};
#endif

View File

@@ -21,7 +21,7 @@
/*
* This is a virtual driver to debug the image based drivers. A small
* python script is provided to connect to it via a socket, allowing
* prints to be sent to this device programmatically.
* prints to be sent to this device programatically.
* Using this it is possible to test libfprint and fprintd.
*/
@@ -252,7 +252,6 @@ 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 ();

View File

@@ -2,7 +2,6 @@
* Driver API definitions
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,14 +18,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __DRIVERS_API_H__
#define __DRIVERS_API_H__
#include <config.h>
#include "fp_internal.h"
#include "fpi-compat.h"
#include "fpi-assembling.h"
#include "fpi-device.h"
#include "fpi-image-device.h"
#include "fpi-image.h"
#include "fpi-log.h"
#include "fpi-print.h"
#include "fpi-usb-transfer.h"
#include "fpi-ssm.h"
#include "fpi-assembling.h"
#include "fpi-image-device.h"
#endif

View File

@@ -94,21 +94,22 @@ async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer u
FpContext *context;
FpContextPrivate *priv;
device = FP_DEVICE (g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
res, &error));
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context);
priv->pending_devices--;
if (error)
device = (FpDevice *) g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error);
if (!device)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context);
priv->pending_devices--;
g_message ("Ignoring device due to initialization error: %s", error->message);
return;
}
context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context);
priv->pending_devices--;
g_ptr_array_add (priv->devices, device);
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
}
@@ -130,7 +131,8 @@ usb_device_added_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx)
for (i = 0; i < priv->drivers->len; i++)
{
GType driver = g_array_index (priv->drivers, GType, i);
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
const FpIdEntry *entry;
if (cls->type != FP_DEVICE_TYPE_USB)
@@ -158,7 +160,7 @@ usb_device_added_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx)
if (found_driver == G_TYPE_NONE)
{
g_debug ("No driver found for USB device %04X:%04X", vid, pid);
g_debug ("No driver found for USB device %04X:%04X", pid, vid);
return;
}
@@ -168,8 +170,8 @@ usb_device_added_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx)
priv->cancellable,
async_device_init_done_cb,
self,
"fpi-usb-device", device,
"fpi-driver-data", found_entry->driver_data,
"fp-usb-device", device,
"fp-driver-data", found_entry->driver_data,
NULL);
}
@@ -274,7 +276,8 @@ fp_context_init (FpContext *self)
for (i = 0; i < priv->drivers->len;)
{
GType driver = g_array_index (priv->drivers, GType, i);
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
if (!is_driver_allowed (cls->id))
g_array_remove_index (priv->drivers, i);
@@ -348,7 +351,8 @@ fp_context_enumerate (FpContext *context)
for (i = 0; i < priv->drivers->len; i++)
{
GType driver = g_array_index (priv->drivers, GType, i);
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
const FpIdEntry *entry;
if (cls->type != FP_DEVICE_TYPE_VIRTUAL)
@@ -369,8 +373,8 @@ fp_context_enumerate (FpContext *context)
priv->cancellable,
async_device_init_done_cb,
context,
"fpi-environ", val,
"fpi-driver-data", entry->driver_data,
"fp-environ", val,
"fp-driver-data", entry->driver_data,
NULL);
g_debug ("created");
}

View File

@@ -41,7 +41,7 @@ typedef struct
GSList *sources;
/* We always make sure that only one task is run at a time. */
FpiDeviceAction current_action;
FpDeviceAction current_action;
GTask *current_task;
GAsyncReadyCallback current_user_cb;
gulong current_cancellable_id;
@@ -63,20 +63,3 @@ typedef struct
} FpEnrollData;
void enroll_data_free (FpEnrollData *enroll_data);
typedef struct
{
FpPrint *enrolled_print; /* verify */
GPtrArray *gallery; /* identify */
gboolean result_reported;
FpPrint *match;
FpPrint *print;
GError *error;
FpMatchCb match_cb;
gpointer match_data;
GDestroyNotify match_destroy;
} FpMatchData;
void match_data_free (FpMatchData *match_data);

View File

@@ -24,11 +24,16 @@
#include "fp-device-private.h"
/**
* SECTION: fp-device
* @title: FpDevice
* @short_description: Fingerpint device routines
* SECTION: fpi-device
* @title: Internal FpDevice
* @short_description: Internal device routines
*
* These are the public #FpDevice routines.
* The methods that are availabe 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.
*/
static void fp_device_async_initable_iface_init (GAsyncInitableIface *iface);
@@ -76,7 +81,7 @@ fp_device_cancel_in_idle_cb (gpointer user_data)
FpDevicePrivate *priv = fp_device_get_instance_private (self);
g_assert (cls->cancel);
g_assert (priv->current_action != FPI_DEVICE_ACTION_NONE);
g_assert (priv->current_action != FP_DEVICE_ACTION_NONE);
g_debug ("Idle cancelling on ongoing operation!");
@@ -143,7 +148,7 @@ fp_device_finalize (GObject *object)
FpDevice *self = (FpDevice *) object;
FpDevicePrivate *priv = fp_device_get_instance_private (self);
g_assert (priv->current_action == FPI_DEVICE_ACTION_NONE);
g_assert (priv->current_action == FP_DEVICE_ACTION_NONE);
g_assert (priv->current_task == NULL);
if (priv->is_open)
g_warning ("User destroyed open device! Not cleaning up properly!");
@@ -263,7 +268,7 @@ fp_device_async_initable_init_async (GAsyncInitable *initable,
return;
}
priv->current_action = FPI_DEVICE_ACTION_PROBE;
priv->current_action = FP_DEVICE_ACTION_PROBE;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (self, cancellable);
@@ -334,46 +339,25 @@ fp_device_class_init (FpDeviceClass *klass)
properties[PROP_OPEN] =
g_param_spec_boolean ("open",
"Opened",
"Whether the device is open or not", FALSE,
"Wether the device is open or not", FALSE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
/**
* FpDevice::fpi-environ: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_ENVIRON] =
g_param_spec_string ("fpi-environ",
g_param_spec_string ("fp-environ",
"Virtual Environment",
"Private: The environment variable for the virtual device",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
/**
* FpDevice::fpi-usb-device: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_USB_DEVICE] =
g_param_spec_object ("fpi-usb-device",
g_param_spec_object ("fp-usb-device",
"USB Device",
"Private: The USB device for the device",
G_USB_TYPE_DEVICE,
G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
/**
* FpDevice::fpi-driver-data: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_DRIVER_DATA] =
g_param_spec_uint64 ("fpi-driver-data",
g_param_spec_uint64 ("fp-driver-data",
"Driver Data",
"Private: The driver data from the ID table entry",
0,
@@ -600,7 +584,7 @@ fp_device_open (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_OPEN;
priv->current_action = FP_DEVICE_ACTION_OPEN;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
@@ -664,7 +648,7 @@ fp_device_close (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_CLOSE;
priv->current_action = FP_DEVICE_ACTION_CLOSE;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
@@ -725,7 +709,7 @@ fp_device_enroll (FpDevice *device,
g_autoptr(GTask) task = NULL;
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpEnrollData *data;
FpiPrintType print_type;
FpPrintType print_type;
task = g_task_new (device, cancellable, callback, user_data);
if (g_task_return_error_if_cancelled (task))
@@ -753,8 +737,8 @@ fp_device_enroll (FpDevice *device,
return;
}
g_object_get (template_print, "fpi-type", &print_type, NULL);
if (print_type != FPI_PRINT_UNDEFINED)
g_object_get (template_print, "fp-type", &print_type, NULL);
if (print_type != FP_PRINT_UNDEFINED)
{
g_warning ("Passed print template must be newly created and blank!");
g_task_return_error (task,
@@ -762,7 +746,7 @@ fp_device_enroll (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_ENROLL;
priv->current_action = FP_DEVICE_ACTION_ENROLL;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
@@ -770,7 +754,6 @@ fp_device_enroll (FpDevice *device,
data->print = g_object_ref_sink (template_print);
data->enroll_progress_cb = progress_cb;
data->enroll_progress_data = progress_data;
data->enroll_progress_destroy = progress_destroy;
// Attach the progress data as task data so that it is destroyed
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) enroll_data_free);
@@ -804,13 +787,10 @@ fp_device_enroll_finish (FpDevice *device,
* @device: a #FpDevice
* @enrolled_print: a #FpPrint to verify
* @cancellable: (nullable): a #GCancellable, or %NULL
* @match_cb: (nullable) (scope notified): match reporting callback
* @match_data: (closure match_cb): user data for @match_cb
* @match_destroy: (destroy match_data): Destroy notify for @match_data
* @callback: the function to call on completion
* @user_data: the data to pass to @callback
*
* Start an asynchronous operation to verify a print. The callback will
* Start an asynchronous operation to close the device. The callback will
* be called once the operation has finished. Retrieve the result with
* fp_device_verify_finish().
*/
@@ -818,15 +798,11 @@ void
fp_device_verify (FpDevice *device,
FpPrint *enrolled_print,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
GDestroyNotify match_destroy,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GTask) task = NULL;
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data;
task = g_task_new (device, cancellable, callback, user_data);
if (g_task_return_error_if_cancelled (task))
@@ -846,18 +822,13 @@ fp_device_verify (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_VERIFY;
priv->current_action = FP_DEVICE_ACTION_VERIFY;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
data = g_new0 (FpMatchData, 1);
data->enrolled_print = g_object_ref (enrolled_print);
data->match_cb = match_cb;
data->match_data = match_data;
data->match_destroy = match_destroy;
// Attach the match data as task data so that it is destroyed
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) match_data_free);
g_task_set_task_data (priv->current_task,
g_object_ref (enrolled_print),
g_object_unref);
FP_DEVICE_GET_CLASS (device)->verify (device);
}
@@ -893,11 +864,7 @@ fp_device_verify_finish (FpDevice *device,
if (print)
{
FpMatchData *data;
data = g_task_get_task_data (G_TASK (result));
*print = data->print;
*print = g_object_get_data (G_OBJECT (result), "print");
if (*print)
g_object_ref (*print);
}
@@ -913,9 +880,6 @@ fp_device_verify_finish (FpDevice *device,
* @device: a #FpDevice
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
* @cancellable: (nullable): a #GCancellable, or %NULL
* @match_cb: (nullable) (scope notified): match reporting callback
* @match_data: (closure match_cb): user data for @match_cb
* @match_destroy: (destroy match_data): Destroy notify for @match_data
* @callback: the function to call on completion
* @user_data: the data to pass to @callback
*
@@ -927,15 +891,11 @@ void
fp_device_identify (FpDevice *device,
GPtrArray *prints,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
GDestroyNotify match_destroy,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GTask) task = NULL;
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data;
task = g_task_new (device, cancellable, callback, user_data);
if (g_task_return_error_if_cancelled (task))
@@ -955,18 +915,13 @@ fp_device_identify (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_IDENTIFY;
priv->current_action = FP_DEVICE_ACTION_IDENTIFY;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
data = g_new0 (FpMatchData, 1);
data->gallery = g_ptr_array_ref (prints);
data->match_cb = match_cb;
data->match_data = match_data;
data->match_destroy = match_destroy;
// Attach the match data as task data so that it is destroyed
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) match_data_free);
g_task_set_task_data (priv->current_task,
g_ptr_array_ref (prints),
(GDestroyNotify) g_ptr_array_unref);
FP_DEVICE_GET_CLASS (device)->identify (device);
}
@@ -997,19 +952,15 @@ fp_device_identify_finish (FpDevice *device,
FpPrint **print,
GError **error)
{
FpMatchData *data;
data = g_task_get_task_data (G_TASK (result));
if (print)
{
*print = data->print;
*print = g_object_get_data (G_OBJECT (result), "print");
if (*print)
g_object_ref (*print);
}
if (match)
{
*match = data->match;
*match = g_object_get_data (G_OBJECT (result), "match");
if (*match)
g_object_ref (*match);
}
@@ -1057,7 +1008,7 @@ fp_device_capture (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_CAPTURE;
priv->current_action = FP_DEVICE_ACTION_CAPTURE;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
@@ -1138,7 +1089,7 @@ fp_device_delete_print (FpDevice *device,
return;
}
priv->current_action = FPI_DEVICE_ACTION_DELETE;
priv->current_action = FP_DEVICE_ACTION_DELETE;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
@@ -1208,15 +1159,7 @@ fp_device_list_prints (FpDevice *device,
return;
}
if (!fp_device_has_storage (device))
{
g_task_return_error (task,
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
"Device has no storage"));
return;
}
priv->current_action = FPI_DEVICE_ACTION_LIST;
priv->current_action = FP_DEVICE_ACTION_LIST;
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
@@ -1344,8 +1287,6 @@ fp_device_enroll_sync (FpDevice *device,
* @device: a #FpDevice
* @enrolled_print: a #FpPrint to verify
* @cancellable: (nullable): a #GCancellable, or %NULL
* @match_cb: (nullable) (scope call): match reporting callback
* @match_data: (closure match_cb): user data for @match_cb
* @match: (out): Whether the user presented the correct finger
* @print: (out) (transfer full) (nullable): Location to store the scanned print, or %NULL to ignore
* @error: Return location for errors, or %NULL to ignore
@@ -1358,8 +1299,6 @@ gboolean
fp_device_verify_sync (FpDevice *device,
FpPrint *enrolled_print,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
gboolean *match,
FpPrint **print,
GError **error)
@@ -1371,7 +1310,6 @@ fp_device_verify_sync (FpDevice *device,
fp_device_verify (device,
enrolled_print,
cancellable,
match_cb, match_data, NULL,
async_result_ready, &task);
while (!task)
g_main_context_iteration (NULL, TRUE);
@@ -1384,8 +1322,6 @@ fp_device_verify_sync (FpDevice *device,
* @device: a #FpDevice
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
* @cancellable: (nullable): a #GCancellable, or %NULL
* @match_cb: (nullable) (scope call): match reporting callback
* @match_data: (closure match_cb): user data for @match_cb
* @match: (out) (transfer full) (nullable): Location for the matched #FpPrint, or %NULL
* @print: (out) (transfer full) (nullable): Location for the new #FpPrint, or %NULL
* @error: Return location for errors, or %NULL to ignore
@@ -1398,8 +1334,6 @@ gboolean
fp_device_identify_sync (FpDevice *device,
GPtrArray *prints,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
FpPrint **match,
FpPrint **print,
GError **error)
@@ -1411,7 +1345,6 @@ fp_device_identify_sync (FpDevice *device,
fp_device_identify (device,
prints,
cancellable,
match_cb, match_data, NULL,
async_result_ready, &task);
while (!task)
g_main_context_iteration (NULL, TRUE);

View File

@@ -79,7 +79,7 @@ typedef enum {
/**
* FpDeviceError:
* @FP_DEVICE_ERROR_GENERAL: A general error occurred.
* @FP_DEVICE_ERROR_GENERAL: A general error occured.
* @FP_DEVICE_ERROR_NOT_SUPPORTED: The device does not support the requested
* operation.
* @FP_DEVICE_ERROR_NOT_OPEN: The device needs to be opened to start this
@@ -113,7 +113,7 @@ GQuark fp_device_error_quark (void);
* FpEnrollProgress:
* @device: a #FpDevice
* @completed_stages: Number of completed stages
* @print: (nullable) (transfer none): The last scanned print
* @print: (nullable) (transfer none): The last scaned print
* @user_data: (nullable) (transfer none): User provided data
* @error: (nullable) (transfer none): #GError or %NULL
*
@@ -125,43 +125,6 @@ typedef void (*FpEnrollProgress) (FpDevice *device,
gpointer user_data,
GError *error);
/**
* FpMatchCb:
* @device: a #FpDevice
* @match: (nullable) (transfer none): The matching print if any matched @print
* @print: (nullable) (transfer none): The newly scanned print
* @user_data: (nullable) (transfer none): User provided data
* @error: (nullable) (transfer none): #GError or %NULL
*
* Report the result of a match (identify or verify) operation.
*
* If @match is non-%NULL, then it is set to the matching #FpPrint as passed
* to the match operation. In this case @error will always be %NULL.
*
* If @error is not %NULL then its domain is guaranteed to be
* %FP_DEVICE_RETRY. All other error conditions will not be reported using
* this callback. If such an error occurs before a match/no-match decision
* can be made, then this callback will not be called. Should an error
* happen afterwards, then you will get a match report through this callback
* and an error when the operation finishes.
*
* If @match and @error are %NULL, then a finger was presented but it did not
* match any known print.
*
* @print represents the newly scanned print. The driver may or may not
* provide this information. Image based devices will provide it and it
* allows access to the raw data.
*
* This callback exists because it makes sense for drivers to wait e.g. on
* finger removal before completing the match operation. However, the
* success/failure can often be reported at an earlier time, and there is
* no need to make the user wait.
*/
typedef void (*FpMatchCb) (FpDevice *device,
FpPrint *match,
FpPrint *print,
gpointer user_data,
GError *error);
const gchar *fp_device_get_driver (FpDevice *device);
const gchar *fp_device_get_device_id (FpDevice *device);
@@ -197,18 +160,12 @@ void fp_device_enroll (FpDevice *device,
void fp_device_verify (FpDevice *device,
FpPrint *enrolled_print,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
GDestroyNotify match_destroy,
GAsyncReadyCallback callback,
gpointer user_data);
void fp_device_identify (FpDevice *device,
GPtrArray *prints,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
GDestroyNotify match_destroy,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -274,16 +231,12 @@ FpPrint * fp_device_enroll_sync (FpDevice *device,
gboolean fp_device_verify_sync (FpDevice *device,
FpPrint *enrolled_print,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
gboolean *match,
FpPrint **print,
GError **error);
gboolean fp_device_identify_sync (FpDevice *device,
GPtrArray *prints,
GCancellable *cancellable,
FpMatchCb match_cb,
gpointer match_data,
FpPrint **match,
FpPrint **print,
GError **error);

View File

@@ -25,17 +25,17 @@
typedef struct
{
FpiImageDeviceState state;
gboolean active;
gboolean cancelling;
FpImageDeviceState state;
gboolean active;
gboolean cancelling;
gboolean enroll_await_on_pending;
gint enroll_stage;
gboolean enroll_await_on_pending;
gint enroll_stage;
guint pending_activation_timeout_id;
gboolean pending_activation_timeout_waiting_finger_off;
guint pending_activation_timeout_id;
gboolean pending_activation_timeout_waiting_finger_off;
gint bz3_threshold;
gint bz3_threshold;
} FpImageDevicePrivate;

View File

@@ -100,13 +100,13 @@ fp_image_device_close (FpDevice *device)
* 1. We are inactive
* -> immediately close
* 2. We are waiting for finger off
* -> immediately deactivate
* -> imediately deactivate
* 3. We are deactivating
* -> handled by deactivate_complete */
if (!priv->active)
cls->img_close (self);
else if (priv->state != FPI_IMAGE_DEVICE_STATE_INACTIVE)
else if (priv->state != FP_IMAGE_DEVICE_STATE_INACTIVE)
fpi_image_device_deactivate (self);
}
@@ -115,16 +115,16 @@ fp_image_device_cancel_action (FpDevice *device)
{
FpImageDevice *self = FP_IMAGE_DEVICE (device);
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
action = fpi_device_get_current_action (device);
/* We can only cancel capture operations, in that case, deactivate and return
* an error immediately. */
if (action == FPI_DEVICE_ACTION_ENROLL ||
action == FPI_DEVICE_ACTION_VERIFY ||
action == FPI_DEVICE_ACTION_IDENTIFY ||
action == FPI_DEVICE_ACTION_CAPTURE)
if (action == FP_DEVICE_ACTION_ENROLL ||
action == FP_DEVICE_ACTION_VERIFY ||
action == FP_DEVICE_ACTION_IDENTIFY ||
action == FP_DEVICE_ACTION_CAPTURE)
{
priv->cancelling = TRUE;
fpi_image_device_deactivate (self);
@@ -143,14 +143,14 @@ fp_image_device_start_capture_action (FpDevice *device)
{
FpImageDevice *self = FP_IMAGE_DEVICE (device);
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
/* There is just one action that we cannot support out
* of the box, which is a capture without first waiting
* for a finger to be on the device.
*/
action = fpi_device_get_current_action (device);
if (action == FPI_DEVICE_ACTION_CAPTURE)
if (action == FP_DEVICE_ACTION_CAPTURE)
{
gboolean wait_for_finger;
@@ -162,12 +162,12 @@ fp_image_device_start_capture_action (FpDevice *device)
return;
}
}
else if (action == FPI_DEVICE_ACTION_ENROLL)
else if (action == FP_DEVICE_ACTION_ENROLL)
{
FpPrint *enroll_print = NULL;
fpi_device_get_enroll_data (device, &enroll_print);
fpi_print_set_type (enroll_print, FPI_PRINT_NBIS);
fpi_print_set_type (enroll_print, FP_PRINT_NBIS);
}
priv->enroll_stage = 0;
@@ -178,14 +178,14 @@ fp_image_device_start_capture_action (FpDevice *device)
* error (which will usually say that the user should remove the
* finger).
*/
if (priv->state != FPI_IMAGE_DEVICE_STATE_INACTIVE || priv->active)
if (priv->state != FP_IMAGE_DEVICE_STATE_INACTIVE || priv->active)
{
g_debug ("Got a new request while the device was still active");
g_assert (priv->pending_activation_timeout_id == 0);
priv->pending_activation_timeout_id =
g_timeout_add (100, pending_activation_timeout, device);
if (priv->state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
if (priv->state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
priv->pending_activation_timeout_waiting_finger_off = TRUE;
else
priv->pending_activation_timeout_waiting_finger_off = FALSE;
@@ -245,23 +245,6 @@ fp_image_device_get_property (GObject *object,
}
}
static void
fp_image_device_constructed (GObject *obj)
{
FpImageDevice *self = FP_IMAGE_DEVICE (obj);
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (self);
/* Set default values. */
fpi_device_set_nr_enroll_stages (FP_DEVICE (self), IMG_ENROLL_STAGES);
priv->bz3_threshold = BOZORTH3_DEFAULT_THRESHOLD;
if (cls->bz3_threshold > 0)
priv->bz3_threshold = cls->bz3_threshold;
G_OBJECT_CLASS (fp_image_device_parent_class)->constructed (obj);
}
static void
fp_image_device_class_init (FpImageDeviceClass *klass)
{
@@ -270,7 +253,6 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
object_class->finalize = fp_image_device_finalize;
object_class->get_property = fp_image_device_get_property;
object_class->constructed = fp_image_device_constructed;
fp_device_class->open = fp_image_device_open;
fp_device_class->close = fp_image_device_close;
@@ -285,37 +267,21 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
klass->activate = fp_image_device_default_activate;
klass->deactivate = fp_image_device_default_deactivate;
/**
* FpImageDevice::fpi-image-device-state: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_STATE] =
g_param_spec_enum ("fpi-image-device-state",
g_param_spec_enum ("fp-image-device-state",
"Image Device State",
"Private: The state of the image device",
FPI_TYPE_IMAGE_DEVICE_STATE,
FPI_IMAGE_DEVICE_STATE_INACTIVE,
FP_TYPE_IMAGE_DEVICE_STATE,
FP_IMAGE_DEVICE_STATE_INACTIVE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
/**
* FpImageDevice::fpi-image-device-state-changed: (skip)
* @image_device: A #FpImageDevice
* @new_state: The new state of the device
*
* This signal is only for internal purposes.
*
* Stability: private
*/
signals[FPI_STATE_CHANGED] =
g_signal_new ("fpi-image-device-state-changed",
g_signal_new ("fp-image-device-state-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (FpImageDeviceClass, change_state),
NULL, NULL, NULL,
G_TYPE_NONE, 1, FPI_TYPE_IMAGE_DEVICE_STATE);
G_TYPE_NONE, 1, FP_TYPE_IMAGE_DEVICE_STATE);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -323,4 +289,13 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
static void
fp_image_device_init (FpImageDevice *self)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (self);
/* Set default values. */
fpi_device_set_nr_enroll_stages (FP_DEVICE (self), IMG_ENROLL_STAGES);
priv->bz3_threshold = BOZORTH3_DEFAULT_THRESHOLD;
if (cls->bz3_threshold > 0)
priv->bz3_threshold = cls->bz3_threshold;
}

View File

@@ -184,8 +184,10 @@ fp_image_detect_minutiae_cb (GObject *source_object,
GTask *task = G_TASK (res);
FpImage *image;
DetectMinutiaeData *data = g_task_get_task_data (task);
GCancellable *cancellable;
if (!g_task_had_error (task))
cancellable = g_task_get_cancellable (task);
if (!cancellable || !g_cancellable_is_cancelled (cancellable))
{
gint i;
image = FP_IMAGE (source_object);
@@ -281,7 +283,6 @@ 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)
@@ -295,15 +296,12 @@ 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, lfsparms);
data->ppmm, &g_lfsparms_V2);
g_timer_stop (timer);
fp_dbg ("Minutiae scan completed in %f secs", g_timer_elapsed (timer, NULL));
@@ -318,14 +316,6 @@ fp_image_detect_minutiae_thread_func (GTask *task,
return;
}
if (!data->minutiae || data->minutiae->num == 0)
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
"No minutiae found");
g_object_unref (task);
return;
}
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}

View File

@@ -27,7 +27,7 @@ struct _FpPrint
{
GInitiallyUnowned parent_instance;
FpiPrintType type;
FpPrintType type;
gchar *driver;
gchar *device_id;

View File

@@ -21,7 +21,6 @@
#define FP_COMPONENT "print"
#include "fp-print-private.h"
#include "fpi-compat.h"
#include "fpi-log.h"
/**
@@ -51,7 +50,7 @@ enum {
PROP_IMAGE,
/* The following is metadata that is stored by default for each print.
* Drivers may make use of these during enrollment (e.g. to additionally store
* Drivers may make use of these during enrollment (e.g. to additionaly store
* the metadata on the device). */
PROP_FINGER,
PROP_USERNAME,
@@ -269,30 +268,16 @@ fp_print_class_init (FpPrintClass *klass)
G_TYPE_DATE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
/**
* FpPrint::fpi-type: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_TYPE] =
g_param_spec_enum ("fpi-type",
g_param_spec_enum ("fp-type",
"Type",
"Private: The type of the print data",
FPI_TYPE_PRINT_TYPE,
FPI_PRINT_RAW,
FP_TYPE_PRINT_TYPE,
FP_PRINT_RAW,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* FpPrint::fpi-data: (skip)
*
* This property is only for internal purposes.
*
* Stability: private
*/
properties[PROP_FPI_DATA] =
g_param_spec_variant ("fpi-data",
g_param_spec_variant ("fp-data",
"Raw Data",
"The raw data for internal use only",
G_VARIANT_TYPE_ANY,
@@ -570,8 +555,8 @@ fp_print_equal (FpPrint *self, FpPrint *other)
{
g_return_val_if_fail (FP_IS_PRINT (self), FALSE);
g_return_val_if_fail (FP_IS_PRINT (other), FALSE);
g_return_val_if_fail (self->type != FPI_PRINT_UNDEFINED, FALSE);
g_return_val_if_fail (other->type != FPI_PRINT_UNDEFINED, FALSE);
g_return_val_if_fail (self->type != FP_PRINT_UNDEFINED, FALSE);
g_return_val_if_fail (other->type != FP_PRINT_UNDEFINED, FALSE);
if (self->type != other->type)
return FALSE;
@@ -582,13 +567,13 @@ fp_print_equal (FpPrint *self, FpPrint *other)
if (g_strcmp0 (self->device_id, other->device_id))
return FALSE;
if (self->type == FPI_PRINT_RAW)
if (self->type == FP_PRINT_RAW)
{
return g_variant_equal (self->data, other->data);
}
else if (self->type == FPI_PRINT_NBIS)
else if (self->type == FP_PRINT_NBIS)
{
guint i;
gint i;
if (self->prints->len != other->prints->len)
return FALSE;
@@ -610,7 +595,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
}
}
#define FPI_PRINT_VARIANT_TYPE G_VARIANT_TYPE ("(issbymsmsia{sv}v)")
#define FP_PRINT_VARIANT_TYPE G_VARIANT_TYPE ("(issbymsmsia{sv}v)")
G_STATIC_ASSERT (sizeof (((struct xyt_struct *) NULL)->xcol[0]) == 4);
@@ -633,7 +618,7 @@ fp_print_serialize (FpPrint *print,
GError **error)
{
g_autoptr(GVariant) result = NULL;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (FPI_PRINT_VARIANT_TYPE);
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (FP_PRINT_VARIANT_TYPE);
gsize len;
g_assert (data);
@@ -658,10 +643,10 @@ fp_print_serialize (FpPrint *print,
g_variant_builder_close (&builder);
/* Insert NBIS print data for type NBIS, otherwise the GVariant directly */
if (print->type == FPI_PRINT_NBIS)
if (print->type == FP_PRINT_NBIS)
{
GVariantBuilder nested = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(a(aiaiai))"));
guint i;
gint i;
g_variant_builder_open (&nested, G_VARIANT_TYPE ("a(aiaiai)"));
for (i = 0; i < print->prints->len; i++)
@@ -753,14 +738,14 @@ fp_print_deserialize (const guchar *data,
g_autoptr(GVariant) raw_value = NULL;
g_autoptr(GVariant) value = NULL;
g_autoptr(GVariant) print_data = NULL;
g_autoptr(GDate) date = NULL;
guchar *aligned_data = NULL;
GDate *date = NULL;
guint8 finger_int8;
FpFinger finger;
g_autofree gchar *username = NULL;
g_autofree gchar *description = NULL;
gint julian_date;
FpiPrintType type;
FpPrintType type;
const gchar *driver;
const gchar *device_id;
gboolean device_stored;
@@ -781,7 +766,7 @@ fp_print_deserialize (const guchar *data,
* longer. */
aligned_data = g_malloc (length - 3);
memcpy (aligned_data, data + 3, length - 3);
raw_value = g_variant_new_from_data (FPI_PRINT_VARIANT_TYPE,
raw_value = g_variant_new_from_data (FP_PRINT_VARIANT_TYPE,
aligned_data, length - 3,
FALSE, g_free, aligned_data);
@@ -809,20 +794,20 @@ fp_print_deserialize (const guchar *data,
finger = finger_int8;
/* Assume data is valid at this point if the values are somewhat sane. */
if (type == FPI_PRINT_NBIS)
if (type == FP_PRINT_NBIS)
{
g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
guint i;
gint i;
result = g_object_new (FP_TYPE_PRINT,
"driver", driver,
"device-id", device_id,
"device-stored", device_stored,
NULL);
fpi_print_set_type (result, FPI_PRINT_NBIS);
fpi_print_set_type (result, FP_PRINT_NBIS);
for (i = 0; i < g_variant_n_children (prints); i++)
{
g_autofree struct xyt_struct *xyt = NULL;
g_autofree struct xyt_struct *xyt = g_new0 (struct xyt_struct, 1);
const gint32 *xcol, *ycol, *thetacol;
gsize xlen, ylen, thetalen;
g_autoptr(GVariant) xyt_data = NULL;
@@ -848,7 +833,6 @@ 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);
@@ -857,16 +841,16 @@ fp_print_deserialize (const guchar *data,
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
}
}
else if (type == FPI_PRINT_RAW)
else if (type == FP_PRINT_RAW)
{
g_autoptr(GVariant) fp_data = g_variant_get_child_value (print_data, 0);
result = g_object_new (FP_TYPE_PRINT,
"fpi-type", type,
"fp-type", type,
"driver", driver,
"device-id", device_id,
"device-stored", device_stored,
"fpi-data", fp_data,
"fp-data", fp_data,
NULL);
}
else
@@ -883,6 +867,8 @@ fp_print_deserialize (const guchar *data,
"enroll_date", date,
NULL);
g_date_free (date);
return g_steal_pointer (&result);
invalid_format:

View File

@@ -28,9 +28,6 @@ G_BEGIN_DECLS
#define FP_TYPE_PRINT (fp_print_get_type ())
G_DECLARE_FINAL_TYPE (FpPrint, fp_print, FP, PRINT, GInitiallyUnowned)
#define FP_FINGER_IS_VALID(finger) \
((finger) >= FP_FINGER_FIRST && (finger) <= FP_FINGER_LAST)
#include "fp-device.h"
/**
@@ -46,8 +43,6 @@ G_DECLARE_FINAL_TYPE (FpPrint, fp_print, FP, PRINT, GInitiallyUnowned)
* @FP_FINGER_RIGHT_MIDDLE: Right middle finger
* @FP_FINGER_RIGHT_RING: Right ring finger
* @FP_FINGER_RIGHT_LITTLE: Right little finger
* @FP_FINGER_FIRST: The first finger in the fp-print order
* @FP_FINGER_LAST: The last finger in the fp-print order
*/
typedef enum {
FP_FINGER_UNKNOWN = 0,
@@ -61,9 +56,6 @@ typedef enum {
FP_FINGER_RIGHT_MIDDLE,
FP_FINGER_RIGHT_RING,
FP_FINGER_RIGHT_LITTLE,
FP_FINGER_FIRST = FP_FINGER_LEFT_THUMB,
FP_FINGER_LAST = FP_FINGER_RIGHT_LITTLE,
} FpFinger;
FpPrint *fp_print_new (FpDevice *device);

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
* Internal/private definitions for libfprint
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,22 +19,7 @@
#pragma once
#include <glib-object.h>
#if !GLIB_CHECK_VERSION (2, 57, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GTypeClass, g_type_class_unref);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GEnumClass, g_type_class_unref);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GParamSpec, g_param_spec_unref);
#else
/* Re-define G_SOURCE_FUNC as we are technically not allowed to use it with
* the version we depend on currently. */
#undef G_SOURCE_FUNC
#endif
#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void))(f))
#if !GLIB_CHECK_VERSION (2, 63, 3)
typedef struct _FpDeviceClass FpDeviceClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpDeviceClass, g_type_class_unref);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GDate, g_date_free);
#endif
#include "fpi-log.h"
#include "fpi-image.h"
#include "fpi-image-device.h"
#include "fpi-minutiae.h"

View File

@@ -21,8 +21,7 @@
#define FP_COMPONENT "assembling"
#include "fpi-log.h"
#include "fpi-image.h"
#include "fp_internal.h"
#include <string.h>
@@ -52,9 +51,6 @@ calc_error (struct fpi_frame_asmbl_ctx *ctx,
width = ctx->frame_width - (dx > 0 ? dx : -dx);
height = ctx->frame_height - dy;
if (height == 0 || width == 0)
return INT_MAX;
y1 = 0;
y2 = dy;
i = 0;
@@ -89,6 +85,9 @@ calc_error (struct fpi_frame_asmbl_ctx *ctx,
err *= (ctx->frame_height * ctx->frame_width);
err /= (height * width);
if (err == 0)
return INT_MAX;
return err;
}
@@ -99,8 +98,6 @@ static void
find_overlap (struct fpi_frame_asmbl_ctx *ctx,
struct fpi_frame *first_frame,
struct fpi_frame *second_frame,
int *dx_out,
int *dy_out,
unsigned int *min_error)
{
int dx, dy;
@@ -122,8 +119,8 @@ find_overlap (struct fpi_frame_asmbl_ctx *ctx,
if (err < *min_error)
{
*min_error = err;
*dx_out = -dx;
*dy_out = dy;
second_frame->delta_x = -dx;
second_frame->delta_y = dy;
}
}
}
@@ -135,7 +132,7 @@ do_movement_estimation (struct fpi_frame_asmbl_ctx *ctx,
{
GSList *l;
GTimer *timer;
guint num_frames = 1;
guint num_frames = 0;
struct fpi_frame *prev_stripe;
unsigned int min_error;
/* Max error is width * height * 255, for AES2501 which has the largest
@@ -145,27 +142,20 @@ do_movement_estimation (struct fpi_frame_asmbl_ctx *ctx,
unsigned long long total_error = 0;
timer = g_timer_new ();
/* Skip the first frame */
prev_stripe = stripes->data;
for (l = stripes->next; l != NULL; l = l->next, num_frames++)
for (l = stripes; l != NULL; l = l->next, num_frames++)
{
struct fpi_frame *cur_stripe = l->data;
if (reverse)
{
find_overlap (ctx, prev_stripe, cur_stripe,
&cur_stripe->delta_x, &cur_stripe->delta_y,
&min_error);
find_overlap (ctx, prev_stripe, cur_stripe, &min_error);
cur_stripe->delta_y = -cur_stripe->delta_y;
cur_stripe->delta_x = -cur_stripe->delta_x;
}
else
{
find_overlap (ctx, cur_stripe, prev_stripe,
&cur_stripe->delta_x, &cur_stripe->delta_y,
&min_error);
find_overlap (ctx, cur_stripe, prev_stripe, &min_error);
}
total_error += min_error;
@@ -337,10 +327,19 @@ fpi_assemble_frames (struct fpi_frame_asmbl_ctx *ctx,
{
fpi_frame = l->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;
}
}
return img;

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __FPI_ASSEMBLING_H__
#define __FPI_ASSEMBLING_H__
#include <fprint.h>
@@ -115,3 +116,5 @@ struct fpi_line_asmbl_ctx
FpImage *fpi_assemble_lines (struct fpi_line_asmbl_ctx *ctx,
GSList *lines,
size_t num_lines);
#endif

View File

@@ -19,7 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
#pragma once
#ifndef __FPI_BYTE_READER_H__
#define __FPI_BYTE_READER_H__
#include <glib.h>
#include "fpi-byte-utils.h"
@@ -675,3 +676,5 @@ fpi_byte_reader_skip_inline (FpiByteReader * reader, guint nbytes)
#endif /* FPI_BYTE_READER_DISABLE_INLINES */
G_END_DECLS
#endif /* __FPI_BYTE_READER_H__ */

View File

@@ -21,7 +21,9 @@
* Boston, MA 02110-1301, USA.
*/
#pragma once
#ifndef __FP_UTILS_H__
#define __FP_UTILS_H__
#include <glib.h>
@@ -483,3 +485,4 @@ FP_WRITE_DOUBLE_BE(guint8 *data, gdouble num)
G_END_DECLS
#endif /* __GTK_DOC_IGNORE__ */
#endif /* __FP_UTILS_H__ */

View File

@@ -18,7 +18,8 @@
* Boston, MA 02110-1301, USA.
*/
#pragma once
#ifndef __FPI_BYTE_WRITER_H__
#define __FPI_BYTE_WRITER_H__
#include "fpi-byte-reader.h"
#include <string.h>
@@ -408,3 +409,5 @@ fpi_byte_writer_fill_inline (FpiByteWriter * writer, guint8 value, guint size)
#endif
G_END_DECLS
#endif /* __FPI_BYTE_WRITER_H__ */

View File

@@ -20,7 +20,6 @@
#include <gusb.h>
#include "fp-context.h"
#include "fpi-compat.h"
/**
* fpi_get_driver_types:

View File

@@ -28,7 +28,7 @@
* @title: Internal FpDevice
* @short_description: Internal device routines
*
* The methods that are available for drivers to manipulate a device. See
* The methods that are availabe 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.
@@ -100,7 +100,7 @@ fpi_device_error_new (FpDeviceError error)
switch (error)
{
case FP_DEVICE_ERROR_GENERAL:
msg = "An unspecified error occurred!";
msg = "An unspecified error occured!";
break;
case FP_DEVICE_ERROR_NOT_SUPPORTED:
@@ -138,7 +138,7 @@ fpi_device_error_new (FpDeviceError error)
default:
g_warning ("Unsupported error, returning general error instead!");
error = FP_DEVICE_ERROR_GENERAL;
msg = "An unspecified error occurred!";
msg = "An unspecified error occured!";
}
return g_error_new_literal (FP_DEVICE_ERROR, error, msg);
@@ -350,21 +350,21 @@ fpi_device_get_virtual_env (FpDevice *device)
* fpi_device_get_current_action:
* @device: The #FpDevice
*
* Get the currently ongoing action or %FPI_DEVICE_ACTION_NONE if there
* Get the currently ongoing action or %FP_DEVICE_ACTION_NONE if there
* is no operation at this time.
*
* This is useful for drivers that might share code paths between different
* actions (e.g. verify and identify) and want to find out again later which
* action was started in the beginning.
*
* Returns: The ongoing #FpiDeviceAction
* Returns: The ongoing #FpDeviceAction
*/
FpiDeviceAction
FpDeviceAction
fpi_device_get_current_action (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_val_if_fail (FP_IS_DEVICE (device), FPI_DEVICE_ACTION_NONE);
g_return_val_if_fail (FP_IS_DEVICE (device), FP_DEVICE_ACTION_NONE);
return priv->current_action;
}
@@ -387,7 +387,7 @@ fpi_device_action_is_cancelled (FpDevice *device)
GCancellable *cancellable;
g_return_val_if_fail (FP_IS_DEVICE (device), TRUE);
g_return_val_if_fail (priv->current_action != FPI_DEVICE_ACTION_NONE, TRUE);
g_return_val_if_fail (priv->current_action != FP_DEVICE_ACTION_NONE, TRUE);
cancellable = g_task_get_cancellable (priv->current_task);
@@ -420,23 +420,6 @@ enroll_data_free (FpEnrollData *data)
g_free (data);
}
void
match_data_free (FpMatchData *data)
{
g_clear_object (&data->print);
g_clear_object (&data->match);
g_clear_error (&data->error);
if (data->match_destroy)
data->match_destroy (data->match_data);
data->match_data = NULL;
g_clear_object (&data->enrolled_print);
g_clear_pointer (&data->gallery, g_ptr_array_unref);
g_free (data);
}
/**
* fpi_device_get_enroll_data:
* @device: The #FpDevice
@@ -452,7 +435,7 @@ fpi_device_get_enroll_data (FpDevice *device,
FpEnrollData *data;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_ENROLL);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_ENROLL);
data = g_task_get_task_data (priv->current_task);
g_assert (data);
@@ -475,7 +458,7 @@ fpi_device_get_capture_data (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_CAPTURE);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_CAPTURE);
if (wait_for_finger)
*wait_for_finger = priv->wait_for_finger;
@@ -493,16 +476,12 @@ fpi_device_get_verify_data (FpDevice *device,
FpPrint **print)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
data = g_task_get_task_data (priv->current_task);
g_assert (data);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_VERIFY);
if (print)
*print = data->enrolled_print;
*print = g_task_get_task_data (priv->current_task);
}
/**
@@ -517,16 +496,12 @@ fpi_device_get_identify_data (FpDevice *device,
GPtrArray **prints)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
data = g_task_get_task_data (priv->current_task);
g_assert (data);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_IDENTIFY);
if (prints)
*prints = data->gallery;
*prints = g_task_get_task_data (priv->current_task);
}
/**
@@ -543,7 +518,7 @@ fpi_device_get_delete_data (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_DELETE);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_DELETE);
if (print)
*print = g_task_get_task_data (priv->current_task);
@@ -567,7 +542,7 @@ fpi_device_get_cancellable (FpDevice *device)
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_val_if_fail (FP_IS_DEVICE (device), NULL);
g_return_val_if_fail (priv->current_action != FPI_DEVICE_ACTION_NONE, NULL);
g_return_val_if_fail (priv->current_action != FP_DEVICE_ACTION_NONE, NULL);
return g_task_get_cancellable (priv->current_task);
}
@@ -589,7 +564,7 @@ fpi_device_action_error (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action != FPI_DEVICE_ACTION_NONE);
g_return_if_fail (priv->current_action != FP_DEVICE_ACTION_NONE);
if (error != NULL)
{
@@ -604,44 +579,44 @@ fpi_device_action_error (FpDevice *device,
switch (priv->current_action)
{
case FPI_DEVICE_ACTION_PROBE:
case FP_DEVICE_ACTION_PROBE:
fpi_device_probe_complete (device, NULL, NULL, error);
break;
case FPI_DEVICE_ACTION_OPEN:
case FP_DEVICE_ACTION_OPEN:
fpi_device_open_complete (device, error);
break;
case FPI_DEVICE_ACTION_CLOSE:
case FP_DEVICE_ACTION_CLOSE:
fpi_device_close_complete (device, error);
break;
case FPI_DEVICE_ACTION_ENROLL:
case FP_DEVICE_ACTION_ENROLL:
fpi_device_enroll_complete (device, NULL, error);
break;
case FPI_DEVICE_ACTION_VERIFY:
fpi_device_verify_complete (device, error);
case FP_DEVICE_ACTION_VERIFY:
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
break;
case FPI_DEVICE_ACTION_IDENTIFY:
fpi_device_identify_complete (device, error);
case FP_DEVICE_ACTION_IDENTIFY:
fpi_device_identify_complete (device, NULL, NULL, error);
break;
case FPI_DEVICE_ACTION_CAPTURE:
case FP_DEVICE_ACTION_CAPTURE:
fpi_device_capture_complete (device, NULL, error);
break;
case FPI_DEVICE_ACTION_DELETE:
case FP_DEVICE_ACTION_DELETE:
fpi_device_delete_complete (device, error);
break;
case FPI_DEVICE_ACTION_LIST:
case FP_DEVICE_ACTION_LIST:
fpi_device_list_complete (device, NULL, error);
break;
default:
case FPI_DEVICE_ACTION_NONE:
case FP_DEVICE_ACTION_NONE:
g_return_if_reached ();
break;
}
@@ -688,7 +663,7 @@ fp_device_task_return_in_idle_cb (gpointer user_data)
g_debug ("Completing action %d in idle!", priv->current_action);
task = g_steal_pointer (&priv->current_task);
priv->current_action = FPI_DEVICE_ACTION_NONE;
priv->current_action = FP_DEVICE_ACTION_NONE;
priv->current_task_idle_return_source = NULL;
switch (data->type)
@@ -771,7 +746,7 @@ fpi_device_probe_complete (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_PROBE);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_PROBE);
g_debug ("Device reported probe completion");
@@ -813,7 +788,7 @@ fpi_device_open_complete (FpDevice *device, GError *error)
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_OPEN);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_OPEN);
g_debug ("Device reported open completion");
@@ -846,11 +821,13 @@ fpi_device_close_complete (FpDevice *device, GError *error)
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_CLOSE);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_CLOSE);
g_debug ("Device reported close completion");
clear_device_cancel_action (device);
priv->is_open = FALSE;
g_object_notify (G_OBJECT (device), "open");
switch (priv->type)
{
@@ -875,16 +852,10 @@ fpi_device_close_complete (FpDevice *device, GError *error)
}
if (!error)
{
priv->is_open = FALSE;
g_object_notify (G_OBJECT (device), "open");
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
GUINT_TO_POINTER (TRUE));
}
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
GUINT_TO_POINTER (TRUE));
else
{
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
}
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
}
/**
@@ -902,7 +873,7 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_ENROLL);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_ENROLL);
g_debug ("Device reported enroll completion");
@@ -912,20 +883,6 @@ 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
@@ -950,68 +907,64 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
/**
* fpi_device_verify_complete:
* @device: The #FpDevice
* @result: The #FpiMatchResult of the operation
* @print: The scanned #FpPrint
* @error: A #GError if result is %FPI_MATCH_ERROR
*
* Finish an ongoing verify operation. The returned print should be
* representing the new scan and not the one passed for verification.
*
* Note that @error should only be set for actual errors. In the case
* of retry errors, report these using fpi_device_verify_report()
* and then call this function without any error argument.
*/
void
fpi_device_verify_complete (FpDevice *device,
GError *error)
fpi_device_verify_complete (FpDevice *device,
FpiMatchResult result,
FpPrint *print,
GError *error)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_VERIFY);
g_debug ("Device reported verify completion");
data = g_task_get_task_data (priv->current_task);
clear_device_cancel_action (device);
g_object_set_data_full (G_OBJECT (priv->current_task),
"print",
print,
g_object_unref);
if (!error)
{
if (!data->result_reported)
if (result != FPI_MATCH_ERROR)
{
g_warning ("Driver reported successful verify complete but did not report the result earlier. Reporting error instead");
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR,
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
}
else if (data->error)
{
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, g_steal_pointer (&data->error));
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT,
GINT_TO_POINTER (result));
}
else
{
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT,
GINT_TO_POINTER (data->match != NULL ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL));
g_warning ("Driver did not provide an error for a failed verify operation!");
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Driver failed to provide an error!");
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
}
}
else
{
/* Replace a retry error with a general error, this is a driver bug. */
if (error->domain == FP_DEVICE_RETRY)
{
g_warning ("Driver reported a retry error to fpi_device_verify_complete. "
"This is not permissible and needs to be reported using "
"fpi_device_verify_report, reporting general verification "
"failure instead.");
g_clear_error (&error);
error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
}
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
if (result != FPI_MATCH_ERROR)
{
g_warning ("Driver passed an error but also provided a match result, returning error!");
g_object_unref (print);
}
}
}
/**
* fpi_device_identify_complete:
* @device: The #FpDevice
* @match: The matching #FpPrint from the passed gallery, or %NULL if none matched
* @print: The scanned #FpPrint, may be %NULL
* @error: The #GError or %NULL on success
*
* Finish an ongoing identify operation. The match that was identified is
@@ -1020,50 +973,40 @@ fpi_device_verify_complete (FpDevice *device,
*/
void
fpi_device_identify_complete (FpDevice *device,
FpPrint *match,
FpPrint *print,
GError *error)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_IDENTIFY);
g_debug ("Device reported identify completion");
data = g_task_get_task_data (priv->current_task);
clear_device_cancel_action (device);
g_object_set_data_full (G_OBJECT (priv->current_task),
"print",
print,
g_object_unref);
g_object_set_data_full (G_OBJECT (priv->current_task),
"match",
match,
g_object_unref);
if (!error)
{
if (!data->result_reported)
{
g_warning ("Driver reported successful identify complete but did not report the result earlier. Reporting error instead");
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR,
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
}
else if (data->error)
{
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, g_steal_pointer (&data->error));
}
else
{
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT, GINT_TO_POINTER (TRUE));
}
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
GUINT_TO_POINTER (TRUE));
}
else
{
/* Replace a retry error with a general error, this is a driver bug. */
if (error->domain == FP_DEVICE_RETRY)
{
g_warning ("Driver reported a retry error to fpi_device_identify_complete. "
"This is not permissible and needs to be reported using "
"fpi_device_identify_report, reporting general identification "
"failure instead.");
g_clear_error (&error);
error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
}
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
if (match)
{
g_warning ("Driver passed an error but also provided a match result, returning error!");
g_clear_object (&match);
}
}
}
@@ -1084,7 +1027,7 @@ fpi_device_capture_complete (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_CAPTURE);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_CAPTURE);
g_debug ("Device reported capture completion");
@@ -1129,7 +1072,7 @@ fpi_device_delete_complete (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_DELETE);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_DELETE);
g_debug ("Device reported deletion completion");
@@ -1163,7 +1106,7 @@ fpi_device_list_complete (FpDevice *device,
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_LIST);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_LIST);
g_debug ("Device reported listing completion");
@@ -1191,7 +1134,7 @@ fpi_device_list_complete (FpDevice *device,
* fpi_device_enroll_progress:
* @device: The #FpDevice
* @completed_stages: The number of stages that are completed at this point
* @print: (transfer floating): The #FpPrint for the newly completed stage or %NULL on failure
* @print: (transfer full): The #FpPrint for the newly completed stage or %NULL on failure
* @error: (transfer full): The #GError or %NULL on success
*
* Notify about the progress of the enroll operation. This is important for UI interaction.
@@ -1207,14 +1150,11 @@ fpi_device_enroll_progress (FpDevice *device,
FpEnrollData *data;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_ENROLL);
g_return_if_fail (priv->current_action == FP_DEVICE_ACTION_ENROLL);
g_return_if_fail (error == NULL || error->domain == FP_DEVICE_RETRY);
g_debug ("Device reported enroll progress, reported %i of %i have been completed", completed_stages, priv->nr_enroll_stages);
if (print)
g_object_ref_sink (print);
if (error && print)
{
g_warning ("Driver passed an error and also provided a print, returning error!");
@@ -1235,151 +1175,3 @@ fpi_device_enroll_progress (FpDevice *device,
g_clear_error (&error);
g_clear_object (&print);
}
/**
* fpi_device_verify_report:
* @device: The #FpDevice
* @result: The #FpiMatchResult of the operation
* @print: (transfer floating) The scanned #FpPrint
* @error: A #GError if result is %FPI_MATCH_ERROR
*
* Report the result of a verify operation. Note that the passed @error must be
* a retry error with the %FP_DEVICE_RETRY domain. For all other error cases,
* the error should passed to fpi_device_verify_complete().
*/
void
fpi_device_verify_report (FpDevice *device,
FpiMatchResult result,
FpPrint *print,
GError *error)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data = g_task_get_task_data (priv->current_task);
gboolean call_cb = TRUE;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
g_return_if_fail (data->result_reported == FALSE);
data->result_reported = TRUE;
g_debug ("Device reported verify result");
if (print)
print = g_object_ref_sink (print);
if (error || result == FPI_MATCH_ERROR)
{
if (result != FPI_MATCH_ERROR)
g_warning ("Driver reported an error code without setting match result to error!");
if (error == NULL)
{
g_warning ("Driver reported an error without specifying a retry code, assuming general retry error!");
error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
}
if (print)
{
g_warning ("Driver reported a print together with an error!");
g_clear_object (&print);
}
data->error = error;
if (error->domain != FP_DEVICE_RETRY)
{
g_warning ("Driver reported a verify error that was not in the retry domain, delaying report!");
call_cb = FALSE;
}
}
else
{
if (result == FPI_MATCH_SUCCESS)
{
fpi_device_get_verify_data (device, &data->match);
g_object_ref (data->match);
}
data->print = g_steal_pointer (&print);
}
if (call_cb && data->match_cb)
data->match_cb (device, data->match, data->print, data->match_data, data->error);
}
/**
* fpi_device_identify_report:
* @device: The #FpDevice
* @match: (transfer none): The #FpPrint from the gallery that matched
* @print: (transfer floating): The scanned #FpPrint
* @error: A #GError if result is %FPI_MATCH_ERROR
*
* Report the result of a identify operation. Note that the passed @error must be
* a retry error with the %FP_DEVICE_RETRY domain. For all other error cases,
* the error should passed to fpi_device_identify_complete().
*/
void
fpi_device_identify_report (FpDevice *device,
FpPrint *match,
FpPrint *print,
GError *error)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpMatchData *data = g_task_get_task_data (priv->current_task);
gboolean call_cb = TRUE;
g_return_if_fail (FP_IS_DEVICE (device));
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
g_return_if_fail (data->result_reported == FALSE);
data->result_reported = TRUE;
if (match)
g_object_ref (match);
if (print)
print = g_object_ref_sink (print);
if (match && !g_ptr_array_find (data->gallery, match, NULL))
{
g_warning ("Driver reported a match to a print that was not in the gallery, ignoring match.");
g_clear_object (&match);
}
g_debug ("Device reported identify result");
if (error)
{
if (match != NULL)
{
g_warning ("Driver reported an error code but also provided a match!");
g_clear_object (&match);
}
if (print)
{
g_warning ("Driver reported a print together with an error!");
g_clear_object (&print);
}
data->error = error;
if (error->domain != FP_DEVICE_RETRY)
{
g_warning ("Driver reported a verify error that was not in the retry domain, delaying report!");
call_cb = FALSE;
}
}
else
{
if (match)
data->match = g_steal_pointer (&match);
if (print)
data->print = g_steal_pointer (&print);
}
if (call_cb && data->match_cb)
data->match_cb (device, data->match, data->print, data->match_data, data->error);
}

View File

@@ -65,10 +65,10 @@ struct _FpIdEntry
* @probe: Called immediately for all devices. Most drivers will not need to
* implement this. Drivers should setup the device identifier from the probe
* callback which will be used to verify the compatibility of stored
* #FpPrint's. It is permissible to temporarily open the USB device if this
* #FpPrint's. It is permissable to temporarily open the USB device if this
* is required for the operation. If an error is returned, then the device
* will be destroyed again immediately and never reported to the API user.
* @open: Open the device for further operations. Any of the normal actions are
* @open: Open the device for futher operations. Any of the normal actions are
* guaranteed to only happen when the device is open (this includes delete).
* @close: Close the device again
* @enroll: Start an enroll operation
@@ -142,39 +142,39 @@ typedef void (*FpTimeoutFunc) (FpDevice *device,
gpointer user_data);
/**
* FpiDeviceAction:
* @FPI_DEVICE_ACTION_NONE: No action is active.
* @FPI_DEVICE_ACTION_PROBE: Probe device for support and information.
* @FPI_DEVICE_ACTION_OPEN: Device is currently being opened.
* @FPI_DEVICE_ACTION_CLOSE: Device is currently being closed.
* @FPI_DEVICE_ACTION_ENROLL: Device is currently enrolling.
* @FPI_DEVICE_ACTION_VERIFY: Device is currently verifying.
* @FPI_DEVICE_ACTION_IDENTIFY: Device is currently identifying.
* @FPI_DEVICE_ACTION_CAPTURE: Device is currently capturing an image.
* @FPI_DEVICE_ACTION_LIST: Device stored prints are being queried.
* @FPI_DEVICE_ACTION_DELETE: Device stored print is being deleted.
* FpDeviceAction:
* @FP_DEVICE_ACTION_NONE: No action is active.
* @FP_DEVICE_ACTION_PROBE: Probe device for support and information.
* @FP_DEVICE_ACTION_OPEN: Device is currently being opened.
* @FP_DEVICE_ACTION_CLOSE: Device is currently being closed.
* @FP_DEVICE_ACTION_ENROLL: Device is currently enrolling.
* @FP_DEVICE_ACTION_VERIFY: Device is currently verifying.
* @FP_DEVICE_ACTION_IDENTIFY: Device is currently identifying.
* @FP_DEVICE_ACTION_CAPTURE: Device is currently capturing an image.
* @FP_DEVICE_ACTION_LIST: Device stored prints are being queried.
* @FP_DEVICE_ACTION_DELETE: Device stored print is being deleted.
*
* Current active action of the device. A driver can retrieve the action.
*/
typedef enum {
FPI_DEVICE_ACTION_NONE = 0,
FPI_DEVICE_ACTION_PROBE,
FPI_DEVICE_ACTION_OPEN,
FPI_DEVICE_ACTION_CLOSE,
FPI_DEVICE_ACTION_ENROLL,
FPI_DEVICE_ACTION_VERIFY,
FPI_DEVICE_ACTION_IDENTIFY,
FPI_DEVICE_ACTION_CAPTURE,
FPI_DEVICE_ACTION_LIST,
FPI_DEVICE_ACTION_DELETE,
} FpiDeviceAction;
FP_DEVICE_ACTION_NONE = 0,
FP_DEVICE_ACTION_PROBE,
FP_DEVICE_ACTION_OPEN,
FP_DEVICE_ACTION_CLOSE,
FP_DEVICE_ACTION_ENROLL,
FP_DEVICE_ACTION_VERIFY,
FP_DEVICE_ACTION_IDENTIFY,
FP_DEVICE_ACTION_CAPTURE,
FP_DEVICE_ACTION_LIST,
FP_DEVICE_ACTION_DELETE,
} FpDeviceAction;
GUsbDevice *fpi_device_get_usb_device (FpDevice *device);
const gchar *fpi_device_get_virtual_env (FpDevice *device);
//const gchar *fpi_device_get_spi_dev (FpDevice *device);
FpiDeviceAction fpi_device_get_current_action (FpDevice *device);
FpDeviceAction fpi_device_get_current_action (FpDevice *device);
gboolean fpi_device_action_is_cancelled (FpDevice *device);
GError * fpi_device_retry_new (FpDeviceRetry error);
@@ -229,9 +229,13 @@ void fpi_device_close_complete (FpDevice *device,
void fpi_device_enroll_complete (FpDevice *device,
FpPrint *print,
GError *error);
void fpi_device_verify_complete (FpDevice *device,
GError *error);
void fpi_device_verify_complete (FpDevice *device,
FpiMatchResult result,
FpPrint *print,
GError *error);
void fpi_device_identify_complete (FpDevice *device,
FpPrint *match,
FpPrint *print,
GError *error);
void fpi_device_capture_complete (FpDevice *device,
FpImage *image,
@@ -246,13 +250,5 @@ void fpi_device_enroll_progress (FpDevice *device,
gint completed_stages,
FpPrint *print,
GError *error);
void fpi_device_verify_report (FpDevice *device,
FpiMatchResult result,
FpPrint *print,
GError *error);
void fpi_device_identify_report (FpDevice *device,
FpPrint *match,
FpPrint *print,
GError *error);
G_END_DECLS

View File

@@ -24,11 +24,12 @@
#include "fp-image-device.h"
/**
* SECTION: fpi-image-device
* @title: Internal FpImageDevice
* @short_description: Internal image device functions
* SECTION: fpi-image
* @title: Internal FpImage
* @short_description: Internal image handling routines
*
* Internal image device functions. See #FpImageDevice for public routines.
* Internal image handling routines. Also see the public <ulink
* url="libfprint-FpImage.html">FpImage routines</ulink>.
*/
/* Manually redefine what G_DEFINE_* macro does */
@@ -53,8 +54,8 @@ fpi_image_device_activate (FpImageDevice *self)
/* We don't have a neutral ACTIVE state, but we always will
* go into WAIT_FINGER_ON afterwards. */
priv->state = FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
priv->state = FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
g_object_notify (G_OBJECT (self), "fp-image-device-state");
/* We might have been waiting for deactivation to finish before
* starting the next operation. */
@@ -78,11 +79,11 @@ fpi_image_device_deactivate (FpImageDevice *self)
fp_dbg ("Already deactivated, ignoring request.");
return;
}
if (!priv->cancelling && priv->state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
if (!priv->cancelling && priv->state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
g_warning ("Deactivating image device while waiting for finger, this should not happen.");
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
priv->state = FP_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fp-image-device-state");
fp_dbg ("Deactivating image device\n");
cls->deactivate (self);
@@ -91,12 +92,12 @@ fpi_image_device_deactivate (FpImageDevice *self)
/* Static helper functions */
static void
fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state)
fp_image_device_change_state (FpImageDevice *self, FpImageDeviceState state)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
/* Cannot change to inactive using this function. */
g_assert (state != FPI_IMAGE_DEVICE_STATE_INACTIVE);
g_assert (state != FP_IMAGE_DEVICE_STATE_INACTIVE);
/* We might have been waiting for the finger to go OFF to start the
* next operation. */
@@ -105,8 +106,8 @@ fp_image_device_change_state (FpImageDevice *self, FpiImageDeviceState state)
fp_dbg ("Image device internal state change from %d to %d\n", priv->state, state);
priv->state = state;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
g_signal_emit_by_name (self, "fpi-image-device-state-changed", priv->state);
g_object_notify (G_OBJECT (self), "fp-image-device-state");
g_signal_emit_by_name (self, "fp-image-device-state-changed", priv->state);
}
static void
@@ -117,7 +118,7 @@ fp_image_device_enroll_maybe_await_finger_on (FpImageDevice *self)
if (priv->enroll_await_on_pending)
{
priv->enroll_await_on_pending = FALSE;
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
fp_image_device_change_state (self, FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
}
else
{
@@ -134,7 +135,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
FpImageDevice *self = FP_IMAGE_DEVICE (user_data);
FpDevice *device = FP_DEVICE (self);
FpImageDevicePrivate *priv;
FpiDeviceAction action;
FpDeviceAction action;
/* Note: We rely on the device to not disappear during an operation. */
@@ -158,7 +159,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
priv = fp_image_device_get_instance_private (FP_IMAGE_DEVICE (device));
action = fpi_device_get_current_action (device);
if (action == FPI_DEVICE_ACTION_CAPTURE)
if (action == FP_DEVICE_ACTION_CAPTURE)
{
fpi_device_capture_complete (device, g_steal_pointer (&image), error);
fpi_image_device_deactivate (self);
@@ -168,21 +169,12 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
if (!error)
{
print = fp_print_new (device);
fpi_print_set_type (print, FPI_PRINT_NBIS);
fpi_print_set_type (print, FP_PRINT_NBIS);
if (!fpi_print_add_from_image (print, image, &error))
{
g_clear_object (&print);
if (error->domain != FP_DEVICE_RETRY)
{
fpi_device_action_error (device, error);
fpi_image_device_deactivate (self);
return;
}
}
g_clear_object (&print);
}
if (action == FPI_DEVICE_ACTION_ENROLL)
if (action == FP_DEVICE_ACTION_ENROLL)
{
FpPrint *enroll_print;
fpi_device_get_enroll_data (device, &enroll_print);
@@ -207,7 +199,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
fp_image_device_enroll_maybe_await_finger_on (FP_IMAGE_DEVICE (device));
}
}
else if (action == FPI_DEVICE_ACTION_VERIFY)
else if (action == FP_DEVICE_ACTION_VERIFY)
{
FpPrint *template;
FpiMatchResult result;
@@ -218,12 +210,10 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
else
result = FPI_MATCH_ERROR;
if (!error || error->domain == FP_DEVICE_RETRY)
fpi_device_verify_report (device, result, g_steal_pointer (&print), g_steal_pointer (&error));
fpi_device_verify_complete (device, error);
fpi_device_verify_complete (device, result, g_steal_pointer (&print), error);
fpi_image_device_deactivate (self);
}
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
else if (action == FP_DEVICE_ACTION_IDENTIFY)
{
gint i;
GPtrArray *templates;
@@ -236,14 +226,12 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
if (fpi_print_bz3_match (template, print, priv->bz3_threshold, &error) == FPI_MATCH_SUCCESS)
{
result = template;
result = g_object_ref (template);
break;
}
}
if (!error || error->domain == FP_DEVICE_RETRY)
fpi_device_identify_report (device, result, g_steal_pointer (&print), g_steal_pointer (&error));
fpi_device_identify_complete (device, error);
fpi_device_identify_complete (device, result, g_steal_pointer (&print), error);
fpi_image_device_deactivate (self);
}
else
@@ -297,9 +285,9 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
{
FpDevice *device = FP_DEVICE (self);
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
if (priv->state == FP_IMAGE_DEVICE_STATE_INACTIVE)
{
/* Do we really want to always ignore such reports? We could
* also track the state in case the user had the finger on
@@ -312,16 +300,16 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
action = fpi_device_get_current_action (device);
g_assert (action != FPI_DEVICE_ACTION_OPEN);
g_assert (action != FPI_DEVICE_ACTION_CLOSE);
g_assert (action != FP_DEVICE_ACTION_OPEN);
g_assert (action != FP_DEVICE_ACTION_CLOSE);
g_debug ("Image device reported finger status: %s", present ? "on" : "off");
if (present && priv->state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
if (present && priv->state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON)
{
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_CAPTURE);
fp_image_device_change_state (self, FP_IMAGE_DEVICE_STATE_CAPTURE);
}
else if (!present && priv->state == FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
else if (!present && priv->state == FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
{
/* We need to deactivate or continue to await finger */
@@ -336,7 +324,7 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
* minutiae detection to prevent deactivation (without cancellation)
* from the AWAIT_FINGER_ON state.
*/
if (action != FPI_DEVICE_ACTION_ENROLL)
if (action != FP_DEVICE_ACTION_ENROLL)
fpi_image_device_deactivate (self);
else
fp_image_device_enroll_maybe_await_finger_on (self);
@@ -361,18 +349,18 @@ void
fpi_image_device_image_captured (FpImageDevice *self, FpImage *image)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
action = fpi_device_get_current_action (FP_DEVICE (self));
g_return_if_fail (image != NULL);
g_return_if_fail (priv->state == FPI_IMAGE_DEVICE_STATE_CAPTURE);
g_return_if_fail (action == FPI_DEVICE_ACTION_ENROLL ||
action == FPI_DEVICE_ACTION_VERIFY ||
action == FPI_DEVICE_ACTION_IDENTIFY ||
action == FPI_DEVICE_ACTION_CAPTURE);
g_return_if_fail (priv->state == FP_IMAGE_DEVICE_STATE_CAPTURE);
g_return_if_fail (action == FP_DEVICE_ACTION_ENROLL ||
action == FP_DEVICE_ACTION_VERIFY ||
action == FP_DEVICE_ACTION_IDENTIFY ||
action == FP_DEVICE_ACTION_CAPTURE);
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
fp_image_device_change_state (self, FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
g_debug ("Image device captured an image");
@@ -397,55 +385,32 @@ void
fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
GError *error;
action = fpi_device_get_current_action (FP_DEVICE (self));
/* We might be waiting for a finger at this point, so just accept
* all but INACTIVE */
g_return_if_fail (priv->state != FPI_IMAGE_DEVICE_STATE_INACTIVE);
g_return_if_fail (action == FPI_DEVICE_ACTION_ENROLL ||
action == FPI_DEVICE_ACTION_VERIFY ||
action == FPI_DEVICE_ACTION_IDENTIFY ||
action == FPI_DEVICE_ACTION_CAPTURE);
g_return_if_fail (priv->state != FP_IMAGE_DEVICE_STATE_INACTIVE);
g_return_if_fail (action == FP_DEVICE_ACTION_ENROLL ||
action == FP_DEVICE_ACTION_VERIFY ||
action == FP_DEVICE_ACTION_IDENTIFY ||
action == FP_DEVICE_ACTION_CAPTURE);
error = fpi_device_retry_new (retry);
if (action == FPI_DEVICE_ACTION_ENROLL)
if (action == FP_DEVICE_ACTION_ENROLL)
{
g_debug ("Reporting retry during enroll");
fpi_device_enroll_progress (FP_DEVICE (self), priv->enroll_stage, NULL, error);
/* Wait for finger removal and re-touch.
* TODO: Do we need to check that the finger is already off? */
priv->enroll_await_on_pending = TRUE;
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
}
else if (action == FPI_DEVICE_ACTION_VERIFY)
{
fpi_device_verify_report (FP_DEVICE (self), FPI_MATCH_ERROR, NULL, error);
priv->cancelling = TRUE;
fpi_image_device_deactivate (self);
priv->cancelling = FALSE;
fpi_device_verify_complete (FP_DEVICE (self), NULL);
}
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
{
fpi_device_identify_report (FP_DEVICE (self), NULL, NULL, error);
priv->cancelling = TRUE;
fpi_image_device_deactivate (self);
priv->cancelling = FALSE;
fpi_device_identify_complete (FP_DEVICE (self), NULL);
}
else
{
/* We abort the operation and let the surrounding code retry in the
* non-enroll case (this is identical to a session error). */
g_debug ("Abort current operation due to retry (non-enroll case)");
priv->cancelling = TRUE;
fpi_image_device_deactivate (self);
priv->cancelling = FALSE;
fpi_device_action_error (FP_DEVICE (self), error);
}
}
@@ -456,9 +421,7 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
* @error: The #GError to report
*
* Report an error while interacting with the device. This effectively
* aborts the current ongoing action. Note that doing so will result in
* the deactivation handler to be called and this function must not be
* used to report an error during deactivation.
* aborts the current ongoing action.
*/
void
fpi_image_device_session_error (FpImageDevice *self, GError *error)
@@ -475,39 +438,27 @@ fpi_image_device_session_error (FpImageDevice *self, GError *error)
if (!priv->active)
{
FpiDeviceAction action = fpi_device_get_current_action (FP_DEVICE (self));
FpDeviceAction action = fpi_device_get_current_action (FP_DEVICE (self));
g_warning ("Driver reported session error, but device is inactive.");
if (action != FPI_DEVICE_ACTION_NONE)
if (action != FP_DEVICE_ACTION_NONE)
{
g_warning ("Translating to activation failure!");
fpi_image_device_activate_complete (self, error);
return;
}
}
else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
fpi_device_action_is_cancelled (FP_DEVICE (self)))
else if (priv->state == FP_IMAGE_DEVICE_STATE_INACTIVE)
{
/* Ignore cancellation errors here, as we will explicitly deactivate
* anyway (or, may already have done so at this point).
*/
g_debug ("Driver reported a cancellation error, this is expected but not required. Ignoring.");
g_clear_error (&error);
return;
}
else if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
{
g_warning ("Driver reported session error while deactivating already, ignoring. This indicates a driver bug.");
g_clear_error (&error);
g_warning ("Driver reported session error; translating to deactivation failure.");
fpi_image_device_deactivate_complete (self, error);
return;
}
if (error->domain == FP_DEVICE_RETRY)
g_warning ("Driver should report retries using fpi_image_device_retry_scan!");
priv->cancelling = TRUE;
fpi_image_device_deactivate (self);
priv->cancelling = FALSE;
fpi_device_action_error (FP_DEVICE (self), error);
}
@@ -522,15 +473,15 @@ void
fpi_image_device_activate_complete (FpImageDevice *self, GError *error)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
action = fpi_device_get_current_action (FP_DEVICE (self));
g_return_if_fail (priv->active == FALSE);
g_return_if_fail (action == FPI_DEVICE_ACTION_ENROLL ||
action == FPI_DEVICE_ACTION_VERIFY ||
action == FPI_DEVICE_ACTION_IDENTIFY ||
action == FPI_DEVICE_ACTION_CAPTURE);
g_return_if_fail (action == FP_DEVICE_ACTION_ENROLL ||
action == FP_DEVICE_ACTION_VERIFY ||
action == FP_DEVICE_ACTION_IDENTIFY ||
action == FP_DEVICE_ACTION_CAPTURE);
if (error)
{
@@ -545,7 +496,7 @@ fpi_image_device_activate_complete (FpImageDevice *self, GError *error)
/* We always want to capture at this point, move to AWAIT_FINGER
* state. */
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
fp_image_device_change_state (self, FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
}
/**
@@ -560,10 +511,10 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (self);
FpiDeviceAction action;
FpDeviceAction action;
g_return_if_fail (priv->active == TRUE);
g_return_if_fail (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE);
g_return_if_fail (priv->state == FP_IMAGE_DEVICE_STATE_INACTIVE);
g_debug ("Image device deactivation completed");
@@ -576,7 +527,7 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
/* Special case, if we should be closing, but didn't due to a running
* deactivation, then do so now. */
if (action == FPI_DEVICE_ACTION_CLOSE)
if (action == FP_DEVICE_ACTION_CLOSE)
{
cls->img_close (self);
return;
@@ -602,17 +553,17 @@ void
fpi_image_device_open_complete (FpImageDevice *self, GError *error)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
action = fpi_device_get_current_action (FP_DEVICE (self));
g_return_if_fail (priv->active == FALSE);
g_return_if_fail (action == FPI_DEVICE_ACTION_OPEN);
g_return_if_fail (action == FP_DEVICE_ACTION_OPEN);
g_debug ("Image device open completed");
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
priv->state = FP_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fp-image-device-state");
fpi_device_open_complete (FP_DEVICE (self), error);
}
@@ -628,17 +579,17 @@ void
fpi_image_device_close_complete (FpImageDevice *self, GError *error)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpiDeviceAction action;
FpDeviceAction action;
action = fpi_device_get_current_action (FP_DEVICE (self));
g_debug ("Image device close completed");
g_return_if_fail (priv->active == FALSE);
g_return_if_fail (action == FPI_DEVICE_ACTION_CLOSE);
g_return_if_fail (action == FP_DEVICE_ACTION_CLOSE);
priv->state = FPI_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fpi-image-device-state");
priv->state = FP_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify (G_OBJECT (self), "fp-image-device-state");
fpi_device_close_complete (FP_DEVICE (self), error);
}

View File

@@ -23,11 +23,11 @@
#include "fp-image-device.h"
/**
* FpiImageDeviceState:
* @FPI_IMAGE_DEVICE_STATE_INACTIVE: inactive
* @FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: waiting for the finger to be pressed or swiped
* @FPI_IMAGE_DEVICE_STATE_CAPTURE: capturing an image
* @FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: waiting for the finger to be removed
* FpImageDeviceState:
* @FP_IMAGE_DEVICE_STATE_INACTIVE: inactive
* @FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON: waiting for the finger to be pressed or swiped
* @FP_IMAGE_DEVICE_STATE_CAPTURE: capturing an image
* @FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF: waiting for the finger to be removed
*
* The state of an imaging device while doing a capture. The state is
* passed through to the driver using the ::activate() or ::change_state() vfuncs.
@@ -37,11 +37,11 @@
* unconditionally if the device supports raw capturing.
*/
typedef enum {
FPI_IMAGE_DEVICE_STATE_INACTIVE,
FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON,
FPI_IMAGE_DEVICE_STATE_CAPTURE,
FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF,
} FpiImageDeviceState;
FP_IMAGE_DEVICE_STATE_INACTIVE,
FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON,
FP_IMAGE_DEVICE_STATE_CAPTURE,
FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF,
} FpImageDeviceState;
/**
* FpImageDeviceClass:
@@ -90,8 +90,8 @@ struct _FpImageDeviceClass
void (*img_open) (FpImageDevice *dev);
void (*img_close) (FpImageDevice *dev);
void (*activate) (FpImageDevice *dev);
void (*change_state) (FpImageDevice *dev,
FpiImageDeviceState state);
void (*change_state) (FpImageDevice *dev,
FpImageDeviceState state);
void (*deactivate) (FpImageDevice *dev);
};

View File

@@ -34,7 +34,8 @@
* @title: Internal FpImage
* @short_description: Internal image handling routines
*
* Internal image handling routines. See #FpImage for public routines.
* Internal image handling routines. Also see the public <ulink
* url="libfprint-FpImage.html">FpImage routines</ulink>.
*/
/**

View File

@@ -37,7 +37,6 @@ 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;
/**

View File

@@ -17,7 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef __FPI_LOG_H__
#define __FPI_LOG_H__
/**
* SECTION:fpi-log
@@ -93,3 +94,5 @@
* Same as BUG_ON() but is always true.
*/
#define BUG() BUG_ON (1)
#endif

View File

@@ -23,7 +23,6 @@
#include "fp-print-private.h"
#include "fpi-device.h"
#include "fpi-compat.h"
/**
* SECTION: fpi-print
@@ -39,15 +38,15 @@
* @print: A #FpPrint
* @add: Print to append to @print
*
* Appends the single #FPI_PRINT_NBIS print from @add to the collection of
* prints in @print. Both print objects need to be of type #FPI_PRINT_NBIS
* Appends the single #FP_PRINT_NBIS print from @add to the collection of
* prints in @print. Both print objects need to be of type #FP_PRINT_NBIS
* for this to work.
*/
void
fpi_print_add_print (FpPrint *print, FpPrint *add)
{
g_return_if_fail (print->type == FPI_PRINT_NBIS);
g_return_if_fail (add->type == FPI_PRINT_NBIS);
g_return_if_fail (print->type == FP_PRINT_NBIS);
g_return_if_fail (add->type == FP_PRINT_NBIS);
g_assert (add->prints->len == 1);
g_ptr_array_add (print->prints, g_memdup (add->prints->pdata[0], sizeof (struct xyt_struct)));
@@ -63,20 +62,20 @@ fpi_print_add_print (FpPrint *print, FpPrint *add)
* print passed during enrollment.
*/
void
fpi_print_set_type (FpPrint *print,
FpiPrintType type)
fpi_print_set_type (FpPrint *print,
FpPrintType type)
{
g_return_if_fail (FP_IS_PRINT (print));
/* We only allow setting this once! */
g_return_if_fail (print->type == FPI_PRINT_UNDEFINED);
g_return_if_fail (print->type == FP_PRINT_UNDEFINED);
print->type = type;
if (print->type == FPI_PRINT_NBIS)
if (print->type == FP_PRINT_NBIS)
{
g_assert_null (print->prints);
print->prints = g_ptr_array_new_with_free_func (g_free);
}
g_object_notify (G_OBJECT (print), "fpi-type");
g_object_notify (G_OBJECT (print), "fp-type");
}
/**
@@ -144,7 +143,7 @@ minutiae_to_xyt (struct fp_minutiae *minutiae,
* @error: Return location for error
*
* Extracts the minutiae from the given image and adds it to @print of
* type #FPI_PRINT_NBIS.
* type #FP_PRINT_NBIS.
*
* The @image will be kept so that API users can get retrieve it e.g.
* for debugging purposes.
@@ -160,7 +159,7 @@ fpi_print_add_from_image (FpPrint *print,
struct fp_minutiae _minutiae;
struct xyt_struct *xyt;
if (print->type != FPI_PRINT_NBIS || !image)
if (print->type != FP_PRINT_NBIS || !image)
{
g_set_error (error,
G_IO_ERROR,
@@ -204,7 +203,7 @@ fpi_print_add_from_image (FpPrint *print,
* Match the newly scanned @print (containing exactly one print) against the
* prints contained in @template which will have been stored during enrollment.
*
* Both @template and @print need to be of type #FPI_PRINT_NBIS for this to
* Both @template and @print need to be of type #FP_PRINT_NBIS for this to
* work.
*
* Returns: Whether the prints match, @error will be set if #FPI_MATCH_ERROR is returned
@@ -217,7 +216,7 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
gint i;
/* XXX: Use a different error type? */
if (template->type != FPI_PRINT_NBIS || print->type != FPI_PRINT_NBIS)
if (template->type != FP_PRINT_NBIS || print->type != FP_PRINT_NBIS)
{
*error = fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
"It is only possible to match NBIS type print data");
@@ -248,115 +247,3 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
return FPI_MATCH_FAIL;
}
/**
* fpi_print_generate_user_id:
* @print: #FpPrint to generate the ID for
*
* Generates a string identifier for the represented print. This identifier
* encodes some metadata about the print. It also includes a random string
* and may be assumed to be unique.
*
* This is useful if devices are able to store a string identifier, but more
* storing more metadata may be desirable. In effect, this means the driver
* can provide somewhat more meaningful data to fp_device_list_prints().
*
* The generated ID may be truncated after 23 characters. However, more space
* is required to include the username, and it is recommended to store at
* at least 31 bytes.
*
* The generated format may change in the future. It is versioned though and
* decoding should remain functional.
*
* Returns: A unique string of 23 + strlen(username) characters
*/
gchar *
fpi_print_generate_user_id (FpPrint *print)
{
const gchar *username = NULL;
gchar *user_id = NULL;
const GDate *date;
gint y = 0, m = 0, d = 0;
gint32 rand_id = 0;
g_assert (print);
date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
username = fp_print_get_username (print);
if (!username)
username = "nobody";
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
fp_print_get_finger (print),
rand_id,
username);
return user_id;
}
/**
* fpi_print_fill_from_user_id:
* @print: #FpPrint to fill metadata into
* @user_id: An ID that was likely encoded using fpi_print_generate_user_id()
*
* This is the reverse operation of fpi_print_generate_user_id(), allowing
* the driver to encode some print metadata in a string.
*
* Returns: Whether a valid ID was found
*/
gboolean
fpi_print_fill_from_user_id (FpPrint *print, const char *user_id)
{
g_return_val_if_fail (user_id, FALSE);
/* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (user_id, "FP1-") && strlen (user_id) >= 24 &&
user_id[12] == '-' && user_id[14] == '-' && user_id[23] == '-')
{
g_autofree gchar *copy = g_strdup (user_id);
g_autoptr(GDate) date = NULL;
gint32 date_ymd;
gint32 finger;
gchar *username;
/* Try to parse information from the string. */
copy[12] = '\0';
date_ymd = g_ascii_strtod (copy + 4, NULL);
if (date_ymd > 0)
date = g_date_new_dmy (date_ymd % 100,
(date_ymd / 100) % 100,
date_ymd / 10000);
else
date = g_date_new ();
fp_print_set_enroll_date (print, date);
copy[14] = '\0';
finger = g_ascii_strtoll (copy + 13, NULL, 16);
fp_print_set_finger (print, finger);
/* We ignore the next chunk, it is just random data.
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
return TRUE;
}
return FALSE;
}

View File

@@ -7,20 +7,20 @@
G_BEGIN_DECLS
/**
* FpiPrintType:
* @FPI_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
* @FPI_PRINT_RAW: A raw print where the data is directly compared
* @FPI_PRINT_NBIS: NBIS minutiae comparison
* FpPrintType:
* @FP_PRINT_UNDEFINED: Undefined type, this happens prior to enrollment
* @FP_PRINT_RAW: A raw print where the data is directly compared
* @FP_PRINT_NBIS: NBIS minutiae comparison
*/
typedef enum {
FPI_PRINT_UNDEFINED = 0,
FPI_PRINT_RAW,
FPI_PRINT_NBIS,
} FpiPrintType;
FP_PRINT_UNDEFINED = 0,
FP_PRINT_RAW,
FP_PRINT_NBIS,
} FpPrintType;
/**
* FpiMatchResult:
* @FPI_MATCH_ERROR: An error occurred during matching
* @FPI_MATCH_ERROR: An error occured during matching
* @FPI_MATCH_FAIL: The prints did not match
* @FPI_MATCH_SUCCESS: The prints matched
*/
@@ -33,8 +33,8 @@ typedef enum {
void fpi_print_add_print (FpPrint *print,
FpPrint *add);
void fpi_print_set_type (FpPrint *print,
FpiPrintType type);
void fpi_print_set_type (FpPrint *print,
FpPrintType type);
void fpi_print_set_device_stored (FpPrint *print,
gboolean device_stored);
@@ -47,9 +47,4 @@ FpiMatchResult fpi_print_bz3_match (FpPrint * template,
gint bz3_threshold,
GError **error);
/* Helpers to encode metadata into user ID strings. */
gchar * fpi_print_generate_user_id (FpPrint *print);
gboolean fpi_print_fill_from_user_id (FpPrint *print,
const char *user_id);
G_END_DECLS

View File

@@ -22,6 +22,7 @@
#pragma once
#include "fp-device.h"
#include "fpi-usb-transfer.h"
/* async drv <--> lib comms */
@@ -100,8 +101,6 @@ int fpi_ssm_get_cur_state (FpiSsm *machine);
/* Callbacks to be used by the driver instead of implementing their own
* logic.
*/
typedef struct _FpiUsbTransfer FpiUsbTransfer;
void fpi_ssm_usb_transfer_cb (FpiUsbTransfer *transfer,
FpDevice *device,
gpointer unused_data,

View File

@@ -366,7 +366,7 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
*
* Note that #FpiUsbTransfer will be stolen when this function is called.
* So that all associated data will be free'ed automatically, after the
* callback ran unless fpi_usb_transfer_ref() is explicitly called.
* callback ran unless fpi_usb_transfer_ref() is explictly called.
*/
void
fpi_usb_transfer_submit (FpiUsbTransfer *transfer,

View File

@@ -30,7 +30,8 @@ G_BEGIN_DECLS
#define FPI_USB_ENDPOINT_OUT 0x00
typedef struct _FpiUsbTransfer FpiUsbTransfer;
typedef struct _FpiSsm FpiSsm;
#include "fpi-ssm.h"
typedef void (*FpiUsbTransferCallback)(FpiUsbTransfer *transfer,
FpDevice *dev,
@@ -61,7 +62,7 @@ typedef enum {
* @length: The requested length of the transfer in bytes.
* @actual_length: The actual length of the transfer
* (see also fpi_usb_transfer_set_short_error())
* @buffer: The transferred data.
* @buffer: The transfered data.
*
* Helper for handling USB transfers.
*/

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,8 @@ insert_drivers (GList *list)
for (i = 0; i < drivers->len; i++)
{
GType driver = g_array_index (drivers, GType, i);
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
const FpIdEntry *entry;
if (cls->type != FP_DEVICE_TYPE_USB)

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2009 Red Hat <mjg@redhat.com>
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -104,7 +104,8 @@ main (int argc, char **argv)
for (i = 0; i < drivers->len; i++)
{
GType driver = g_array_index (drivers, GType, i);
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
if (cls->type != FP_DEVICE_TYPE_USB)
continue;

View File

@@ -8,39 +8,32 @@ libfprint_sources = [
libfprint_private_sources = [
'fpi-assembling.c',
'fpi-byte-reader.c',
'fpi-byte-writer.c',
'fpi-device.c',
'fpi-image-device.c',
'fpi-image.c',
'fpi-image-device.c',
'fpi-print.c',
'fpi-ssm.c',
'fpi-usb-transfer.c',
'fpi-byte-reader.c',
'fpi-byte-writer.c',
]
libfprint_public_headers = [
'fp-context.h',
'fp-device.h',
'fp-image-device.h',
'fp-image.h',
'fp-print.h',
]
libfprint_private_headers = [
'fpi-assembling.h',
'fpi-byte-reader.h',
'fpi-byte-utils.h',
'fpi-byte-writer.h',
'fpi-compat.h',
'fpi-context.h',
'fpi-device.h',
'fpi-image-device.h',
'fpi-image.h',
'fpi-log.h',
'fpi-minutiae.h',
'fpi-image-device.h',
'fpi-print.h',
'fpi-usb-transfer.h',
'fpi-ssm.h',
'fpi-byte-reader.h',
'fpi-byte-writer.h',
'fpi-byte-utils.h',
]
nbis_sources = [
@@ -177,21 +170,14 @@ other_sources = []
fp_enums = gnome.mkenums_simple('fp-enums',
sources: libfprint_public_headers,
install_header: true,
install_dir: get_option('includedir') / versioned_libname,
)
install_header : true)
fp_enums_h = fp_enums[1]
fpi_enums = gnome.mkenums_simple('fpi-enums',
sources: libfprint_private_headers,
install_header: false,
)
install_header : true)
fpi_enums_h = fpi_enums[1]
enums_dep = declare_dependency(
sources: [ fp_enums_h, fpi_enums_h ]
)
drivers_sources += configure_file(input: 'empty_file',
output: 'fpi-drivers.c',
capture: true,
@@ -200,21 +186,8 @@ drivers_sources += configure_file(input: 'empty_file',
'\n'.join(drivers_type_list + [] + drivers_type_func)
])
deps = [
enums_dep,
gio_dep,
glib_dep,
gobject_dep,
gusb_dep,
imaging_dep,
mathlib_dep,
nss_dep,
]
deps = [ mathlib_dep, glib_dep, gusb_dep, nss_dep, imaging_dep, gio_dep ]
# These are empty and only exist so that the include directories are created
# in the build tree. This silences a build time warning.
subdir('nbis/include')
subdir('nbis/libfprint-include')
deps += declare_dependency(include_directories: [
root_inc,
include_directories('nbis/include'),
@@ -232,16 +205,13 @@ libnbis = static_library('nbis',
install: false)
libfprint_private = static_library('fprint-private',
sources: [
fpi_enums,
libfprint_private_sources,
],
sources: libfprint_private_sources + fpi_enums + [ fp_enums_h ],
dependencies: deps,
link_with: libnbis,
install: false)
libfprint_drivers = static_library('fprint-drivers',
sources: drivers_sources,
sources: drivers_sources + [ fp_enums_h ],
c_args: drivers_cflags,
dependencies: deps,
link_with: libfprint_private,
@@ -250,33 +220,26 @@ libfprint_drivers = static_library('fprint-drivers',
mapfile = files('libfprint.ver')
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
libfprint = library(versioned_libname.split('lib')[1],
sources: [
fp_enums,
libfprint_sources,
other_sources,
],
libfprint = library('fprint',
sources: libfprint_sources + fp_enums + other_sources,
soversion: soversion,
version: libversion,
link_args : vflag,
link_depends : mapfile,
link_with: [libfprint_drivers, libfprint_private],
link_with: [libfprint_private, libfprint_drivers],
dependencies: deps,
install: true)
libfprint_dep = declare_dependency(link_with: libfprint,
sources: [ fp_enums_h ],
include_directories: root_inc,
dependencies: [
enums_dep,
gio_dep,
glib_dep,
gobject_dep,
gusb_dep,
])
install_headers(['fprint.h'] + libfprint_public_headers,
subdir: versioned_libname
)
install_headers(['fprint.h'] + libfprint_public_headers, subdir: 'libfprint')
libfprint_private_dep = declare_dependency(
include_directories: include_directories('.'),
@@ -295,7 +258,7 @@ udev_rules = executable('fprint-list-udev-rules',
if get_option('udev_rules')
custom_target('udev-rules',
output: '60-@0@-autosuspend.rules'.format(versioned_libname),
output: '60-fprint-autosuspend.rules',
capture: true,
command: [ udev_rules ],
install: true,
@@ -316,7 +279,7 @@ if get_option('introspection')
libfprint_public_headers,
libfprint_sources,
],
nsversion : '@0@.0'.format(soversion),
nsversion : '2.0',
namespace : 'FPrint',
symbol_prefix : 'fp_',
identifier_prefix : 'Fp',
@@ -327,7 +290,6 @@ if get_option('introspection')
link_with : libfprint,
dependencies : [
gio_dep,
gobject_dep,
gusb_dep,
],
includes : [

View File

@@ -1,57 +0,0 @@
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. */

View File

@@ -260,8 +260,6 @@ 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;
@@ -611,9 +609,6 @@ 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 *****/
@@ -1128,9 +1123,6 @@ 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,

View File

@@ -440,8 +440,6 @@ 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;

View File

@@ -150,8 +150,6 @@ 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,
@@ -236,8 +234,6 @@ 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,

View File

@@ -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 != 0)
if(ret == IGNORE)
/* 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 != 0)
if(ret == IGNORE)
/* Deallocate the minutia. */
free_minutia(minutia);

View File

@@ -195,11 +195,6 @@ 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);
}
@@ -1334,159 +1329,6 @@ 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

View File

@@ -147,8 +147,6 @@ 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,
@@ -409,8 +407,6 @@ 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. */

View File

@@ -1,231 +0,0 @@
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

View File

@@ -192,9 +192,3 @@ 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

View File

@@ -1,12 +1,12 @@
project('libfprint', [ 'c', 'cpp' ],
version: '1.90.1',
version: '1.90.0',
license: 'LGPLv2.1+',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
'c_std=gnu99',
'c_std=c99',
],
meson_version: '>= 0.49.0')
meson_version: '>= 0.46.0')
gnome = import('gnome')
@@ -53,9 +53,10 @@ common_cflags = cc.get_supported_arguments([
'-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def,
'-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def,
'-D_GNU_SOURCE',
'-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()),
'-DG_LOG_DOMAIN="libfprint"',
])
c_cflags = cc.get_supported_arguments([
'-std=gnu99',
'-Wimplicit-function-declaration',
'-Wmissing-prototypes',
'-Wnested-externs',
@@ -74,18 +75,13 @@ soversion = 2
current = 0
revision = 0
libversion = '@0@.@1@.@2@'.format(soversion, current, revision)
versioned_libname = meson.project_name() + '-' + soversion.to_string()
# Dependencies
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
gusb_dep = dependency('gusb', version: '>= 0.2.0')
gusb_dep = dependency('gusb', version: '>= 0.3.0')
mathlib_dep = cc.find_library('m', required: false)
# The following dependencies are only used for tests
cairo_dep = dependency('cairo', required: false)
# Drivers
drivers = get_option('drivers').split(',')
virtual_drivers = [ 'virtual_image' ]
@@ -207,11 +203,10 @@ subdir('tests')
pkgconfig = import('pkgconfig')
pkgconfig.generate(
name: versioned_libname,
name: 'libfprint',
description: 'Generic C API for fingerprint reader access',
version: meson.project_version(),
libraries: libfprint,
requires: [gio_dep, gobject_dep],
subdirs: versioned_libname,
filebase: versioned_libname,
)
subdirs: 'libfprint',
filebase: 'libfprint2',
install_dir: join_paths(get_option('libdir'), 'pkgconfig'))

View File

@@ -21,33 +21,4 @@ To create a new umockdev test, you should:
Please note, there is no need to use a real finger print in this case. If
you would like to avoid submitting your own fingerprint then please just
use e.g. the side of your finger, arm, or anything else that will produce
an image with the device.
Note that umockdev-record groups URBs aggressively. In most cases, manual
intervention is unfortunately required. In most cases, drivers do a chain
of commands like e.g. A then B each with a different reply. Umockdev will
create a file like:
A
reply 1
reply 2
B
reply 1
reply 2
which then needs to be re-ordered to be:
A
reply 1
B
reply 1
A
reply 2
B
reply 2
Other changes may be needed to get everything working. For example the elan
driver relies on a timeout that is not reported correctly. In this case the
driver works around it by interpreting the protocol error differently in
the virtual environment.
an image with the device.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -1,284 +0,0 @@
P: /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.4
N: bus/usb/001/094=1201000200000008F304260C40010102000109023E0001010080320904000005FF0000000921100100012215000705810240000107050102400001070582024000010705830240000107050302400001
E: DEVNAME=/dev/bus/usb/001/094
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=4f3/c26/140
E: TYPE=0/0/0
E: BUSNUM=001
E: DEVNUM=094
E: MAJOR=189
E: MINOR=93
E: SUBSYSTEM=usb
E: ID_VENDOR=ELAN
E: ID_VENDOR_ENC=ELAN
E: ID_VENDOR_ID=04f3
E: ID_MODEL=ELAN:Fingerprint
E: ID_MODEL_ENC=ELAN:Fingerprint
E: ID_MODEL_ID=0c26
E: ID_REVISION=0140
E: ID_SERIAL=ELAN_ELAN:Fingerprint
E: ID_BUS=usb
E: ID_USB_INTERFACES=:ff0000:
E: ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp.
E: ID_PATH=pci-0000:00:14.0-usb-0:4.4
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_4_4
E: LIBFPRINT_DRIVER=ElanTech Fingerprint Sensor
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=00
A: bDeviceProtocol=00
A: bDeviceSubClass=00
A: bMaxPacketSize0=8
A: bMaxPower=100mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0140
A: bmAttributes=80
A: busnum=1
A: configuration=
H: descriptors=1201000200000008F304260C40010102000109023E0001010080320904000005FF0000000921100100012215000705810240000107050102400001070582024000010705830240000107050302400001
A: dev=189:93
A: devnum=94
A: devpath=4.4
L: driver=../../../../../../bus/usb/drivers/usb
A: idProduct=0c26
A: idVendor=04f3
A: ltm_capable=no
A: manufacturer=ELAN
A: maxchild=0
L: port=../1-4:1.0/1-4-port4
A: power/active_duration=4747
A: power/autosuspend=2
A: power/autosuspend_delay_ms=2000
A: power/connected_duration=54012
A: power/control=auto
A: power/level=auto
A: power/persist=1
A: power/runtime_active_time=4721
A: power/runtime_status=active
A: power/runtime_suspended_time=49114
A: product=ELAN:Fingerprint
A: quirks=0x0
A: removable=removable
A: rx_lanes=1
A: speed=12
A: tx_lanes=1
A: urbnum=13
A: version= 2.00
P: /devices/pci0000:00/0000:00:14.0/usb1/1-4
N: bus/usb/001/083=1201100209000140EF17181084520102000109021900010100E0000904000001090000000705810301000C
E: DEVNAME=/dev/bus/usb/001/083
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=17ef/1018/5284
E: TYPE=9/0/1
E: BUSNUM=001
E: DEVNUM=083
E: MAJOR=189
E: MINOR=82
E: SUBSYSTEM=usb
E: ID_VENDOR=VIA_Labs__Inc.
E: ID_VENDOR_ENC=VIA\x20Labs\x2c\x20Inc.\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_VENDOR_ID=17ef
E: ID_MODEL=USB2.0_Hub
E: ID_MODEL_ENC=USB2.0\x20Hub\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
E: ID_MODEL_ID=1018
E: ID_REVISION=5284
E: ID_SERIAL=VIA_Labs__Inc._USB2.0_Hub
E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR_FROM_DATABASE=Lenovo
E: ID_PATH=pci-0000:00:14.0-usb-0:4
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_4
E: ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_4
E: TAGS=:seat:
A: authorized=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=09
A: bDeviceProtocol=01
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=5284
A: bmAttributes=e0
A: busnum=1
A: configuration=
H: descriptors=1201100209000140EF17181084520102000109021900010100E0000904000001090000000705810301000C
A: dev=189:82
A: devnum=83
A: devpath=4
L: driver=../../../../../bus/usb/drivers/usb
A: idProduct=1018
A: idVendor=17ef
A: ltm_capable=no
A: manufacturer=VIA Labs, Inc.
A: maxchild=4
L: port=../1-0:1.0/usb1-port4
A: power/active_duration=11223581
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=11223581
A: power/control=auto
A: power/level=auto
A: power/runtime_active_time=11223333
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=USB2.0 Hub
A: quirks=0x0
A: removable=removable
A: rx_lanes=1
A: speed=480
A: tx_lanes=1
A: urbnum=106
A: version= 2.10
P: /devices/pci0000:00/0000:00:14.0/usb1
N: bus/usb/001/001=12010002090001406B1D020003050302010109021900010100E0000904000001090000000705810304000C
E: DEVNAME=/dev/bus/usb/001/001
E: DEVTYPE=usb_device
E: DRIVER=usb
E: PRODUCT=1d6b/2/503
E: TYPE=9/0/1
E: BUSNUM=001
E: DEVNUM=001
E: MAJOR=189
E: MINOR=0
E: SUBSYSTEM=usb
E: ID_VENDOR=Linux_5.3.8-300.fc31.x86_64_xhci-hcd
E: ID_VENDOR_ENC=Linux\x205.3.8-300.fc31.x86_64\x20xhci-hcd
E: ID_VENDOR_ID=1d6b
E: ID_MODEL=xHCI_Host_Controller
E: ID_MODEL_ENC=xHCI\x20Host\x20Controller
E: ID_MODEL_ID=0002
E: ID_REVISION=0503
E: ID_SERIAL=Linux_5.3.8-300.fc31.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0
E: ID_SERIAL_SHORT=0000:00:14.0
E: ID_BUS=usb
E: ID_USB_INTERFACES=:090000:
E: ID_VENDOR_FROM_DATABASE=Linux Foundation
E: ID_MODEL_FROM_DATABASE=2.0 root hub
E: ID_PATH=pci-0000:00:14.0
E: ID_PATH_TAG=pci-0000_00_14_0
E: ID_FOR_SEAT=usb-pci-0000_00_14_0
E: TAGS=:seat:
A: authorized=1
A: authorized_default=1
A: avoid_reset_quirk=0
A: bConfigurationValue=1
A: bDeviceClass=09
A: bDeviceProtocol=01
A: bDeviceSubClass=00
A: bMaxPacketSize0=64
A: bMaxPower=0mA
A: bNumConfigurations=1
A: bNumInterfaces= 1
A: bcdDevice=0503
A: bmAttributes=e0
A: busnum=1
A: configuration=
H: descriptors=12010002090001406B1D020003050302010109021900010100E0000904000001090000000705810304000C
A: dev=189:0
A: devnum=1
A: devpath=0
L: driver=../../../../bus/usb/drivers/usb
A: idProduct=0002
A: idVendor=1d6b
A: interface_authorized_default=1
A: ltm_capable=no
A: manufacturer=Linux 5.3.8-300.fc31.x86_64 xhci-hcd
A: maxchild=12
A: power/active_duration=2372569822
A: power/autosuspend=0
A: power/autosuspend_delay_ms=0
A: power/connected_duration=2405642105
A: power/control=auto
A: power/level=auto
A: power/runtime_active_time=2372599414
A: power/runtime_status=active
A: power/runtime_suspended_time=33016992
A: power/wakeup=disabled
A: power/wakeup_abort_count=
A: power/wakeup_active=
A: power/wakeup_active_count=
A: power/wakeup_count=
A: power/wakeup_expire_count=
A: power/wakeup_last_time_ms=
A: power/wakeup_max_time_ms=
A: power/wakeup_total_time_ms=
A: product=xHCI Host Controller
A: quirks=0x0
A: removable=unknown
A: rx_lanes=1
A: serial=0000:00:14.0
A: speed=480
A: tx_lanes=1
A: urbnum=19225
A: version= 2.00
P: /devices/pci0000:00/0000:00:14.0
E: DRIVER=xhci_hcd
E: PCI_CLASS=C0330
E: PCI_ID=8086:9D2F
E: PCI_SUBSYS_ID=17AA:2238
E: PCI_SLOT_NAME=0000:00:14.0
E: MODALIAS=pci:v00008086d00009D2Fsv000017AAsd00002238bc0Csc03i30
E: SUBSYSTEM=pci
E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: ID_MODEL_FROM_DATABASE=Sunrise Point-LP USB 3.0 xHCI Controller
A: ari_enabled=0
A: broken_parity_status=0
A: class=0x0c0330
H: config=86802F9D060490022130030C00008000040022E1000000000000000000000000000000000000000000000000AA1738220000000070000000000000000B010000
A: consistent_dma_mask_bits=64
A: d3cold_allowed=1
A: dbc=disabled
A: device=0x9d2f
A: dma_mask_bits=64
L: driver=../../../bus/pci/drivers/xhci_hcd
A: driver_override=(null)
A: enable=1
A: irq=125
A: local_cpulist=0-3
A: local_cpus=f
A: modalias=pci:v00008086d00009D2Fsv000017AAsd00002238bc0Csc03i30
A: msi_bus=1
A: msi_irqs/125=msi
A: numa_node=-1
A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 37 38 2112 38\nxHCI ring segments 116 120 4096 120\nbuffer-2048 3 6 2048 3\nbuffer-512 0 0 512 0\nbuffer-128 30 32 128 1\nbuffer-32 0 0 32 0
A: power/control=on
A: power/runtime_active_time=2405617003
A: power/runtime_status=active
A: power/runtime_suspended_time=0
A: power/wakeup=enabled
A: power/wakeup_abort_count=0
A: power/wakeup_active=0
A: power/wakeup_active_count=0
A: power/wakeup_count=0
A: power/wakeup_expire_count=0
A: power/wakeup_last_time_ms=0
A: power/wakeup_max_time_ms=0
A: power/wakeup_total_time_ms=0
A: resource=0x00000000e1220000 0x00000000e122ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
A: revision=0x21
A: subsystem_device=0x2238
A: subsystem_vendor=0x17aa
A: vendor=0x8086

View File

@@ -4,7 +4,7 @@ envs.set('G_DEBUG', 'fatal-warnings')
envs.set('G_MESSAGES_DEBUG', 'all')
# Setup paths
envs.set('MESON_SOURCE_ROOT', meson.source_root())
envs.set('MESON_SOURCE_ROOT', meson.build_root())
envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
# Set FP_DEVICE_EMULATION so that drivers can adapt (e.g. to use fixed
@@ -16,83 +16,34 @@ envs.set('FP_DRIVERS_WHITELIST', 'virtual_image')
envs.set('NO_AT_BRIDGE', '1')
drivers_tests = [
'elan',
'vfs5011',
'synaptics',
]
if get_option('introspection')
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
if 'virtual_image' in drivers
python3 = find_program('python3')
unittest_inspector = find_program('unittest_inspector.py')
base_args = files('virtual-image.py')
suite = []
r = run_command(unittest_inspector, files('virtual-image.py'))
unit_tests = r.stdout().strip().split('\n')
if r.returncode() == 0 and unit_tests.length() > 0
suite += 'virtual-image'
else
unit_tests = ['virtual-image']
endif
foreach ut: unit_tests
ut_suite = suite
ut_args = base_args
if unit_tests.length() > 1
ut_args += ut
ut_suite += ut.split('.')[0]
endif
test(ut,
python3,
args: ut_args,
suite: ut_suite,
depends: libfprint_typelib,
env: envs,
)
endforeach
else
test('virtual-image',
find_program('sh'),
args: ['-c', 'exit 77']
find_program('virtual-image.py'),
args: '--verbose',
env: envs,
depends: libfprint_typelib,
)
endif
drivers_tests = [
'vfs5011',
'synaptics',
]
foreach driver_test: drivers_tests
driver_envs = envs
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
if driver_test in drivers and gusb_dep.version().version_compare('>= 0.3.0')
test(driver_test,
find_program('umockdev-test.py'),
args: join_paths(meson.current_source_dir(), driver_test),
env: driver_envs,
suite: ['drivers'],
timeout: 10,
depends: libfprint_typelib,
)
else
test(driver_test,
find_program('sh'),
args: ['-c', 'exit 77']
)
endif
endforeach
else
warning('Skipping all driver tests as introspection bindings are missing')
test('virtual-image',
find_program('sh'),
args: ['-c', 'exit 77']
)
foreach driver_test: drivers_tests
test(driver_test,
find_program('sh'),
args: ['-c', 'exit 77']
find_program('umockdev-test.py'),
args: join_paths(meson.current_source_dir(), driver_test),
env: driver_envs,
suite: ['drivers'],
timeout: 10,
depends: libfprint_typelib,
)
endforeach
endif
@@ -108,7 +59,6 @@ test_utils = static_library('fprint-test-utils',
unit_tests = [
'fpi-device',
'fpi-ssm',
'fpi-assembling',
]
if 'virtual_image' in drivers
@@ -118,41 +68,11 @@ if 'virtual_image' in drivers
]
endif
unit_tests_deps = { 'fpi-assembling' : [cairo_dep] }
test_config = configuration_data()
test_config.set_quoted('SOURCE_ROOT', meson.source_root())
test_config_h = configure_file(output: 'test-config.h', configuration: test_config)
foreach test_name: unit_tests
if unit_tests_deps.has_key(test_name)
missing_deps = false
foreach dep: unit_tests_deps[test_name]
if not dep.found()
missing_deps = true
break
endif
endforeach
if missing_deps
# Create a dummy test that always skips instead
warning('Test @0@ cannot be compiled due to missing dependencies'.format(test_name))
test(test_name,
find_program('sh'),
suite: ['unit-tests'],
args: ['-c', 'exit 77'],
)
continue
endif
extra_deps = unit_tests_deps[test_name]
else
extra_deps = []
endif
basename = 'test-' + test_name
test_exe = executable(basename,
sources: [basename + '.c', test_config_h],
dependencies: [ libfprint_private_dep ] + extra_deps,
sources: basename + '.c',
dependencies: libfprint_private_dep,
c_args: common_cflags,
link_with: test_utils,
)

View File

@@ -35,15 +35,9 @@ fpi_device_fake_probe (FpDevice *device)
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_PROBE);
fake_dev->last_called_function = fpi_device_fake_probe;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_PROBE);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
fpi_device_probe_complete (device, dev_class->id, dev_class->full_name,
fake_dev->ret_error);
}
@@ -53,15 +47,9 @@ fpi_device_fake_open (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_OPEN);
fake_dev->last_called_function = fpi_device_fake_open;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
fpi_device_open_complete (device, fake_dev->ret_error);
}
@@ -70,15 +58,9 @@ fpi_device_fake_close (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_CLOSE);
fake_dev->last_called_function = fpi_device_fake_close;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CLOSE);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
fpi_device_close_complete (device, fake_dev->ret_error);
}
@@ -88,26 +70,14 @@ fpi_device_fake_enroll (FpDevice *device)
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *print = fake_dev->ret_print;
fake_dev->last_called_function = fpi_device_fake_enroll;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_ENROLL);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_ENROLL);
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_print_set_type (print, FPI_PRINT_RAW);
}
fpi_device_get_enroll_data (device, &print);
fpi_device_enroll_complete (device,
print ? g_object_ref (print) : NULL,
fake_dev->ret_error);
fake_dev->last_called_function = fpi_device_fake_enroll;
fpi_device_enroll_complete (device, print, fake_dev->ret_error);
}
static void
@@ -116,29 +86,15 @@ fpi_device_fake_verify (FpDevice *device)
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *print = fake_dev->ret_print;
fake_dev->last_called_function = fpi_device_fake_verify;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_VERIFY);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_VERIFY);
fpi_device_get_verify_data (device, (FpPrint **) &fake_dev->action_data);
if (!print && !fake_dev->ret_error)
fpi_device_get_verify_data (device, &print);
if (!fake_dev->ret_error || fake_dev->ret_error->domain == FP_DEVICE_RETRY)
{
fpi_device_verify_report (device, fake_dev->ret_result, print, fake_dev->ret_error);
fpi_device_verify_complete (device, NULL);
}
else
{
fpi_device_verify_complete (device, fake_dev->ret_error);
}
fake_dev->last_called_function = fpi_device_fake_verify;
fpi_device_verify_complete (device, fake_dev->ret_result, print,
fake_dev->ret_error);
}
static void
@@ -147,15 +103,7 @@ fpi_device_fake_identify (FpDevice *device)
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *match = fake_dev->ret_match;
fake_dev->last_called_function = fpi_device_fake_identify;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_IDENTIFY);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_IDENTIFY);
fpi_device_get_identify_data (device, (GPtrArray **) &fake_dev->action_data);
if (!match && !fake_dev->ret_error)
@@ -177,34 +125,20 @@ fpi_device_fake_identify (FpDevice *device)
}
}
if (!fake_dev->ret_error || fake_dev->ret_error->domain == FP_DEVICE_RETRY)
{
fpi_device_identify_report (device, match, fake_dev->ret_print, fake_dev->ret_error);
fpi_device_identify_complete (device, NULL);
}
else
{
fpi_device_identify_complete (device, fake_dev->ret_error);
}
fake_dev->last_called_function = fpi_device_fake_identify;
fpi_device_identify_complete (device, match, fake_dev->ret_print,
fake_dev->ret_error);
}
static void
fpi_device_fake_capture (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean wait_for_finger;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_CAPTURE);
fpi_device_get_capture_data (device, (gboolean *) &fake_dev->action_data);
fake_dev->last_called_function = fpi_device_fake_capture;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CAPTURE);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
fpi_device_get_capture_data (device, &wait_for_finger);
fake_dev->action_data = GINT_TO_POINTER (wait_for_finger);
fpi_device_capture_complete (device, fake_dev->ret_image, fake_dev->ret_error);
}
@@ -213,15 +147,9 @@ fpi_device_fake_list (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_LIST);
fake_dev->last_called_function = fpi_device_fake_list;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_LIST);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
fpi_device_list_complete (device, fake_dev->ret_list, fake_dev->ret_error);
}
@@ -230,16 +158,10 @@ fpi_device_fake_delete (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FP_DEVICE_ACTION_DELETE);
fpi_device_get_delete_data (device, (gpointer) & fake_dev->action_data);
fake_dev->last_called_function = fpi_device_fake_delete;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_DELETE);
if (fake_dev->return_action_error)
{
fpi_device_action_error (device, fake_dev->ret_error);
return;
}
fpi_device_get_delete_data (device, (FpPrint **) (&fake_dev->action_data));
fpi_device_delete_complete (device, fake_dev->ret_error);
}
@@ -248,8 +170,9 @@ fpi_device_fake_cancel (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), !=, FP_DEVICE_ACTION_NONE);
fake_dev->last_called_function = fpi_device_fake_cancel;
g_assert_cmpuint (fpi_device_get_current_action (device), !=, FPI_DEVICE_ACTION_NONE);
}
static void

View File

@@ -30,7 +30,6 @@ struct _FpiDeviceFake
FpDevice parent;
gpointer last_called_function;
gboolean return_action_error;
GError *ret_error;
FpPrint *ret_print;

Some files were not shown because too many files have changed in this diff Show More