Compare commits

..

67 Commits

Author SHA1 Message Date
Benjamin Berg
e1fdc7b01b uru4000: Fix control transfer request type
During porting the request type was accidentally changed from VENDOR to
DEVICE. Change the type back to VENDOR.

Fixes: #205
2019-12-04 13:11:32 +01:00
Marco Trevisan (Treviño)
1e2f19ea3d fpi-ssm: Mark a fpi-ssm completed on delay 2019-12-03 18:28:48 +01:00
Marco Trevisan (Treviño)
b0effae990 fpi-ssm: Bug on handler set to a NULL function
We would crash otherwise, while this is quite obvious there was no code
enforcing this.
2019-12-03 18:28:48 +01:00
Marco Trevisan (Treviño)
ff67bf5a16 fpi-ssm: Make delayed actions cancellable
Add a GCancellable parameter to fpi_ssm_nex_state_delayed and
fpi_ssm_jump_to_state_delayed() so that it's possible to cancel an action
from the caller and in case the driver wants to cancel a delayed operation
when a device action has been cancelled.
2019-12-03 18:28:48 +01:00
Marco Trevisan (Treviño)
bac6382f67 drivers: Use SSM delayed actions when possible 2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
e12978f402 fpi-ssm: Clarify the ownership of error in fpi_ssm_mark_failed 2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
1ba95db379 drivers: Use fpi_ssm_next_state_delayed instead of custom callbacks
As per this fpi_ssm_next_state_timeout_cb can be removed
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
7ec2df2405 fpi-ssm: Add possibility to jump to a state (or next one) with delay
This allows to have an automatic cleanup of the timeout source when the
the callback is reached and to avoid to do further state changes in the
middle.
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
3ed73aa17c fpi-device: Make possible to set a DestroyNotify for timeout data
Since GSource data can be automatically cleaned up on source destruction, we
can mimic this for the devices timeout easily as well.

Add an extra parameter, and let's use this cocci file to adapt all the
drivers like magic:

	@@
	expression e1, e2, e3, e4;
	@@
	fpi_device_add_timeout (e1, e2, e3, e4
	+  , NULL
  	)
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
0241617713 fpi-ssm: Also bug-on negative state value
Being an integer, anything could happen.
2019-12-03 17:31:22 +01:00
Marco Trevisan (Treviño)
20a52593eb vfs301: Use a transfer autopointer to cleanup it on sync submission
Partially revert commit a855c0cc7, since the driver uses a sync transfer
and in such case the caller still keeps the ownership.
2019-12-03 13:58:42 +00:00
Marco Trevisan (Treviño)
42db16364d synaptics: Close the usb device if reset failed
If reseting the device failed, we still need to close the usb device before
returning.
2019-12-03 13:58:42 +00:00
Marco Trevisan (Treviño)
ee606ae49e synaptics: Use an autoptr to handle the FpiUsbTransfer sync transfers
When using fpi_usb_transfer_submit_sync we still need to unref the transfer
once done with it, so let's use an auto pointer so we free it also on
errors and early returns without having to handle this manually.
2019-12-03 13:58:42 +00:00
Benjamin Berg
f9b2c7f9c3 virtual-image: Fix driver reading insufficient data
In rare occasions it could happen that the driver was reading
insufficient data. Fix this by using g_input_stream_read_all_async
which will ensure that incomplete data will not be misinterpreted.

This fixes rare test failures seen in fprintd.
2019-12-02 17:04:05 +01:00
Benjamin Berg
4115ae7ced Fix indentation issues using newer uncrustify
Seems like the older uncrustify versions did not find these indentation
issues. Fix them.

Old versions of uncrustify will leave things as is, so this is not a
problem if developers are using an old version of uncrustify.
2019-12-02 17:04:05 +01:00
Benjamin Berg
8cc0fd321f assembling: Use fixed point for image assembly
Using floating point causes architecture dependent results due to
accuracy/rounding differences. It is not hard to switch to fixed point,
and while this does cause quite different rounding errors, the
difference is small.

Fixes: #200
2019-11-28 20:41:45 +00:00
Benjamin Berg
a7541b1f76 tests: Fix endianness issue in test suite
The test suite needs to compare greyscale images and was picking an
undefined byte in the pixel data on big-endian. Select a byte that works
on any endian instead.

See: #200
2019-11-28 20:41:45 +00:00
Marco Trevisan (Treviño)
b9ff75c4e9 fp-print: Set the aligned_data as the data used by the cleanup function
g_variant_new_from_data() allows to destroy some other user_data passed as
parameter that might be different from the aligned_data itself.

But since in this case they match, pass it to be set as g_free parameter
or it won't be free'd.
2019-11-28 21:30:17 +01:00
Marco Trevisan (Treviño)
4447a0d183 ci: Add a test case where we run tests with valgrind 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
545af23536 tests: Use a loop for generating drivers tests and use suites
So we can just run drivers tests with --suite=drivers
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
db905a2048 fp-device: Use g_clear_error instead of check + free 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
712853d1e3 fp-device: Mark user data in FpEnrollProgress as transfer none
The data has its own DestroyNotify set, so while no generic DestroyNotify
exists for generic data, let's make it clear.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
c6298ede72 fp-device: Unref the print once we've notified the progress
When we notify the enroll progress with a print, this needs to be unreffed
once we're done, but this only was happening in case of error.

Since it's not up to the callback function to free it, let's do it at the
end of the function.

As per this, clarify the docs for FpEnrollProgress marking it as transfer
none.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
b1d99e7608 fp-device: Use an autopointer and steal the print when passed
Make it clearer that we're stealing the print when passing it away, instead
of just doing this silently.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
5927a205e3 virtual-image: Also unref the object when closing a the stream
While a stream is closed when completely unreffed, the other way around
isn't true, so always unref the object.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
8c05f3b78c fp-print: Unref print data and get static strings when deserializing 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
92db82e3d4 fp-print: Assert the prints aren't set when initialized 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
f6f689f9cd fp-print: Unref the prints on finalize 2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
5dc3edf07c fp-context: Run dispose on the usb context to deal with circular refs
Ensure that we dispose the USB context before unreffing it, so that it will
release any reference it has and destroy the internal libusb context.
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
71625ec1cf fp-device: Unref the usb device on finalize
Each device adds a ref to the underlying usb device, but it doesn't remove
the reference on finalization.

So clear the object to fix the leak
2019-11-27 21:40:44 +01:00
Marco Trevisan (Treviño)
c9216cf96c tests: Add setup mode to run tests using valgrind
In such case we need to ignore the python errors, so including a suppression
file when using --setup=valgrind.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
53713c0098 tests: Add 'gdb' setup to run tests using gdb
When using --setup=gdb the tests will be running using gdb, however this
as per meson limitation allows only running a test when using verbose mode.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
222c33ec32 virtual-image: Re-run the test using the defined wrapper if any
In case a LIBFPRINT_TEST_WRAPPER is defined, execute again the script using
the same python processor but using the passed wrapper command.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
19a50cfdc3 umockdev-test: Make possible to use a wrapper to run tests
Support LIBFPRINT_TEST_WRAPPER env variable to run tests with a wrapper.
2019-11-27 21:40:43 +01:00
Marco Trevisan (Treviño)
9892eb1c03 fpi-ssm: Make clearer that data is unused in fpi_ssm_usb_transfer_cb 2019-11-27 21:02:20 +01:00
Marco Trevisan (Treviño)
587131a6bd drivers: Use more fpi_ssm_usb_transfer_cb when possible
Replace all the transfer callbacks where we just switch to the next state or
fail with fpi_ssm_usb_transfer_cb.
2019-11-27 21:02:20 +01:00
Marco Trevisan (Treviño)
65d0d5e3e0 fpi-ssm: Add a usb transfer callback with data as weak pointer
Allow to pass a double-pointer to be nullified as the transfer data in order
to mark it as NULL when the transfer is done.

This is useful if we're keeping the transfer around in order to check that
no one is currently running.
2019-11-27 21:02:19 +01:00
Marco Trevisan (Treviño)
2642fc6560 fpi-usb-transfer: Take ownership of the transfer when submitting it
When a transfer is completed, we automatically unref it since we can't
consider it valid anymore since this point.

Update the drivers not to free the transfer after submitting anymore.
2019-11-27 21:02:19 +01:00
Marco Trevisan (Treviño)
a855c0cc79 fpi-ssm: Take ownership of the SSM when completing it
When a machine is completed, we automatically free it since we can't
consider it valid anymore since this point.

Update the drivers not to free the SSM on completion callback anymore.
2019-11-27 21:02:19 +01:00
Marco Trevisan (Treviño)
876924df6a examples: Handle the cases where the print date is not set 2019-11-27 19:14:35 +01:00
Marco Trevisan (Treviño)
519b5acc91 synaptics: Initialize user_id autoptr to NULL 2019-11-27 18:54:21 +01:00
Marco Trevisan (Treviño)
e812653acd synaptics: Use GDate getters to retrieve the DMY values
As per commit 201b5a961 we use g_date_copy() to copy the date, however the
GLib implementation is done assuming that the GDate getters are always used
as the copy function doesn't preserve the original format of the date
(whether is using julian days or dmy), and the synaptics driver access to
the dmy values directly, without using the getter that would recompute the
proper values.
Causing a read error of unset values.

So, to avoid this, just use the g_date_get_* getters to retrieve the day
month and year for for defining the print enroll id.
2019-11-27 18:54:21 +01:00
Marco Trevisan (Treviño)
1b23f0efe1 drivers: Use clearer messages using parameters 2019-11-26 12:18:57 +00:00
Marco Trevisan (Treviño)
f6559ba8b1 fp-device: Support variadic arguments to error functions
Make possible to generate a formatted message when creating an error from
a device, without having save it first.
2019-11-26 12:18:57 +00:00
Marco Trevisan (Treviño)
3b72b925b0 gitlab-ci: Check indentation in an initial check-source stage 2019-11-25 19:08:31 +01:00
Marco Trevisan (Treviño)
15d218a112 fpi-log: Set fp_error as equal to g_critical 2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
0a08a24896 fpi-ssm: Remove any reference to fpi_timeout_add()
This doesn't exist anymore, while fpi_device_add_timeout does exists.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
cca6d3b04b fp-image-device: Use a GObject signal to notify image state changed
This is more GObject-friendly and we have the automatic call of the vfunc if
one is set.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
be367988ae fp-image-device: Add private "fp-image-device-state" property
In this way drivers may get this without having to keep a copy of it
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
ea4da08af0 fp-image-device: Reactivate in idle on deactivation completed
This is the same logic we apply to fp-device by default: any completed
action should trigger the subsequent one when it is finished.
So in case we want reactivate after a deactivation, let's do it in an idle,
after removing the current pending timeout.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
60ad1ab9e3 fp-image-device: Clear the pending activation timeout on finalize 2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
201b5a9614 fp-print: Use g_date_copy
As per previous commit we depend on glib 2.56, we can use this utility
function as well.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
8b270141f3 image-device: Use g_clear_handle_id for timeouts
As per this depend on glib 2.56: it has been released almost 2 years ago,
I suppose we're fine with that.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
ceb62d7617 meson: Avoid repeating the needed glib version multiple times
Just define once and modify its syntax when needed.
Use a more verbose definition for the min/max version (instead of just
join the split version) so that in case we may depend on a specifc glib
micro release during development.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
099fa9f005 meson: Use preferred syntax everywhere
Meson files are normally using 4-spaces to indent and functions use first
parameter on the same line while others at next indentation level, not
following the parenthesis indentation.

So adapt libfprint to follow the meson standard.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
dd7d1baece meson: Use multiline-array for default dirvers listing
It will make reviews and diffs nicer to handle when adding new drivers.
2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
d8efa336e5 fpi-ssm, fp-device: Add missing copyright 2019-11-25 18:59:46 +01:00
Marco Trevisan (Treviño)
76dd4066f3 verify: Ensure we set set the autoptr value to NULL at definition 2019-11-25 18:59:46 +01:00
Benjamin Berg
9b48864c5b print: Ensure xyt struct is not leaked during deserialization
In the unlikely event of an error, the variable may have been leaked.
Fix this by using g_autoptr combined with a g_steal_pointer.
2019-11-25 18:46:14 +01:00
Benjamin Berg
14a41bdd48 print: Free temporary col variable
The variable was leaked during serialization. Free it.
2019-11-25 18:46:14 +01:00
Benjamin Berg
25bc89a4f5 image-device: Remove unused fpi_device_get_current_action call
There is a later call in the function which is sufficient. Simply remove
the first call.
2019-11-25 18:46:14 +01:00
Benjamin Berg
2f0824ab88 upeksonly: Add default clauses to switch statements
This effectively only annotates the code to make it clear that variables
set in the switch are always initialized.
2019-11-25 18:46:14 +01:00
Benjamin Berg
8ba6f4dad2 synaptics: Add an explicit assert on the response
The response must be non-NULL in the function. Add an explicit assert to
appease to static code analysis tools.
2019-11-25 18:46:14 +01:00
Benjamin Berg
ada5d488fa synaptics: Correctly unref pointer array
The pointer arrays were unref'ed using g_ptr_array_free rather than
g_ptr_array_unref from g_clear_pointer. Switch to the correct function.
2019-11-25 18:46:14 +01:00
Benjamin Berg
b16245ad58 elan: Fix switch in change_state
The switch in change_state had a useless break and a useless if clause.
Remove both.
2019-11-25 18:46:14 +01:00
Benjamin Berg
8b28133bee elan: Fix potential leak of dark frame
Dark frames would be leaked, add an explicit free to avoid this.
2019-11-25 18:46:14 +01:00
Benjamin Berg
7a4dd96406 udev-rules: Remove debug spew from udev rules
Some debug output was ending up inside the udev rules. Remove it again.
2019-11-22 17:07:56 +01:00
49 changed files with 918 additions and 694 deletions

View File

@@ -1,5 +1,6 @@
image: fedora:rawhide
stages:
- check-source
- build
- test
- flatpack
@@ -48,8 +49,16 @@ test:
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit
test_indent:
test_valgrind:
stage: test
script:
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES valgrind
- meson -Ddrivers=all . _build
- ninja -C _build
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
test_indent:
stage: check-source
script:
- dnf update -y --nogpgcheck && dnf install -y --nogpgcheck git uncrustify
- scripts/uncrustify.sh --check

View File

@@ -1,21 +1,24 @@
gtk_test_resources = gnome.compile_resources('gtk-test-resources', 'gtk-libfprint-test.gresource.xml',
source_dir : '.',
c_name : 'gtk_test')
gtk_test_resources = gnome.compile_resources('gtk-test-resources',
'gtk-libfprint-test.gresource.xml',
source_dir : '.',
c_name : 'gtk_test')
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))
datadir = join_paths(prefix, get_option('datadir'))
executable('gtk-libfprint-test',
[ 'gtk-libfprint-test.c', gtk_test_resources ],
dependencies: [ libfprint_dep, gtk_dep ],
include_directories: [
root_inc,
],
c_args: [ common_cflags,
'-DPACKAGE_VERSION="' + meson.project_version() + '"' ],
install: true,
install_dir: bindir)
[ 'gtk-libfprint-test.c', gtk_test_resources ],
dependencies: [ libfprint_dep, gtk_dep ],
include_directories: [
root_inc,
],
c_args: [
common_cflags,
'-DPACKAGE_VERSION="' + meson.project_version() + '"'
],
install: true,
install_dir: bindir)
appdata = 'org.freedesktop.libfprint.Demo.appdata.xml'
install_data(appdata,

View File

@@ -215,7 +215,10 @@ fpi_ssm_free
fpi_ssm_start
fpi_ssm_start_subsm
fpi_ssm_next_state
fpi_ssm_next_state_delayed
fpi_ssm_jump_to_state
fpi_ssm_jump_to_state_delayed
fpi_ssm_cancel_delayed_state_change
fpi_ssm_mark_completed
fpi_ssm_mark_failed
fpi_ssm_set_data

View File

@@ -1,14 +1,14 @@
subdir('xml')
private_headers = [
'config.h',
'nbis-helpers.h',
'fprint.h',
'fp_internal.h',
'config.h',
'nbis-helpers.h',
'fprint.h',
'fp_internal.h',
# Subdirectories to ignore
'drivers',
'nbis',
# Subdirectories to ignore
'drivers',
'nbis',
]
html_images = [
@@ -25,20 +25,20 @@ glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
gnome.gtkdoc('libfprint',
main_xml: 'libfprint-docs.xml',
src_dir: join_paths(meson.source_root(), 'libfprint'),
dependencies: libfprint_dep,
content_files: content_files,
expand_content_files: expand_content_files,
scan_args: [
#'--rebuild-sections',
'--ignore-decorators=API_EXPORTED',
'--ignore-headers=' + ' '.join(private_headers),
],
fixxref_args: [
'--html-dir=@0@'.format(docpath),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')),
],
html_assets: html_images,
install: true)
main_xml: 'libfprint-docs.xml',
src_dir: join_paths(meson.source_root(), 'libfprint'),
dependencies: libfprint_dep,
content_files: content_files,
expand_content_files: expand_content_files,
scan_args: [
#'--rebuild-sections',
'--ignore-decorators=API_EXPORTED',
'--ignore-headers=' + ' '.join(private_headers),
],
fixxref_args: [
'--html-dir=@0@'.format(docpath),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')),
],
html_assets: html_images,
install: true)

View File

@@ -7,4 +7,6 @@ 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())
ent_conf.set('PACKAGE_API_VERSION', '1.0')
configure_file(input: 'gtkdocentities.ent.in', output: 'gtkdocentities.ent', configuration: ent_conf)
configure_file(input: 'gtkdocentities.ent.in',
output: 'gtkdocentities.ent',
configuration: ent_conf)

View File

@@ -153,14 +153,19 @@ on_list_completed (FpDevice *dev,
for (i = 0; i < prints->len; ++i)
{
FpPrint * print = prints->pdata[i];
const GDate *date = fp_print_get_enroll_date (print);
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d",
fp_print_get_enroll_date (print));
g_print ("[%d] Print of %s finger for username %s, enrolled "
"on %s. Description: %s\n", i + 1,
g_print ("[%d] Print of %s finger for username %s", i + 1,
finger_to_string (fp_print_get_finger (print)),
fp_print_get_username (print), buf,
fp_print_get_description (print));
fp_print_get_username (print));
if (date)
{
g_date_strftime (buf, G_N_ELEMENTS (buf), "%Y-%m-%d\0", date);
g_print (", enrolled on %s", buf);
}
g_print (". Description: %s\n", fp_print_get_description (print));
}
if (prints->len)

View File

@@ -2,18 +2,18 @@
examples = [ 'enroll', 'verify', 'manage-prints' ]
foreach example: examples
executable(example,
[example + '.c', 'storage.c', 'utilities.c'],
dependencies: [libfprint_dep, glib_dep],
include_directories: [
root_inc,
],
c_args: common_cflags)
[ example + '.c', 'storage.c', 'utilities.c' ],
dependencies: [ libfprint_dep, glib_dep ],
include_directories: [
root_inc,
],
c_args: common_cflags)
endforeach
executable('cpp-test',
'cpp-test.cpp',
dependencies: libfprint_dep,
include_directories: [
root_inc,
],
c_args: common_cflags)
'cpp-test.cpp',
dependencies: libfprint_dep,
include_directories: [
root_inc,
],
c_args: common_cflags)

View File

@@ -127,9 +127,14 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
if (fp_print_get_finger (print) == verify_data->finger &&
g_strcmp0 (fp_print_get_username (print), g_get_user_name ()) == 0)
{
if (!verify_print ||
(g_date_compare (fp_print_get_enroll_date (print),
fp_print_get_enroll_date (verify_print)) >= 0))
const GDate *verify_print_date = NULL;
const GDate *print_date = fp_print_get_enroll_date (print);
if (verify_print)
verify_print_date = fp_print_get_enroll_date (verify_print);
if (!verify_print || !print_date || !verify_print_date ||
g_date_compare (print_date, verify_print_date) >= 0)
verify_print = print;
}
}
@@ -182,7 +187,7 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
{
g_print ("Loading previously enrolled %s finger data...\n",
finger_to_string (verify_data->finger));
g_autoptr(FpPrint) verify_print;
g_autoptr(FpPrint) verify_print = NULL;
verify_print = print_data_load (dev, verify_data->finger);

View File

@@ -116,18 +116,6 @@ stub_capture_stop_cb (FpImageDevice *dev, GError *error,
}
}
/* check that read succeeded but ignore all data */
static void
generic_ignore_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state (transfer->ssm);
}
static void
generic_write_regv_cb (FpImageDevice *dev, GError *error,
void *user_data)
@@ -154,8 +142,7 @@ generic_read_ignore_data (FpiSsm *ssm, FpDevice *dev,
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
generic_ignore_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
/****** FINGER PRESENCE DETECTION ******/
@@ -238,7 +225,6 @@ finger_det_reqs_cb (FpImageDevice *dev, GError *error,
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -683,7 +669,6 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_strip_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
}
;
@@ -710,7 +695,6 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
start_finger_detection (dev);
}
fpi_ssm_free (ssm);
}
static void
@@ -774,7 +758,6 @@ activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
if (!error)
start_finger_detection (dev);
fpi_ssm_free (ssm);
}
static void

View File

@@ -126,7 +126,6 @@ read_regs_rq_cb (FpImageDevice *dev, GError *error, void *user_data)
fpi_usb_transfer_fill_bulk (transfer, EP_IN, READ_REGS_LEN);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
read_regs_data_cb, rdata);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -183,19 +182,6 @@ generic_write_regv_cb (FpImageDevice *dev, GError *error,
fpi_ssm_mark_failed (ssm, error);
}
/* check that read succeeded but ignore all data */
static void
generic_ignore_data_cb (FpiUsbTransfer *transfer, FpDevice *dev,
gpointer user_data, GError *error)
{
FpiSsm *ssm = transfer->ssm;
if (error)
fpi_ssm_mark_failed (ssm, error);
else
fpi_ssm_next_state (ssm);
}
/* read the specified number of bytes from the IN endpoint but throw them
* away, then increment the SSM */
static void
@@ -209,8 +195,7 @@ generic_read_ignore_data (FpiSsm *ssm, FpDevice *dev,
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_bulk (transfer, EP_IN, bytes);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
generic_ignore_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
/****** IMAGE PROCESSING ******/
@@ -315,7 +300,6 @@ finger_det_reqs_cb (FpImageDevice *dev, GError *error,
fpi_usb_transfer_fill_bulk (transfer, EP_IN, FINGER_DETECTION_LEN);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -547,7 +531,6 @@ capture_run_state (FpiSsm *ssm, FpDevice *device)
fpi_usb_transfer_fill_bulk (transfer, EP_IN, STRIP_CAPTURE_LEN);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_strip_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
}
}
@@ -575,7 +558,6 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
start_finger_detection (dev);
}
fpi_ssm_free (ssm);
}
static void
@@ -806,7 +788,6 @@ activate_sm_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
if (!error)
start_finger_detection (FP_IMAGE_DEVICE (dev));
fpi_ssm_free (ssm);
}
static void

View File

@@ -134,7 +134,6 @@ finger_det_reqs_cb (FpiUsbTransfer *t, FpDevice *device,
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -157,7 +156,6 @@ start_finger_detection (FpImageDevice *dev)
sizeof (finger_det_reqs), NULL);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_reqs_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
/****** CAPTURE ******/
@@ -218,16 +216,6 @@ process_strip_data (FpiSsm *ssm, FpImageDevice *dev,
return TRUE;
}
static void
capture_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void
capture_set_idle_reqs_cb (FpiUsbTransfer *transfer,
FpDevice *device, gpointer user_data,
@@ -334,8 +322,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_reqs_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
break;
@@ -347,7 +334,6 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
break;
@@ -363,7 +349,6 @@ capture_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_set_idle_reqs_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
break;
}
@@ -391,7 +376,6 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
start_finger_detection (dev);
}
fpi_ssm_free (ssm);
}
static void
@@ -436,36 +420,13 @@ enum activate_states {
ACTIVATE_NUM_STATES,
};
static void
init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void
init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
/* TODO: use calibration table, datasheet is rather terse on that
* need more info for implementation */
static void
calibrate_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
fpi_ssm_usb_transfer_cb (transfer, device, user_data, error);
}
static void
@@ -482,8 +443,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
init_reqs_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
break;
@@ -494,8 +454,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
fpi_usb_transfer_fill_bulk (transfer, EP_IN, AES2550_EP_IN_BUF_SIZE);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
init_read_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
break;
@@ -509,8 +468,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
init_reqs_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
break;
@@ -522,7 +480,6 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
calibrate_read_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
break;
}
@@ -537,7 +494,6 @@ activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
if (!error)
start_finger_detection (dev);
fpi_ssm_free (ssm);
}
static void

View File

@@ -142,7 +142,6 @@ do_capture (FpImageDevice *dev)
fpi_usb_transfer_submit (priv->img_trf, 0,
fpi_device_get_cancellable (FP_DEVICE (dev)),
img_cb, NULL);
fpi_usb_transfer_unref (priv->img_trf);
}
static void

View File

@@ -88,7 +88,6 @@ do_write_regv (FpImageDevice *dev, struct write_regv_data *wdata, int upper_boun
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
write_regv_trf_complete, wdata);
fpi_usb_transfer_unref (transfer);
}
/* write the next batch of registers to be written, or if there are no more,

View File

@@ -68,7 +68,6 @@ aesX660_send_cmd_timeout (FpiSsm *ssm,
cmd_len, NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, timeout, NULL, callback, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -100,17 +99,6 @@ aesX660_read_response (FpiSsm *ssm,
transfer->ssm = ssm;
transfer->short_is_error = short_is_error;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, cancel, callback, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
aesX660_send_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void
@@ -131,7 +119,9 @@ aesX660_read_calibrate_data_cb (FpiUsbTransfer *transfer,
fp_dbg ("Bogus calibrate response: %.2x\n", data[0]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus calibrate response"));
"Bogus calibrate "
"response: %.2x",
data[0]));
return;
}
@@ -175,7 +165,8 @@ finger_det_read_fd_data_cb (FpiUsbTransfer *transfer,
fp_dbg ("Bogus FD response: %.2x\n", data[0]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus FD response"));
"Bogus FD response %.2x",
data[0]));
return;
}
@@ -212,7 +203,6 @@ finger_det_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
fp_dbg ("Finger detection completed");
fpi_image_device_report_finger_status (dev, TRUE);
fpi_ssm_free (ssm);
if (priv->deactivating)
{
@@ -238,12 +228,12 @@ finger_det_run_state (FpiSsm *ssm, FpDevice *dev)
{
case FINGER_DET_SEND_LED_CMD:
aesX660_send_cmd (ssm, dev, led_blink_cmd, sizeof (led_blink_cmd),
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case FINGER_DET_SEND_FD_CMD:
aesX660_send_cmd_timeout (ssm, dev, wait_for_finger_cmd, sizeof (wait_for_finger_cmd),
aesX660_send_cmd_cb, 0);
fpi_ssm_usb_transfer_cb, 0);
break;
case FINGER_DET_READ_FD_DATA:
@@ -433,14 +423,14 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev)
{
case CAPTURE_SEND_LED_CMD:
aesX660_send_cmd (ssm, _dev, led_solid_cmd, sizeof (led_solid_cmd),
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case CAPTURE_SEND_CAPTURE_CMD:
g_byte_array_set_size (priv->stripe_packet, 0);
aesX660_send_cmd (ssm, _dev, cls->start_imaging_cmd,
cls->start_imaging_cmd_len,
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case CAPTURE_READ_STRIPE_DATA:
@@ -463,7 +453,6 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *device, GError *error)
FpiDeviceAesX660Private *priv = fpi_device_aes_x660_get_instance_private (self);
fp_dbg ("Capture completed");
fpi_ssm_free (ssm);
if (priv->deactivating)
{
@@ -538,7 +527,8 @@ activate_read_id_cb (FpiUsbTransfer *transfer, FpDevice *device,
fp_dbg ("Bogus read ID response: %.2x\n", data[AESX660_RESPONSE_TYPE_OFFSET]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus read ID response"));
"Bogus read ID response %.2x",
data[AESX660_RESPONSE_TYPE_OFFSET]));
return;
}
@@ -565,7 +555,8 @@ activate_read_id_cb (FpiUsbTransfer *transfer, FpDevice *device,
fp_dbg ("Failed to init device! init status: %.2x\n", data[7]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Failed to init device"));
"Failed to init device %.2x",
data[7]));
break;
}
}
@@ -594,7 +585,8 @@ activate_read_init_cb (FpiUsbTransfer *transfer, FpDevice *device,
data[3]);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Bogus read init response"));
"Bogus read init response: "
"%.2x %.2x", data[0], data[3]));
return;
}
priv->init_cmd_idx++;
@@ -623,13 +615,13 @@ activate_run_state (FpiSsm *ssm, FpDevice *_dev)
priv->init_seq_idx = 0;
fp_dbg ("Activate: set idle\n");
aesX660_send_cmd (ssm, _dev, set_idle_cmd, sizeof (set_idle_cmd),
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_SEND_READ_ID_CMD:
fp_dbg ("Activate: read ID\n");
aesX660_send_cmd (ssm, _dev, read_id_cmd, sizeof (read_id_cmd),
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_READ_ID:
@@ -643,7 +635,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *_dev)
aesX660_send_cmd (ssm, _dev,
priv->init_seq[priv->init_cmd_idx].cmd,
priv->init_seq[priv->init_cmd_idx].len,
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_READ_INIT_RESPONSE:
@@ -653,7 +645,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *_dev)
case ACTIVATE_SEND_CALIBRATE_CMD:
aesX660_send_cmd (ssm, _dev, calibrate_cmd, sizeof (calibrate_cmd),
aesX660_send_cmd_cb);
fpi_ssm_usb_transfer_cb);
break;
case ACTIVATE_READ_CALIBRATE_DATA:
@@ -666,7 +658,6 @@ static void
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
fpi_image_device_activate_complete (FP_IMAGE_DEVICE (_dev), error);
fpi_ssm_free (ssm);
if (!error)
start_finger_detection (FP_IMAGE_DEVICE (_dev));

View File

@@ -223,6 +223,7 @@ elan_save_img_frame (FpiDeviceElan *elandev)
{
fp_dbg
("frame darker than background; finger present during calibration?");
g_free (frame);
return -1;
}
@@ -405,7 +406,6 @@ elan_cmd_read (FpiSsm *ssm, FpDevice *dev)
cancellable = fpi_device_get_cancellable (dev);
fpi_usb_transfer_submit (transfer, self->cmd_timeout, cancellable, elan_cmd_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -448,7 +448,6 @@ elan_run_cmd (FpiSsm *ssm,
cancellable,
elan_cmd_cb,
NULL);
fpi_usb_transfer_unref (transfer);
}
enum stop_capture_states {
@@ -478,7 +477,6 @@ stop_capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
G_DEBUG_HERE ();
fpi_ssm_free (ssm);
/* The device is inactive at this point. */
self->dev_state = FP_IMAGE_DEVICE_STATE_INACTIVE;
@@ -605,7 +603,6 @@ capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
fpi_image_device_session_error (dev, error);
}
fpi_ssm_free (ssm);
}
static void
@@ -752,15 +749,10 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
}
else
{
GSource *timeout;
if (self->calib_status == 0x00 &&
self->last_read[0] == 0x01)
self->calib_status = 0x01;
timeout = fpi_device_add_timeout (dev, 50,
fpi_ssm_next_state_timeout_cb,
ssm);
g_source_set_name (timeout, "calibrate_run_state");
fpi_ssm_next_state_delayed (ssm, 50, NULL);
}
break;
@@ -788,7 +780,6 @@ calibrate_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
elan_capture (dev);
}
fpi_ssm_free (ssm);
}
static void
@@ -885,7 +876,6 @@ activate_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
fpi_image_device_activate_complete (idev, error);
fpi_ssm_free (ssm);
}
static void
@@ -974,8 +964,6 @@ elan_change_state (FpImageDevice *idev)
switch (next_state)
{
break;
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON:
/* activation completed or another enroll stage started */
elan_calibrate (dev);
@@ -987,9 +975,8 @@ elan_change_state (FpImageDevice *idev)
case FP_IMAGE_DEVICE_STATE_INACTIVE:
case FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF:
if (self->dev_state != FP_IMAGE_DEVICE_STATE_INACTIVE ||
self->dev_state != FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF)
elan_stop_capture (dev);
elan_stop_capture (dev);
break;
}
}
@@ -1028,7 +1015,7 @@ dev_change_state (FpImageDevice *dev, FpImageDeviceState state)
self->dev_state_next = state;
timeout = fpi_device_add_timeout (FP_DEVICE (dev), 10,
elan_change_state_async,
NULL);
NULL, NULL);
name = g_strdup_printf ("dev_change_state to %d", state);
g_source_set_name (timeout, name);

View File

@@ -710,7 +710,6 @@ async_tx (FpDevice *dev, unsigned int ep, void *cb,
transfer->ssm = ssm;
fpi_usb_transfer_fill_bulk_full (transfer, ep, buffer, length, NULL);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref (transfer);
}
@@ -789,7 +788,6 @@ m_exit_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
else
fp_dbg ("The device is now in idle state");
fpi_image_device_deactivate_complete (idev, error);
fpi_ssm_free (ssm);
}
static void
@@ -911,7 +909,6 @@ m_capture_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
g_error_free (error);
}
}
fpi_ssm_free (ssm);
if (self->is_active == TRUE)
{
@@ -1061,7 +1058,6 @@ m_finger_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
self->is_active = FALSE;
}
fpi_ssm_free (ssm);
}
static void
@@ -1265,7 +1261,6 @@ m_tunevrb_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
if (!self->is_active)
m_exit_start (idev);
fpi_ssm_free (ssm);
}
/*
@@ -1409,7 +1404,6 @@ m_tunedc_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
if (!self->is_active)
m_exit_start (idev);
fpi_ssm_free (ssm);
}
static void
@@ -1543,7 +1537,6 @@ m_init_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
reset_param (FPI_DEVICE_ETES603 (dev));
fpi_image_device_session_error (idev, error);
}
fpi_ssm_free (ssm);
}
static void

View File

@@ -137,7 +137,8 @@ cmd_recieve_cb (FpiUsbTransfer *transfer,
fp_warn ("Received General Error %d from the sensor", (guint) err);
fpi_ssm_mark_failed (transfer->ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Received general error from device"));
"Received general error %u from device",
(guint) err));
//fpi_ssm_jump_to_state (transfer->ssm, fpi_ssm_get_cur_state (transfer->ssm));
return;
}
@@ -204,7 +205,7 @@ static void
synaptics_cmd_run_state (FpiSsm *ssm,
FpDevice *dev)
{
g_autoptr(FpiUsbTransfer) transfer = NULL;
FpiUsbTransfer *transfer;
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (dev);
switch (fpi_ssm_get_cur_state (ssm))
@@ -218,7 +219,7 @@ synaptics_cmd_run_state (FpiSsm *ssm,
NULL,
fpi_ssm_usb_transfer_cb,
NULL);
g_clear_pointer (&self->cmd_pending_transfer, fpi_usb_transfer_unref);
self->cmd_pending_transfer = NULL;
}
else
{
@@ -289,7 +290,6 @@ cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
}
self->cmd_complete_on_removal = FALSE;
g_clear_pointer (&self->cmd_complete_error, g_error_free);
fpi_ssm_free (ssm);
}
static void
@@ -317,7 +317,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
gssize payload_len,
SynCmdMsgCallback callback)
{
g_autoptr(FpiUsbTransfer) transfer = NULL;
FpiUsbTransfer *transfer;
guint8 real_seq_num;
gint msg_len;
gint res;
@@ -447,7 +447,7 @@ list_msg_cb (FpiDeviceSynaptics *self,
if (error)
{
g_clear_pointer (&self->list_result, g_ptr_array_free);
g_clear_pointer (&self->list_result, g_ptr_array_unref);
fpi_device_list_complete (FP_DEVICE (self), NULL, error);
return;
}
@@ -468,11 +468,12 @@ list_msg_cb (FpiDeviceSynaptics *self,
else
{
fp_info ("Failed to query enrolled users: %d", resp->result);
g_clear_pointer (&self->list_result, g_ptr_array_free);
g_clear_pointer (&self->list_result, g_ptr_array_unref);
fpi_device_list_complete (FP_DEVICE (self),
NULL,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Failed to query enrolled users"));
"Failed to query enrolled users: %d",
resp->result));
}
break;
@@ -604,6 +605,8 @@ verify_msg_cb (FpiDeviceSynaptics *self,
return;
}
g_assert (resp != NULL);
verify_resp = &resp->response.verify_resp;
switch (resp->response_id)
@@ -768,7 +771,8 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
fpi_device_enroll_complete (device,
NULL,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Enrollment failed"));
"Enrollment failed (%d)",
resp->result));
}
break;
}
@@ -798,7 +802,7 @@ enroll (FpDevice *device)
GVariant *uid = NULL;
const gchar *username;
guint finger;
g_autofree gchar *user_id;
g_autofree gchar *user_id = NULL;
gssize user_id_len;
g_autofree guint8 *payload = NULL;
const GDate *date;
@@ -812,9 +816,9 @@ enroll (FpDevice *device)
date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = date->year;
m = date->month;
d = date->day;
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
else
{
@@ -946,7 +950,8 @@ dev_probe (FpDevice *device)
{
FpiDeviceSynaptics *self = FPI_DEVICE_SYNAPTICS (device);
GUsbDevice *usb_dev;
FpiUsbTransfer *transfer;
g_autoptr(FpiUsbTransfer) transfer = NULL;
FpiByteReader reader;
GError *error = NULL;
guint16 status;
@@ -965,10 +970,7 @@ dev_probe (FpDevice *device)
}
if (!g_usb_device_reset (fpi_device_get_usb_device (device), &error))
{
fpi_device_probe_complete (device, NULL, NULL, error);
return;
}
goto err_close;
if (!g_usb_device_claim_interface (fpi_device_get_usb_device (device), 0, 0, &error))
goto err_close;
@@ -980,9 +982,8 @@ dev_probe (FpDevice *device)
transfer->buffer[0] = SENSOR_CMD_GET_VERSION;
if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error))
goto err_close;
fpi_usb_transfer_unref (transfer);
g_clear_pointer (&transfer, fpi_usb_transfer_unref);
transfer = fpi_usb_transfer_new (device);
fpi_usb_transfer_fill_bulk (transfer, USB_EP_REPLY, 40);
if (!fpi_usb_transfer_submit_sync (transfer, 1000, &error))
@@ -1035,7 +1036,6 @@ dev_probe (FpDevice *device)
fp_dbg ("Target: %d", self->mis_version.target);
fp_dbg ("Product: %d", self->mis_version.product);
fpi_usb_transfer_unref (transfer);
/* We need at least firmware version 10.1, and for 10.1 build 2989158 */
if (self->mis_version.version_major < 10 ||
@@ -1050,7 +1050,11 @@ dev_probe (FpDevice *device)
self->mis_version.build_num);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Unsupported firmware version");
"Unsupported firmware version "
"(%d.%d with build number %d)",
self->mis_version.version_major,
self->mis_version.version_minor,
self->mis_version.build_num);
goto err_close;
}
@@ -1118,7 +1122,7 @@ fps_deinit_cb (FpiDeviceSynaptics *self,
case BMKT_RSP_POWER_DOWN_FAIL:
fp_info ("Failed to go to power down mode: %d", resp->result);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Power down failed");
"Power down failed: %d", resp->result);
break;
}

View File

@@ -635,7 +635,6 @@ write_regs_iterate (struct write_regs_data *wrdata)
transfer->short_is_error = TRUE;
transfer->ssm = wrdata->ssm;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, write_regs_cb, NULL);
fpi_usb_transfer_unref (transfer);
transfer->buffer[0] = regwrite->value;
}
@@ -657,17 +656,6 @@ sm_write_regs (FpiSsm *ssm,
write_regs_iterate (wrdata);
}
static void
sm_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state (transfer->ssm);
}
static void
sm_write_reg (FpiSsm *ssm,
FpImageDevice *dev,
@@ -687,8 +675,8 @@ sm_write_reg (FpiSsm *ssm,
1);
transfer->short_is_error = TRUE;
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_write_reg_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
transfer->buffer[0] = value;
}
@@ -737,7 +725,6 @@ sm_read_reg (FpiSsm *ssm,
NULL,
sm_read_reg_cb,
NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -782,7 +769,6 @@ sm_await_intr (FpiSsm *ssm,
fpi_device_get_cancellable (FP_DEVICE (dev)),
sm_await_intr_cb,
NULL);
fpi_usb_transfer_unref (transfer);
}
/***** AWAIT FINGER *****/
@@ -1249,6 +1235,9 @@ loopsm_run_state (FpiSsm *ssm, FpDevice *_dev)
awfsm_1000_run_state,
AWFSM_1000_NUM_STATES);
break;
default:
g_assert_not_reached ();
}
fpi_ssm_start_subsm (ssm, awfsm);
}
@@ -1290,6 +1279,9 @@ loopsm_run_state (FpiSsm *ssm, FpDevice *_dev)
capsm_1001_run_state,
CAPSM_1001_NUM_STATES);
break;
default:
g_assert_not_reached ();
}
fpi_ssm_start_subsm (ssm, capsm);
break;
@@ -1318,6 +1310,9 @@ loopsm_run_state (FpiSsm *ssm, FpDevice *_dev)
deinitsm_1001_run_state,
DEINITSM_1001_NUM_STATES);
break;
default:
g_assert_not_reached ();
}
self->capturing = FALSE;
fpi_ssm_start_subsm (ssm, deinitsm);
@@ -1371,7 +1366,6 @@ loopsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
FpiDeviceUpeksonly *self = FPI_DEVICE_UPEKSONLY (_dev);
fpi_ssm_free (ssm);
if (self->deactivating)
{
@@ -1392,7 +1386,6 @@ initsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
FpiDeviceUpeksonly *self = FPI_DEVICE_UPEKSONLY (_dev);
fpi_ssm_free (ssm);
fpi_image_device_activate_complete (dev, error);
if (error)
return;
@@ -1412,7 +1405,6 @@ dev_activate (FpImageDevice *dev)
self->deactivating = FALSE;
self->capturing = FALSE;
self->img_transfers = g_ptr_array_new_full (NUM_BULK_TRANSFERS, (GDestroyNotify) fpi_usb_transfer_unref);
self->num_flying = 0;
for (i = 0; i < self->img_transfers->len; i++)
@@ -1441,6 +1433,9 @@ dev_activate (FpImageDevice *dev)
ssm = fpi_ssm_new (FP_DEVICE (dev), initsm_1001_run_state,
INITSM_1001_NUM_STATES);
break;
default:
g_assert_not_reached ();
}
fpi_ssm_start (ssm, initsm_complete);
}

View File

@@ -128,7 +128,6 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
write_init_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
break;
@@ -142,7 +141,6 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
read_init_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
break;
}
@@ -157,7 +155,6 @@ activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
if (!error)
start_finger_detection (dev);
fpi_ssm_free (ssm);
}
@@ -226,7 +223,6 @@ finger_det_cmd_cb (FpiUsbTransfer *t, FpDevice *device,
IMAGE_SIZE);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -250,7 +246,6 @@ start_finger_detection (FpImageDevice *dev)
UPEKTC_CMD_LEN, NULL);
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
finger_det_cmd_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
/****** CAPTURE ******/
@@ -261,16 +256,6 @@ enum capture_states {
CAPTURE_NUM_STATES,
};
static void
capture_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void
capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
@@ -309,8 +294,7 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev)
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_cmd_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
break;
@@ -324,7 +308,6 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
capture_read_data_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
break;
}
@@ -345,7 +328,6 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
else
start_finger_detection (dev);
fpi_ssm_free (ssm);
}
static void

View File

@@ -100,7 +100,6 @@ upektc_img_submit_req (FpiSsm *ssm,
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -120,7 +119,6 @@ upektc_img_read_data (FpiSsm *ssm,
NULL);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL, cb, NULL);
fpi_usb_transfer_unref (transfer);
}
/****** CAPTURE ******/
@@ -389,7 +387,6 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error_arg)
g_autoptr(GError) error = error_arg;
fpi_ssm_free (ssm);
/* Note: We assume that the error is a cancellation in the deactivation case */
if (self->deactivating)
@@ -470,7 +467,6 @@ deactivate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (_dev);
fp_dbg ("Deactivate completed");
fpi_ssm_free (ssm);
self->deactivating = FALSE;
fpi_image_device_deactivate_complete (dev, error);
@@ -505,16 +501,6 @@ enum activate_states {
ACTIVATE_NUM_STATES,
};
static void
init_reqs_ctrl_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (!error)
fpi_ssm_next_state (transfer->ssm);
else
fpi_ssm_mark_failed (transfer->ssm, error);
}
static void
init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
@@ -558,8 +544,7 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->buffer[0] = '\0';
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
init_reqs_ctrl_cb, NULL);
fpi_usb_transfer_unref (transfer);
fpi_ssm_usb_transfer_cb, NULL);
}
break;
@@ -601,7 +586,6 @@ activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
fpi_ssm_free (ssm);
fpi_image_device_activate_complete (dev, error);
if (!error)

View File

@@ -226,7 +226,6 @@ busy_ack_retry_read (FpDevice *device, struct read_msg_data *udata)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, busy_ack_sent_cb, udata);
fpi_usb_transfer_unref (transfer);
}
/* Returns 0 if message was handled, 1 if it was a device-busy message, and
@@ -288,7 +287,7 @@ __handle_incoming_msg (FpDevice *device,
{
fp_warn ("cmd response too short (%d)", len);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"CMD response too short");
"CMD response too short (%d)", len);
goto err;
}
if (innerbuf[0] != 0x28)
@@ -371,7 +370,8 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
fp_err ("async msg read too short (%d)",
(gint) transfer->actual_length);
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Packet from device was too short");
"Packet from device was too short (%lu)",
transfer->actual_length);
goto err;
}
@@ -415,7 +415,6 @@ read_msg_cb (FpiUsbTransfer *transfer, FpDevice *device,
fpi_usb_transfer_submit (etransfer, TIMEOUT,
NULL,
read_msg_extend_cb, udata);
fpi_usb_transfer_unref (etransfer);
return;
}
@@ -441,7 +440,6 @@ __read_msg_async (FpDevice *device, struct read_msg_data *udata)
fpi_usb_transfer_fill_bulk_full (transfer, EP_IN, udata->buffer, udata->buflen, NULL);
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, read_msg_cb, udata);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -675,7 +673,6 @@ initsm_send_msg28_handler (FpiSsm *ssm,
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -696,7 +693,6 @@ initsm_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
case READ_MSG03:
@@ -708,7 +704,6 @@ initsm_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
case READ_MSG05:
@@ -798,7 +793,8 @@ read_msg01_cb (FpDevice *dev, enum read_msg_type type,
{
fp_err ("expected seq=1, got %x", seq);
fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"Got wrong sequence number"));
"Got wrong sequence number (%x)",
seq));
return;
}
@@ -818,7 +814,6 @@ deinitsm_state_handler (FpiSsm *ssm, FpDevice *dev)
transfer->short_is_error = TRUE;
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
case READ_MSG01:;
@@ -951,7 +946,6 @@ enroll_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
case READ_ENROLL_MSG28:;
@@ -988,7 +982,6 @@ enroll_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
fp_warn ("Error deinitializing: %s", error->message);
fpi_device_enroll_complete (dev, data->print, data->error);
fpi_ssm_free (ssm);
}
static void
@@ -1204,7 +1197,6 @@ enroll_iterate (FpDevice *dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, enroll_iterate_cmd_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -1215,7 +1207,6 @@ enroll_started (FpiSsm *ssm, FpDevice *dev, GError *error)
else
enroll_iterate (dev);
fpi_ssm_free (ssm);
}
static void
@@ -1254,7 +1245,6 @@ verify_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
fp_warn ("Error deinitializing: %s", error->message);
fpi_device_verify_complete (dev, data->res, NULL, data->error);
fpi_ssm_free (ssm);
}
static void
@@ -1320,7 +1310,6 @@ verify_start_sm_run_state (FpiSsm *ssm, FpDevice *dev)
transfer->short_is_error = TRUE;
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, fpi_ssm_usb_transfer_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
}
@@ -1520,7 +1509,6 @@ verify_iterate (FpDevice *dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, TIMEOUT, NULL, verify_wr2800_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
}
@@ -1538,7 +1526,6 @@ verify_started (FpiSsm *ssm, FpDevice *dev, GError *error)
upekdev->first_verify_iteration = TRUE;
verify_iterate (dev);
fpi_ssm_free (ssm);
}
static void

View File

@@ -175,13 +175,12 @@ write_regs (FpImageDevice *dev, uint16_t first_reg,
transfer->short_is_error = TRUE;
fpi_usb_transfer_fill_control (transfer,
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
G_USB_DEVICE_REQUEST_TYPE_STANDARD,
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
G_USB_DEVICE_RECIPIENT_DEVICE,
USB_RQ, first_reg, 0,
num_regs);
memcpy (transfer->buffer, values, num_regs);
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, callback, user_data);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -203,11 +202,10 @@ read_regs (FpImageDevice *dev, uint16_t first_reg,
fpi_usb_transfer_fill_control (transfer,
G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
G_USB_DEVICE_REQUEST_TYPE_STANDARD,
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
G_USB_DEVICE_RECIPIENT_DEVICE,
USB_RQ, first_reg, 0, num_regs);
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, callback, user_data);
fpi_usb_transfer_unref (transfer);
}
/*
@@ -365,7 +363,6 @@ start_irq_handler (FpImageDevice *dev)
EP_INTR,
IRQ_LENGTH);
fpi_usb_transfer_submit (transfer, 0, self->irq_cancellable, irq_handler, NULL);
fpi_usb_transfer_unref (transfer);
}
static void
@@ -789,7 +786,6 @@ imaging_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
{
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
fpi_ssm_free (ssm);
/* Report error before exiting imaging loop - the error handler
* can request state change, which needs to be postponed to end of
@@ -833,26 +829,6 @@ enum rebootpwr_states {
REBOOTPWR_NUM_STATES,
};
static void
rebootpwr_pause_cb (FpDevice *dev,
void *data)
{
FpiSsm *ssm = data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (!--self->rebootpwr_ctr)
{
fp_err ("could not reboot device power");
fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR,
"Could not reboot device"));
}
else
{
fpi_ssm_jump_to_state (ssm, REBOOTPWR_GET_HWSTAT);
}
}
static void
rebootpwr_run_state (FpiSsm *ssm, FpDevice *_dev)
{
@@ -879,7 +855,17 @@ rebootpwr_run_state (FpiSsm *ssm, FpDevice *_dev)
break;
case REBOOTPWR_PAUSE:
fpi_device_add_timeout (_dev, 10, rebootpwr_pause_cb, ssm);
if (!--self->rebootpwr_ctr)
{
fp_err ("could not reboot device power");
fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR,
"Could not reboot device"));
}
else
{
fpi_ssm_jump_to_state_delayed (ssm, 10, REBOOTPWR_GET_HWSTAT, NULL);
}
break;
}
}
@@ -920,30 +906,6 @@ enum powerup_states {
POWERUP_NUM_STATES,
};
static void
powerup_pause_cb (FpDevice *dev,
void *data)
{
FpiSsm *ssm = data;
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (dev);
if (!--self->powerup_ctr)
{
fp_err ("could not power device up");
fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"could not power device up"));
}
else if (!self->profile->auth_cr)
{
fpi_ssm_jump_to_state (ssm, POWERUP_SET_HWSTAT);
}
else
{
fpi_ssm_next_state (ssm);
}
}
static void
powerup_run_state (FpiSsm *ssm, FpDevice *_dev)
{
@@ -975,7 +937,21 @@ powerup_run_state (FpiSsm *ssm, FpDevice *_dev)
break;
case POWERUP_PAUSE:
fpi_device_add_timeout (_dev, 10, powerup_pause_cb, ssm);
if (!--self->powerup_ctr)
{
fp_err ("could not power device up");
fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"could not power device up"));
}
else if (!self->profile->auth_cr)
{
fpi_ssm_jump_to_state_delayed (ssm, POWERUP_SET_HWSTAT, 10, NULL);
}
else
{
fpi_ssm_next_state_delayed (ssm, 10, NULL);
}
break;
case POWERUP_CHALLENGE_RESPONSE:
@@ -1134,7 +1110,7 @@ init_run_state (FpiSsm *ssm, FpDevice *_dev)
self->scanpwr_irq_timeout = fpi_device_add_timeout (_dev,
300,
init_scanpwr_timeout,
ssm);
ssm, NULL);
break;
case INIT_DONE:

View File

@@ -76,16 +76,6 @@ enum v5s_cmd {
/***** REGISTER I/O *****/
static void
sm_write_reg_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state (transfer->ssm);
}
static void
sm_write_reg (FpiSsm *ssm,
FpDevice *dev,
@@ -101,19 +91,8 @@ sm_write_reg (FpiSsm *ssm,
G_USB_DEVICE_RECIPIENT_DEVICE,
reg, value, 0, 0);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_write_reg_cb,
NULL);
fpi_usb_transfer_unref (transfer);
}
static void
sm_exec_cmd_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error)
{
if (error)
fpi_ssm_mark_failed (transfer->ssm, error);
else
fpi_ssm_next_state (transfer->ssm);
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
}
static void
@@ -131,9 +110,8 @@ sm_exec_cmd (FpiSsm *ssm,
G_USB_DEVICE_RECIPIENT_DEVICE,
cmd, param, 0, 0);
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, sm_exec_cmd_cb,
NULL);
fpi_usb_transfer_unref (transfer);
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL,
fpi_ssm_usb_transfer_cb, NULL);
}
/***** FINGER DETECTION *****/
@@ -227,7 +205,6 @@ capture_iterate (FpiSsm *ssm,
NULL);
fpi_usb_transfer_submit (transfer, CTRL_TIMEOUT, NULL, capture_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
@@ -301,7 +278,6 @@ loopsm_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
FpImageDevice *imgdev = FP_IMAGE_DEVICE (dev);
FpDeviceVcom5s *self = FPI_DEVICE_VCOM5S (dev);
fpi_ssm_free (ssm);
g_object_unref (self->capture_img);
self->capture_img = NULL;
self->loop_running = FALSE;

View File

@@ -56,7 +56,6 @@ async_write (FpiSsm *ssm,
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
async_write_callback, NULL);
fpi_usb_transfer_unref (transfer);
}
/* Callback for async_read */
@@ -108,7 +107,6 @@ async_read (FpiSsm *ssm,
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
async_read_callback, NULL);
fpi_usb_transfer_unref (transfer);
}
/* Callback for async_abort */
@@ -160,7 +158,6 @@ async_abort (FpDevice *dev, FpiSsm *ssm, int ep)
fpi_usb_transfer_submit (transfer, VFS_USB_ABORT_TIMEOUT, NULL,
async_abort_callback, NULL);
fpi_usb_transfer_unref (transfer);
}
/* Image processing functions */
@@ -482,16 +479,6 @@ receive_callback (FpiUsbTransfer *transfer, FpDevice *device,
}
}
/* SSM stub to prepare device to another scan after orange light was on */
static void
another_scan (FpDevice *dev,
void *data)
{
FpiSsm *ssm = data;
fpi_ssm_jump_to_state (ssm, SSM_TURN_ON);
}
/* Main SSM loop */
static void
activate_ssm (FpiSsm *ssm, FpDevice *dev)
@@ -564,7 +551,6 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
0,
fpi_device_get_cancellable (dev),
interrupt_callback, NULL);
fpi_usb_transfer_unref (transfer);
/* I've put it here to be sure that data is cleared */
clear_data (self);
@@ -614,7 +600,6 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, VFS_USB_TIMEOUT, NULL,
receive_callback, NULL);
fpi_usb_transfer_unref (transfer);
break;
}
@@ -623,8 +608,7 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
clear_data (self);
/* Wait for probable vdev->active changing */
fpi_device_add_timeout (dev, VFS_SSM_TIMEOUT,
fpi_ssm_next_state_timeout_cb, ssm);
fpi_ssm_next_state_delayed (ssm, VFS_SSM_TIMEOUT, NULL);
break;
case SSM_NEXT_RECEIVE:
@@ -643,8 +627,8 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
case SSM_WAIT_ANOTHER_SCAN:
/* Orange light is on now */
fpi_device_add_timeout (dev, VFS_SSM_ORANGE_TIMEOUT,
another_scan, ssm);
fpi_ssm_jump_to_state_delayed (ssm, SSM_TURN_ON, VFS_SSM_ORANGE_TIMEOUT,
NULL);
break;
default:
@@ -669,7 +653,6 @@ dev_activate_callback (FpiSsm *ssm, FpDevice *dev, GError *error)
g_error_free (error);
}
fpi_ssm_free (ssm);
}
/* Activate device */
@@ -710,7 +693,6 @@ dev_open_callback (FpiSsm *ssm, FpDevice *dev, GError *error)
{
/* Notify open complete */
fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), error);
fpi_ssm_free (ssm);
}
/* Open device */

View File

@@ -219,7 +219,6 @@ async_send (FpiSsm *ssm,
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
async_send_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
/* Callback of asynchronous recv */
@@ -282,7 +281,6 @@ async_recv (FpiSsm *ssm,
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
async_recv_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
static void async_load (FpiSsm *ssm,
@@ -369,17 +367,6 @@ async_load (FpiSsm *ssm,
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
async_load_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
/* Submit asynchronous sleep */
static void
async_sleep (unsigned int msec,
FpiSsm *ssm,
FpImageDevice *dev)
{
fpi_device_add_timeout (FP_DEVICE (dev), msec,
fpi_ssm_next_state_timeout_cb, ssm);
}
/* Swap ssm states */
@@ -798,7 +785,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
case M_LOOP_0_SLEEP:
/* Wait fingerprint scanning */
async_sleep (50, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 50, NULL);
break;
case M_LOOP_0_GET_STATE:
@@ -841,7 +828,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
img_extract (ssm, dev);
/* Wait handling image */
async_sleep (10, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 10, NULL);
break;
case M_LOOP_0_CHECK_ACTION:
@@ -864,7 +851,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
if (vfs_finger_state (self) == VFS_FINGER_PRESENT)
{
fpi_image_device_report_finger_status (dev, TRUE);
async_sleep (250, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 250, NULL);
}
else
{
@@ -894,7 +881,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
case M_LOOP_1_SLEEP:
/* Wait fingerprint scanning */
async_sleep (10, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 10, NULL);
break;
case M_LOOP_2_ABORT_PRINT:
@@ -930,7 +917,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
{
/* Wait aborting */
self->counter++;
async_sleep (100, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 100, NULL);
}
else
{
@@ -960,7 +947,6 @@ m_loop_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
self->active = FALSE;
fpi_ssm_free (ssm);
}
/* Init ssm states */
@@ -1069,7 +1055,7 @@ m_init_state (FpiSsm *ssm, FpDevice *_dev)
{
/* Wait aborting */
self->counter++;
async_sleep (100, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 100, NULL);
}
else
{
@@ -1098,7 +1084,7 @@ m_init_state (FpiSsm *ssm, FpDevice *_dev)
{
/* Wait removing finger */
self->counter++;
async_sleep (250, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 250, NULL);
}
else
{
@@ -1268,7 +1254,6 @@ m_init_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
}
/* Free sequential state machine */
fpi_ssm_free (ssm);
}
/* Activate device */

View File

@@ -28,17 +28,6 @@ G_DEFINE_TYPE (FpDeviceVfs301, fpi_device_vfs301, FP_TYPE_IMAGE_DEVICE)
/************************** GENERIC STUFF *************************************/
/* Submit asynchronous sleep */
static void
async_sleep (unsigned int msec,
FpiSsm *ssm,
FpImageDevice *dev)
{
/* Add timeout */
fpi_device_add_timeout (FP_DEVICE (dev), msec,
fpi_ssm_next_state_timeout_cb, ssm);
}
static int
submit_image (FpiSsm *ssm,
FpImageDevice *dev)
@@ -108,7 +97,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
case M_WAIT_PRINT:
/* Wait fingerprint scanning */
async_sleep (200, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 200, NULL);
break;
case M_CHECK_PRINT:
@@ -126,7 +115,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
case M_READ_PRINT_WAIT:
/* Wait fingerprint scanning */
async_sleep (200, ssm, dev);
fpi_ssm_next_state_delayed (ssm, 200, NULL);
break;
case M_READ_PRINT_POLL:
@@ -168,7 +157,6 @@ m_loop_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
g_error_free (error);
}
/* Free sequential state machine */
fpi_ssm_free (ssm);
}
/* Exec init sequential state machine */
@@ -201,7 +189,6 @@ m_init_complete (FpiSsm *ssm, FpDevice *dev, GError *error)
}
/* Free sequential state machine */
fpi_ssm_free (ssm);
}
/* Activate device */

View File

@@ -79,7 +79,6 @@ usb_recv (FpDeviceVfs301 *dev, guint8 endpoint, int max_bytes, FpiUsbTransfer **
fpi_usb_transfer_submit_sync (transfer, VFS301_DEFAULT_WAIT_TIMEOUT, &err);
#ifdef DEBUG
usb_print_packet (0, err, transfer->buffer, transfer->actual_length);
#endif
@@ -471,7 +470,7 @@ int
vfs301_proto_peek_event (FpDeviceVfs301 *dev)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpiUsbTransfer) transfer = NULL;
FpiUsbTransfer *transfer;
const char no_event[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const char got_event[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00};
@@ -500,7 +499,7 @@ vfs301_proto_peek_event (FpDeviceVfs301 *dev)
usb_recv (dev, e1, l1, NULL, &error); \
usb_recv (dev, e2, l2, NULL, NULL); \
if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \
usb_recv(dev, e1, l1, NULL, NULL); \
usb_recv (dev, e1, l1, NULL, NULL); \
}
static void
@@ -540,7 +539,6 @@ vfs301_proto_process_event_cb (FpiUsbTransfer *transfer,
fpi_usb_transfer_fill_bulk (new, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_2);
fpi_usb_transfer_submit (new, VFS301_FP_RECV_TIMEOUT, NULL,
vfs301_proto_process_event_cb, NULL);
fpi_usb_transfer_unref (new);
return;
}
}
@@ -580,7 +578,6 @@ vfs301_proto_process_event_start (FpDeviceVfs301 *dev)
fpi_usb_transfer_fill_bulk (transfer, VFS301_RECEIVE_ENDPOINT_DATA, VFS301_FP_RECV_LEN_1);
fpi_usb_transfer_submit (transfer, VFS301_FP_RECV_TIMEOUT, NULL,
vfs301_proto_process_event_cb, NULL);
fpi_usb_transfer_unref (transfer);
}
int

View File

@@ -168,7 +168,6 @@ usbexchange_loop (FpiSsm *ssm, FpDevice *_dev)
transfer->short_is_error = TRUE;
fpi_usb_transfer_submit (transfer, data->timeout, NULL,
async_send_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
case ACTION_RECEIVE:
@@ -180,7 +179,6 @@ usbexchange_loop (FpiSsm *ssm, FpDevice *_dev)
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, data->timeout, NULL,
async_recv_cb, NULL);
fpi_usb_transfer_unref (transfer);
break;
default:
@@ -466,7 +464,6 @@ capture_chunk_async (FpDeviceVfs5011 *self,
transfer->ssm = ssm;
fpi_usb_transfer_submit (transfer, timeout, fpi_device_get_cancellable (FP_DEVICE (self)),
chunk_capture_callback, NULL);
fpi_usb_transfer_unref (transfer);
}
/*
@@ -707,10 +704,7 @@ activate_loop (FpiSsm *ssm, FpDevice *_dev)
break;
case DEV_ACTIVATE_DATA_COMPLETE:
fpi_device_add_timeout (_dev, 1,
fpi_ssm_next_state_timeout_cb,
ssm);
fpi_ssm_next_state_delayed (ssm, 1, NULL);
break;
case DEV_ACTIVATE_PREPARE_NEXT_CAPTURE:
@@ -745,7 +739,6 @@ activate_loop_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
submit_image (ssm, self, dev);
fpi_image_device_report_finger_status (dev, FALSE);
}
fpi_ssm_free (ssm);
self->loop_running = FALSE;
@@ -793,7 +786,6 @@ open_loop_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
self->init_sequence.receive_buf = NULL;
fpi_image_device_open_complete (dev, error);
fpi_ssm_free (ssm);
}
static void

View File

@@ -66,13 +66,14 @@ recv_image_img_recv_cb (GObject *source_object,
g_autoptr(GError) error = NULL;
FpDeviceVirtualImage *self;
FpImageDevice *device;
gssize bytes;
gboolean success;
gsize bytes = 0;
bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
if (bytes <= 0)
if (!success || bytes == 0)
{
if (bytes < 0)
if (!success)
{
g_warning ("Error receiving header for image data: %s", error->message);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
@@ -81,7 +82,7 @@ recv_image_img_recv_cb (GObject *source_object,
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
self->connection = NULL;
g_clear_object (&self->connection);
return;
}
@@ -103,13 +104,14 @@ recv_image_hdr_recv_cb (GObject *source_object,
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualImage *self;
gssize bytes;
gboolean success;
gsize bytes;
bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
if (bytes <= 0)
if (!success || bytes == 0)
{
if (bytes < 0)
if (!success)
{
g_warning ("Error receiving header for image data: %s", error->message);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
@@ -118,7 +120,7 @@ recv_image_hdr_recv_cb (GObject *source_object,
self = FPI_DEVICE_VIRTUAL_IMAGE (user_data);
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
self->connection = NULL;
g_clear_object (&self->connection);
return;
}
@@ -127,7 +129,7 @@ recv_image_hdr_recv_cb (GObject *source_object,
{
g_warning ("Image header suggests an unrealistically large image, disconnecting client.");
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
self->connection = NULL;
g_clear_object (&self->connection);
}
if (self->recv_img_hdr[0] < 0 || self->recv_img_hdr[1] < 0)
@@ -148,7 +150,7 @@ recv_image_hdr_recv_cb (GObject *source_object,
default:
/* disconnect client, it didn't play fair */
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
self->connection = NULL;
g_clear_object (&self->connection);
}
/* And, listen for more images from the same client. */
@@ -158,25 +160,25 @@ recv_image_hdr_recv_cb (GObject *source_object,
self->recv_img = fp_image_new (self->recv_img_hdr[0], self->recv_img_hdr[1]);
g_debug ("image data: %p", self->recv_img->data);
g_input_stream_read_async (G_INPUT_STREAM (source_object),
(guint8 *) self->recv_img->data,
self->recv_img->width * self->recv_img->height,
G_PRIORITY_DEFAULT,
self->cancellable,
recv_image_img_recv_cb,
self);
g_input_stream_read_all_async (G_INPUT_STREAM (source_object),
(guint8 *) self->recv_img->data,
self->recv_img->width * self->recv_img->height,
G_PRIORITY_DEFAULT,
self->cancellable,
recv_image_img_recv_cb,
self);
}
static void
recv_image (FpDeviceVirtualImage *dev, GInputStream *stream)
{
g_input_stream_read_async (stream,
dev->recv_img_hdr,
sizeof (dev->recv_img_hdr),
G_PRIORITY_DEFAULT,
dev->cancellable,
recv_image_hdr_recv_cb,
dev);
g_input_stream_read_all_async (stream,
dev->recv_img_hdr,
sizeof (dev->recv_img_hdr),
G_PRIORITY_DEFAULT,
dev->cancellable,
recv_image_hdr_recv_cb,
dev);
}
static void
@@ -206,6 +208,7 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
if (dev->connection)
{
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
g_object_unref (connection);
return;
}

View File

@@ -186,6 +186,8 @@ fp_context_finalize (GObject *object)
g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
g_clear_pointer (&priv->drivers, g_array_unref);
g_object_run_dispose (G_OBJECT (priv->usb_ctx));
g_clear_object (&priv->usb_ctx);
G_OBJECT_CLASS (fp_context_parent_class)->finalize (object);

View File

@@ -1,6 +1,7 @@
/*
* FpDevice - A fingerprint reader device
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* 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
@@ -242,9 +243,18 @@ fpi_device_error_new (FpDeviceError error)
* and similar calls.
*/
GError *
fpi_device_retry_new_msg (FpDeviceRetry error, const gchar *msg)
fpi_device_retry_new_msg (FpDeviceRetry device_error,
const gchar *msg,
...)
{
return g_error_new_literal (FP_DEVICE_RETRY, error, msg);
GError *error;
va_list args;
va_start (args, msg);
error = g_error_new_valist (FP_DEVICE_RETRY, device_error, msg, args);
va_end (args);
return error;
}
/**
@@ -256,9 +266,18 @@ fpi_device_retry_new_msg (FpDeviceRetry error, const gchar *msg)
* and similar calls.
*/
GError *
fpi_device_error_new_msg (FpDeviceError error, const gchar *msg)
fpi_device_error_new_msg (FpDeviceError device_error,
const gchar *msg,
...)
{
return g_error_new_literal (FP_DEVICE_ERROR, error, msg);
GError *error;
va_list args;
va_start (args, msg);
error = g_error_new_valist (FP_DEVICE_ERROR, device_error, msg, args);
va_end (args);
return error;
}
static gboolean
@@ -363,6 +382,7 @@ fp_device_finalize (GObject *object)
g_clear_pointer (&priv->device_id, g_free);
g_clear_pointer (&priv->device_name, g_free);
g_clear_object (&priv->usb_device);
G_OBJECT_CLASS (fp_device_parent_class)->finalize (object);
}
@@ -1455,7 +1475,8 @@ fpi_device_set_scan_type (FpDevice *device,
* @device: The #FpDevice
* @interval: The interval in milliseconds
* @func: The #FpTimeoutFunc to call on timeout
* @user_data: User data to pass to the callback
* @user_data: (nullable): User data to pass to the callback
* @destroy_notify: (nullable): #GDestroyNotify for @user_data
*
* Register a timeout to run. Drivers should always make sure that timers are
* cancelled when appropriate.
@@ -1463,10 +1484,11 @@ fpi_device_set_scan_type (FpDevice *device,
* Returns: (transfer none): A newly created and attached #GSource
*/
GSource *
fpi_device_add_timeout (FpDevice *device,
gint interval,
FpTimeoutFunc func,
gpointer user_data)
fpi_device_add_timeout (FpDevice *device,
gint interval,
FpTimeoutFunc func,
gpointer user_data,
GDestroyNotify destroy_notify)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
FpDeviceTimeoutSource *source;
@@ -1477,7 +1499,7 @@ fpi_device_add_timeout (FpDevice *device,
source->user_data = user_data;
g_source_attach (&source->source, NULL);
g_source_set_callback (&source->source, (GSourceFunc) func, user_data, NULL);
g_source_set_callback (&source->source, (GSourceFunc) func, user_data, destroy_notify);
g_source_set_ready_time (&source->source,
g_source_get_time (&source->source) + interval * (guint64) 1000);
priv->sources = g_slist_prepend (priv->sources, source);
@@ -2322,8 +2344,9 @@ fpi_device_enroll_progress (FpDevice *device,
data->enroll_progress_data,
error);
}
if (error)
g_error_free (error);
g_clear_error (&error);
g_clear_object (&print);
}

View File

@@ -113,8 +113,8 @@ GQuark fp_device_error_quark (void);
* FpEnrollProgress:
* @device: a #FpDevice
* @completed_stages: Number of completed stages
* @print: (nullable): The last scaned print
* @user_data: (nullable): User provided data
* @print: (nullable) (transfer none): The last scaned print
* @user_data: (nullable) (transfer none): User provided data
* @error: (nullable) (transfer none): #GError or %NULL
*
* The passed error is guaranteed to be of type %FP_DEVICE_RETRY if set.

View File

@@ -21,6 +21,7 @@
#include "fpi-log.h"
#include "fpi-image-device.h"
#include "fpi-enums.h"
#include "fpi-print.h"
#include "fpi-image.h"
@@ -60,6 +61,21 @@ typedef struct
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (FpImageDevice, fp_image_device, FP_TYPE_DEVICE)
enum {
PROP_0,
PROP_FPI_STATE,
N_PROPS
};
static GParamSpec *properties[N_PROPS];
enum {
FPI_STATE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/*******************************************************/
@@ -73,27 +89,19 @@ static void
fp_image_device_change_state (FpImageDevice *self, FpImageDeviceState state)
{
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpImageDeviceClass *cls = FP_IMAGE_DEVICE_GET_CLASS (self);
/* Cannot change to inactive using this function. */
g_assert (state != FP_IMAGE_DEVICE_STATE_INACTIVE);
/* We might have been waiting for the finger to go OFF to start the
* next operation. */
if (priv->pending_activation_timeout_id)
{
g_source_remove (priv->pending_activation_timeout_id);
priv->pending_activation_timeout_id = 0;
}
g_clear_handle_id (&priv->pending_activation_timeout_id, g_source_remove);
fp_dbg ("Image device internal state change from %d to %d\n", priv->state, state);
priv->state = state;
/* change_state is the only callback which is optional and does not
* have a default implementation. */
if (cls->change_state)
cls->change_state (self, state);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FPI_STATE]);
g_signal_emit (self, signals[FPI_STATE_CHANGED], 0, priv->state);
}
static void
@@ -107,14 +115,11 @@ fp_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 = FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FPI_STATE]);
/* We might have been waiting for deactivation to finish before
* starting the next operation. */
if (priv->pending_activation_timeout_id)
{
g_source_remove (priv->pending_activation_timeout_id);
priv->pending_activation_timeout_id = 0;
}
g_clear_handle_id (&priv->pending_activation_timeout_id, g_source_remove);
fp_dbg ("Activating image device\n");
cls->activate (self);
@@ -135,6 +140,7 @@ fp_image_device_deactivate (FpDevice *device)
return;
}
priv->state = FP_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FPI_STATE]);
fp_dbg ("Deactivating image device\n");
cls->deactivate (self);
@@ -286,6 +292,7 @@ fp_image_device_finalize (GObject *object)
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
g_assert (priv->active == FALSE);
g_clear_handle_id (&priv->pending_activation_timeout_id, g_source_remove);
G_OBJECT_CLASS (fp_image_device_parent_class)->finalize (object);
}
@@ -302,6 +309,26 @@ fp_image_device_default_deactivate (FpImageDevice *self)
fpi_image_device_deactivate_complete (self, NULL);
}
static void
fp_image_device_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
FpImageDevice *self = FP_IMAGE_DEVICE (object);
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
switch (prop_id)
{
case PROP_FPI_STATE:
g_value_set_enum (value, priv->state);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
fp_image_device_class_init (FpImageDeviceClass *klass)
{
@@ -309,6 +336,7 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
FpDeviceClass *fp_device_class = FP_DEVICE_CLASS (klass);
object_class->finalize = fp_image_device_finalize;
object_class->get_property = fp_image_device_get_property;
fp_device_class->open = fp_image_device_open;
fp_device_class->close = fp_image_device_close;
@@ -322,6 +350,24 @@ fp_image_device_class_init (FpImageDeviceClass *klass)
/* Default implementations */
klass->activate = fp_image_device_default_activate;
klass->deactivate = fp_image_device_default_deactivate;
properties[PROP_FPI_STATE] =
g_param_spec_enum ("fp-image-device-state",
"Image Device State",
"Private: The state of the image device",
FP_TYPE_IMAGE_DEVICE_STATE,
FP_IMAGE_DEVICE_STATE_INACTIVE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
signals[FPI_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, FP_TYPE_IMAGE_DEVICE_STATE);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
@@ -343,8 +389,8 @@ static void
fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
g_autoptr(FpImage) image = FP_IMAGE (source_object);
g_autoptr(FpPrint) print = NULL;
GError *error = NULL;
FpPrint *print = NULL;
FpDevice *device = FP_DEVICE (user_data);
FpImageDevicePrivate *priv;
FpDeviceAction action;
@@ -397,7 +443,8 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
priv->enroll_stage += 1;
}
fpi_device_enroll_progress (device, priv->enroll_stage, print, error);
fpi_device_enroll_progress (device, priv->enroll_stage,
g_steal_pointer (&print), error);
if (priv->enroll_stage == IMG_ENROLL_STAGES)
{
@@ -416,7 +463,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
else
result = FPI_MATCH_ERROR;
fpi_device_verify_complete (device, result, print, error);
fpi_device_verify_complete (device, result, g_steal_pointer (&print), error);
fp_image_device_deactivate (device);
}
else if (action == FP_DEVICE_ACTION_IDENTIFY)
@@ -437,7 +484,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
}
}
fpi_device_identify_complete (device, result, print, error);
fpi_device_identify_complete (device, result, g_steal_pointer (&print), error);
fp_image_device_deactivate (device);
}
else
@@ -493,8 +540,6 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
FpDeviceAction action;
action = fpi_device_get_current_action (device);
if (priv->state == FP_IMAGE_DEVICE_STATE_INACTIVE)
{
/* Do we really want to always ignore such reports? We could
@@ -741,7 +786,11 @@ fpi_image_device_deactivate_complete (FpImageDevice *self, GError *error)
/* We might be waiting to be able to activate again. */
if (priv->pending_activation_timeout_id)
fp_image_device_activate (self);
{
g_clear_handle_id (&priv->pending_activation_timeout_id, g_source_remove);
priv->pending_activation_timeout_id =
g_idle_add ((GSourceFunc) fp_image_device_activate, self);
}
}
/**
@@ -765,6 +814,7 @@ fpi_image_device_open_complete (FpImageDevice *self, GError *error)
g_debug ("Image device open completed");
priv->state = FP_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FPI_STATE]);
fpi_device_open_complete (FP_DEVICE (self), error);
}
@@ -790,6 +840,7 @@ fpi_image_device_close_complete (FpImageDevice *self, GError *error)
g_return_if_fail (action == FP_DEVICE_ACTION_CLOSE);
priv->state = FP_IMAGE_DEVICE_STATE_INACTIVE;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FPI_STATE]);
fpi_device_close_complete (FP_DEVICE (self), error);
}

View File

@@ -101,6 +101,7 @@ fp_print_finalize (GObject *object)
g_clear_pointer (&self->description, g_free);
g_clear_pointer (&self->enroll_date, g_date_free);
g_clear_pointer (&self->data, g_variant_unref);
g_clear_pointer (&self->prints, g_ptr_array_unref);
G_OBJECT_CLASS (fp_print_parent_class)->finalize (object);
}
@@ -534,11 +535,8 @@ fp_print_set_enroll_date (FpPrint *print,
g_clear_pointer (&print->enroll_date, g_date_free);
if (enroll_date)
{
/* XXX: Should use g_date_copy, but that is new in 2.56. */
print->enroll_date = g_date_new ();
*print->enroll_date = *enroll_date;
}
print->enroll_date = g_date_copy (enroll_date);
g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_ENROLL_DATE]);
}
@@ -582,7 +580,10 @@ fpi_print_set_type (FpPrint *print,
print->type = type;
if (print->type == FP_PRINT_NBIS)
print->prints = g_ptr_array_new_with_free_func (g_free);
{
g_assert_null (print->prints);
print->prints = g_ptr_array_new_with_free_func (g_free);
}
g_object_notify_by_pspec (G_OBJECT (print), properties[PROP_FPI_TYPE]);
}
@@ -921,6 +922,7 @@ fp_print_serialize (FpPrint *print,
xyt->nrows,
sizeof (col[0])));
g_variant_builder_close (&nested);
g_free (col);
}
g_variant_builder_close (&nested);
@@ -976,6 +978,7 @@ fp_print_deserialize (const guchar *data,
g_autoptr(FpPrint) result = NULL;
g_autoptr(GVariant) raw_value = NULL;
g_autoptr(GVariant) value = NULL;
g_autoptr(GVariant) print_data = NULL;
guchar *aligned_data = NULL;
GDate *date = NULL;
guint8 finger_int8;
@@ -987,7 +990,6 @@ fp_print_deserialize (const guchar *data,
const gchar *driver;
const gchar *device_id;
gboolean device_stored;
GVariant *print_data;
g_assert (data);
g_assert (length > 3);
@@ -1007,7 +1009,7 @@ fp_print_deserialize (const guchar *data,
memcpy (aligned_data, data + 3, length - 3);
raw_value = g_variant_new_from_data (FP_PRINT_VARIANT_TYPE,
aligned_data, length - 3,
FALSE, g_free, NULL);
FALSE, g_free, aligned_data);
if (!raw_value)
goto invalid_format;
@@ -1018,7 +1020,7 @@ fp_print_deserialize (const guchar *data,
value = g_variant_get_normal_form (raw_value);
g_variant_get (value,
"(issbymsmsi@a{sv}v)",
"(i&s&sbymsmsi@a{sv}v)",
&type,
&driver,
&device_id,
@@ -1046,7 +1048,7 @@ fp_print_deserialize (const guchar *data,
fpi_print_set_type (result, FP_PRINT_NBIS);
for (i = 0; i < g_variant_n_children (prints); i++)
{
struct xyt_struct *xyt = g_new0 (struct xyt_struct, 1);
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;
@@ -1077,7 +1079,7 @@ fp_print_deserialize (const guchar *data,
memcpy (xyt->ycol, ycol, sizeof (xcol[0]) * xlen);
memcpy (xyt->thetacol, thetacol, sizeof (xcol[0]) * xlen);
g_ptr_array_add (result->prints, xyt);
g_ptr_array_add (result->prints, g_steal_pointer (&xyt));
}
}
else if (type == FP_PRINT_RAW)

View File

@@ -385,8 +385,10 @@ median_filter (int *data, int size, int filtersize)
static void
interpolate_lines (struct fpi_line_asmbl_ctx *ctx,
GSList *line1, float y1, GSList *line2,
float y2, unsigned char *output, float yi, int size)
GSList *line1, gint32 y1_f,
GSList *line2, gint32 y2_f,
unsigned char *output, gint32 yi_f,
int size)
{
int i;
unsigned char p1, p2;
@@ -396,10 +398,12 @@ interpolate_lines (struct fpi_line_asmbl_ctx *ctx,
for (i = 0; i < size; i++)
{
gint unscaled;
p1 = ctx->get_pixel (ctx, line1, i);
p2 = ctx->get_pixel (ctx, line2, i);
output[i] = (float) p1
+ (yi - y1) / (y2 - y1) * (p2 - p1);
unscaled = (yi_f - y1_f) * p2 + (y2_f - yi_f) * p1;
output[i] = (unscaled) / (y2_f - y1_f);
}
}
@@ -424,7 +428,13 @@ fpi_assemble_lines (struct fpi_line_asmbl_ctx *ctx,
/* Number of output lines per distance between two scanners */
int i;
GSList *row1, *row2;
float y = 0.0;
/* The y coordinate is tracked as a 16.16 fixed point number. All
* variables postfixed with _f follow this format here and in
* interpolate_lines.
* We could also use floating point here, but using fixed point means
* we get consistent results across architectures.
*/
gint32 y_f = 0;
int line_ind = 0;
int *offsets = g_new0 (int, num_lines / 2);
unsigned char *output = g_malloc0 (ctx->line_width * ctx->max_height);
@@ -476,21 +486,21 @@ fpi_assemble_lines (struct fpi_line_asmbl_ctx *ctx,
int offset = offsets[i / 2];
if (offset > 0)
{
float ynext = y + (float) ctx->resolution / offset;
while (line_ind < ynext)
gint32 ynext_f = y_f + (ctx->resolution << 16) / offset;
while ((line_ind << 16) < ynext_f)
{
if (line_ind > ctx->max_height - 1)
goto out;
interpolate_lines (ctx,
row1, y,
row1, y_f,
g_slist_next (row1),
ynext,
ynext_f,
output + line_ind * ctx->line_width,
line_ind,
line_ind << 16,
ctx->line_width);
line_ind++;
}
y = ynext;
y_f = ynext_f;
}
}
out:

View File

@@ -181,9 +181,11 @@ GError * fpi_device_retry_new (FpDeviceRetry error);
GError * fpi_device_error_new (FpDeviceError error);
GError * fpi_device_retry_new_msg (FpDeviceRetry error,
const gchar *msg);
const gchar *msg,
...) G_GNUC_PRINTF (2, 3);
GError * fpi_device_error_new_msg (FpDeviceError error,
const gchar *msg);
const gchar *msg,
...) G_GNUC_PRINTF (2, 3);
guint64 fpi_device_get_driver_data (FpDevice *device);
@@ -201,11 +203,11 @@ void fpi_device_get_delete_data (FpDevice *device,
GCancellable *fpi_device_get_cancellable (FpDevice *device);
GSource * fpi_device_add_timeout (FpDevice *device,
gint interval,
FpTimeoutFunc func,
gpointer user_data);
GSource * fpi_device_add_timeout (FpDevice *device,
gint interval,
FpTimeoutFunc func,
gpointer user_data,
GDestroyNotify destroy_notify);
void fpi_device_set_nr_enroll_stages (FpDevice *device,
gint enroll_stages);

View File

@@ -68,11 +68,11 @@
/**
* fp_err:
*
* Same as g_warning(). In the future, this might be changed to a
* Same as g_critical(). In the future, this might be changed to a
* g_assert() instead, so bear this in mind when adding those calls
* to your driver.
*/
#define fp_err g_warning
#define fp_err g_critical
/**
* BUG_ON:

View File

@@ -43,7 +43,7 @@ gboolean fpi_print_add_from_image (FpPrint *print,
GError **error);
FpiMatchResult fpi_print_bz3_match (FpPrint * template,
FpPrint *print,
FpPrint * print,
gint bz3_threshold,
GError **error);

View File

@@ -2,6 +2,7 @@
* Functions to assist with asynchronous driver <---> library communications
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* 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
@@ -50,6 +51,7 @@
*
* To start a ssm, you pass in a completion callback function to fpi_ssm_start()
* which gets called when the ssm completes (both on error and on failure).
* Starting a ssm also takes ownership of it.
*
* To iterate to the next state, call fpi_ssm_next_state(). It is legal to
* attempt to iterate beyond the final state - this is equivalent to marking
@@ -57,6 +59,7 @@
*
* To mark successful completion of a SSM, either iterate beyond the final
* state or call fpi_ssm_mark_completed() from any state.
* This will also invalidate the machine, freeing it.
*
* To mark failed completion of a SSM, call fpi_ssm_mark_failed() from any
* state. You must pass a non-zero error code.
@@ -84,6 +87,9 @@ struct _FpiSsm
int nr_states;
int cur_state;
gboolean completed;
GSource *timeout;
GCancellable *cancellable;
gulong cancellable_id;
GError *error;
FpiSsmCompletedCallback callback;
FpiSsmHandlerCallback handler;
@@ -108,6 +114,7 @@ fpi_ssm_new (FpDevice *dev,
FpiSsm *machine;
BUG_ON (nr_states < 1);
BUG_ON (handler == NULL);
machine = g_new0 (FpiSsm, 1);
machine->handler = handler;
@@ -124,7 +131,6 @@ fpi_ssm_new (FpDevice *dev,
* @ssm_data_destroy: (nullable): #GDestroyNotify for @ssm_data
*
* Sets @machine's data (freeing the existing data, if any).
*
*/
void
fpi_ssm_set_data (FpiSsm *machine,
@@ -152,6 +158,81 @@ fpi_ssm_get_data (FpiSsm *machine)
return machine->ssm_data;
}
static void
fpi_ssm_clear_delayed_action (FpiSsm *machine)
{
if (machine->cancellable_id)
{
g_cancellable_disconnect (machine->cancellable, machine->cancellable_id);
machine->cancellable_id = 0;
}
g_clear_object (&machine->cancellable);
g_clear_pointer (&machine->timeout, g_source_destroy);
}
typedef struct _CancelledActionIdleData
{
gulong cancellable_id;
GCancellable *cancellable;
} CancelledActionIdleData;
static gboolean
on_delayed_action_cancelled_idle (gpointer user_data)
{
CancelledActionIdleData *data = user_data;
g_cancellable_disconnect (data->cancellable, data->cancellable_id);
g_object_unref (data->cancellable);
g_free (data);
return G_SOURCE_REMOVE;
}
static void
on_delayed_action_cancelled (GCancellable *cancellable,
FpiSsm *machine)
{
CancelledActionIdleData *data;
g_clear_pointer (&machine->timeout, g_source_destroy);
data = g_new0 (CancelledActionIdleData, 1);
data->cancellable = g_steal_pointer (&machine->cancellable);
data->cancellable_id = machine->cancellable_id;
machine->cancellable_id = 0;
g_idle_add_full (G_PRIORITY_HIGH_IDLE, on_delayed_action_cancelled_idle,
data, NULL);
}
static void
fpi_ssm_set_delayed_action_timeout (FpiSsm *machine,
int delay,
FpTimeoutFunc callback,
GCancellable *cancellable,
gpointer user_data,
GDestroyNotify destroy_func)
{
BUG_ON (machine->completed);
BUG_ON (machine->timeout != NULL);
fpi_ssm_clear_delayed_action (machine);
if (cancellable != NULL)
{
g_set_object (&machine->cancellable, cancellable);
machine->cancellable_id =
g_cancellable_connect (machine->cancellable,
G_CALLBACK (on_delayed_action_cancelled),
machine, NULL);
}
machine->timeout = fpi_device_add_timeout (machine->dev, delay, callback,
user_data, destroy_func);
}
/**
* fpi_ssm_free:
* @machine: an #FpiSsm state machine
@@ -165,9 +246,12 @@ fpi_ssm_free (FpiSsm *machine)
if (!machine)
return;
BUG_ON (machine->timeout != NULL);
if (machine->ssm_data_destroy)
g_clear_pointer (&machine->ssm_data, machine->ssm_data_destroy);
g_clear_pointer (&machine->error, g_error_free);
fpi_ssm_clear_delayed_action (machine);
g_free (machine);
}
@@ -181,12 +265,16 @@ __ssm_call_handler (FpiSsm *machine)
/**
* fpi_ssm_start:
* @ssm: an #FpiSsm state machine
* @ssm: (transfer full): an #FpiSsm state machine
* @callback: the #FpiSsmCompletedCallback callback to call on completion
*
* Starts a state machine. You can also use this function to restart
* a completed or failed state machine. The @callback will be called
* on completion.
*
* Note that @ssm will be stolen when this function is called.
* So that all associated data will be free'ed automatically, after the
* @callback is ran.
*/
void
fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
@@ -209,7 +297,6 @@ __subsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
fpi_ssm_mark_failed (parent, error);
else
fpi_ssm_next_state (parent);
fpi_ssm_free (ssm);
}
/**
@@ -226,7 +313,9 @@ __subsm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
void
fpi_ssm_start_subsm (FpiSsm *parent, FpiSsm *child)
{
BUG_ON (parent->timeout);
child->parentsm = parent;
g_clear_pointer (&parent->timeout, g_source_destroy);
fpi_ssm_start (child, __subsm_complete);
}
@@ -241,7 +330,12 @@ void
fpi_ssm_mark_completed (FpiSsm *machine)
{
BUG_ON (machine->completed);
BUG_ON (machine->timeout != NULL);
fpi_ssm_clear_delayed_action (machine);
machine->completed = TRUE;
if (machine->error)
fp_dbg ("%p completed with error: %s", machine, machine->error->message);
else
@@ -252,14 +346,55 @@ fpi_ssm_mark_completed (FpiSsm *machine)
machine->callback (machine, machine->dev, error);
}
fpi_ssm_free (machine);
}
static void
on_device_timeout_complete (FpDevice *dev,
gpointer user_data)
{
FpiSsm *machine = user_data;
machine->timeout = NULL;
fpi_ssm_mark_completed (machine);
}
/**
* fpi_ssm_mark_completed_delayed:
* @machine: an #FpiSsm state machine
* @delay: the milliseconds to wait before switching to the next state
* @cancellable: (nullable): a #GCancellable to cancel the delayed operation
*
* Mark a ssm as completed successfully with a delay of @delay ms.
* The callback set when creating the state machine with fpi_ssm_new () will be
* called when the timeout is over.
* The request can be cancelled passing a #GCancellable as @cancellable.
*/
void
fpi_ssm_mark_completed_delayed (FpiSsm *machine,
int delay,
GCancellable *cancellable)
{
g_autofree char *source_name = NULL;
g_return_if_fail (machine != NULL);
fpi_ssm_set_delayed_action_timeout (machine, delay,
on_device_timeout_complete, cancellable,
machine, NULL);
source_name = g_strdup_printf ("[%s] ssm %p complete %d",
fp_device_get_device_id (machine->dev),
machine, machine->cur_state + 1);
g_source_set_name (machine->timeout, source_name);
}
/**
* fpi_ssm_mark_failed:
* @machine: an #FpiSsm state machine
* @error: a #GError
* @error: (transfer full): a #GError
*
* Mark a state machine as failed with @error as the error code.
* Mark a state machine as failed with @error as the error code, completing it.
*/
void
fpi_ssm_mark_failed (FpiSsm *machine, GError *error)
@@ -273,7 +408,7 @@ fpi_ssm_mark_failed (FpiSsm *machine, GError *error)
}
fp_dbg ("SSM failed in state %d with error: %s", machine->cur_state, error->message);
machine->error = error;
machine->error = g_steal_pointer (&error);
fpi_ssm_mark_completed (machine);
}
@@ -291,6 +426,10 @@ fpi_ssm_next_state (FpiSsm *machine)
g_return_if_fail (machine != NULL);
BUG_ON (machine->completed);
BUG_ON (machine->timeout != NULL);
fpi_ssm_clear_delayed_action (machine);
machine->cur_state++;
if (machine->cur_state == machine->nr_states)
fpi_ssm_mark_completed (machine);
@@ -298,22 +437,134 @@ fpi_ssm_next_state (FpiSsm *machine)
__ssm_call_handler (machine);
}
void
fpi_ssm_cancel_delayed_state_change (FpiSsm *machine)
{
g_return_if_fail (machine);
BUG_ON (machine->completed);
BUG_ON (machine->timeout == NULL);
fpi_ssm_clear_delayed_action (machine);
}
static void
on_device_timeout_next_state (FpDevice *dev,
gpointer user_data)
{
FpiSsm *machine = user_data;
machine->timeout = NULL;
fpi_ssm_next_state (machine);
}
/**
* fpi_ssm_next_state_delayed:
* @machine: an #FpiSsm state machine
* @delay: the milliseconds to wait before switching to the next state
* @cancellable: (nullable): a #GCancellable to cancel the delayed operation
*
* Iterate to next state of a state machine with a delay of @delay ms. If the
* current state is the last state, then the state machine will be marked as
* completed, as if calling fpi_ssm_mark_completed().
* Passing a valid #GCancellable will cause the action to be cancelled when
* @cancellable is.
*/
void
fpi_ssm_next_state_delayed (FpiSsm *machine,
int delay,
GCancellable *cancellable)
{
g_autofree char *source_name = NULL;
g_return_if_fail (machine != NULL);
fpi_ssm_set_delayed_action_timeout (machine, delay,
on_device_timeout_next_state, cancellable,
machine, NULL);
source_name = g_strdup_printf ("[%s] ssm %p jump to next state %d",
fp_device_get_device_id (machine->dev),
machine, machine->cur_state + 1);
g_source_set_name (machine->timeout, source_name);
}
/**
* fpi_ssm_jump_to_state:
* @machine: an #FpiSsm state machine
* @state: the state to jump to
*
* Jump to the @state state, bypassing intermediary states.
* If @state is the last state, the machine won't be completed unless
* fpi_ssm_mark_completed() isn't explicitly called.
*/
void
fpi_ssm_jump_to_state (FpiSsm *machine, int state)
{
BUG_ON (machine->completed);
BUG_ON (state >= machine->nr_states);
BUG_ON (state < 0 || state >= machine->nr_states);
BUG_ON (machine->timeout != NULL);
fpi_ssm_clear_delayed_action (machine);
machine->cur_state = state;
__ssm_call_handler (machine);
}
typedef struct
{
FpiSsm *machine;
int next_state;
} FpiSsmJumpToStateDelayedData;
static void
on_device_timeout_jump_to_state (FpDevice *dev,
gpointer user_data)
{
FpiSsmJumpToStateDelayedData *data = user_data;
data->machine->timeout = NULL;
fpi_ssm_jump_to_state (data->machine, data->next_state);
}
/**
* fpi_ssm_jump_to_state_delayed:
* @machine: an #FpiSsm state machine
* @state: the state to jump to
* @delay: the milliseconds to wait before switching to @state state
* @cancellable: (nullable): a #GCancellable to cancel the delayed operation
*
* Jump to the @state state with a delay of @delay milliseconds, bypassing
* intermediary states.
* Passing a valid #GCancellable will cause the action to be cancelled when
* @cancellable is.
*/
void
fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
int state,
int delay,
GCancellable *cancellable)
{
FpiSsmJumpToStateDelayedData *data;
g_autofree char *source_name = NULL;
g_return_if_fail (machine != NULL);
BUG_ON (machine->completed);
BUG_ON (machine->timeout != NULL);
data = g_new0 (FpiSsmJumpToStateDelayedData, 1);
data->machine = machine;
data->next_state = state;
fpi_ssm_set_delayed_action_timeout (machine, delay,
on_device_timeout_jump_to_state,
cancellable, data, g_free);
source_name = g_strdup_printf ("[%s] ssm %p jump to state %d",
fp_device_get_device_id (machine->dev),
machine, state);
g_source_set_name (machine->timeout, source_name);
}
/**
* fpi_ssm_get_cur_state:
* @machine: an #FpiSsm state machine
@@ -360,33 +611,11 @@ fpi_ssm_dup_error (FpiSsm *machine)
return NULL;
}
/**
* fpi_ssm_next_state_timeout_cb:
* @dev: a struct #fp_dev
* @data: a pointer to an #FpiSsm state machine
*
* Same as fpi_ssm_next_state(), but to be used as a callback
* for an fpi_timeout_add() callback, when the state change needs
* to happen after a timeout.
*
* Make sure to pass the #FpiSsm as the `ssm_data` argument
* for that fpi_timeout_add() call.
*/
void
fpi_ssm_next_state_timeout_cb (FpDevice *dev,
void *data)
{
g_return_if_fail (dev != NULL);
g_return_if_fail (data != NULL);
fpi_ssm_next_state (data);
}
/**
* fpi_ssm_usb_transfer_cb:
* @transfer: a #FpiUsbTransfer
* @device: a #FpDevice
* @ssm_data: User data (unused)
* @unused_data: User data (unused)
* @error: The #GError or %NULL
*
* Can be used in as a #FpiUsbTransfer callback handler to automatically
@@ -396,7 +625,7 @@ fpi_ssm_next_state_timeout_cb (FpDevice *dev,
*/
void
fpi_ssm_usb_transfer_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer ssm_data, GError *error)
gpointer unused_data, GError *error)
{
g_return_if_fail (transfer->ssm);
@@ -405,3 +634,32 @@ fpi_ssm_usb_transfer_cb (FpiUsbTransfer *transfer, FpDevice *device,
else
fpi_ssm_next_state (transfer->ssm);
}
/**
* fpi_ssm_usb_transfer_with_weak_pointer_cb:
* @transfer: a #FpiUsbTransfer
* @device: a #FpDevice
* @weak_ptr: A #gpointer pointer to nullify. You can pass a pointer to any
* #gpointer to nullify when the callback is completed. I.e a
* pointer to the current #FpiUsbTransfer.
* @error: The #GError or %NULL
*
* Can be used in as a #FpiUsbTransfer callback handler to automatically
* advance or fail a statemachine on transfer completion.
* Passing a #gpointer* as @weak_ptr permits to nullify it once we're done
* with the transfer.
*
* Make sure to set the #FpiSsm on the transfer.
*/
void
fpi_ssm_usb_transfer_with_weak_pointer_cb (FpiUsbTransfer *transfer,
FpDevice *device, gpointer weak_ptr,
GError *error)
{
g_return_if_fail (transfer->ssm);
if (weak_ptr)
g_nullify_pointer ((gpointer *) weak_ptr);
fpi_ssm_usb_transfer_cb (transfer, device, weak_ptr, error);
}

View File

@@ -2,6 +2,7 @@
* Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* 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
@@ -72,7 +73,18 @@ void fpi_ssm_start_subsm (FpiSsm *parent,
void fpi_ssm_next_state (FpiSsm *machine);
void fpi_ssm_jump_to_state (FpiSsm *machine,
int state);
void fpi_ssm_next_state_delayed (FpiSsm *machine,
int delay,
GCancellable *cancellable);
void fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
int state,
int delay,
GCancellable *cancellable);
void fpi_ssm_cancel_delayed_state_change (FpiSsm *machine);
void fpi_ssm_mark_completed (FpiSsm *machine);
void fpi_ssm_mark_completed_delayed (FpiSsm *machine,
int delay,
GCancellable *cancellable);
void fpi_ssm_mark_failed (FpiSsm *machine,
GError *error);
void fpi_ssm_set_data (FpiSsm *machine,
@@ -86,9 +98,11 @@ int fpi_ssm_get_cur_state (FpiSsm *machine);
/* Callbacks to be used by the driver instead of implementing their own
* logic.
*/
void fpi_ssm_next_state_timeout_cb (FpDevice *dev,
void *data);
void fpi_ssm_usb_transfer_cb (FpiUsbTransfer *transfer,
FpDevice *device,
gpointer user_data,
gpointer unused_data,
GError *error);
void fpi_ssm_usb_transfer_with_weak_pointer_cb (FpiUsbTransfer *transfer,
FpDevice *device,
gpointer weak_ptr,
GError *error);

View File

@@ -356,7 +356,7 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
/**
* fpi_usb_transfer_submit:
* @transfer: The transfer to submit, must have been filled.
* @transfer: (transfer full): The transfer to submit, must have been filled.
* @timeout_ms: Timeout for the transfer in ms
* @cancellable: Cancellable to use, e.g. fpi_device_get_cancellable()
* @callback: Callback on completion or error
@@ -364,10 +364,9 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
*
* Submit a USB transfer with a specific timeout and callback functions.
*
* Note that #FpiUsbTransfer is owned by the user. In most cases, you
* should call fpi_usb_transfer_unref() just after calling this function.
* Doing so means that all associated data will be free'ed automatically
* after the callback ran.
* 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 explictly called.
*/
void
fpi_usb_transfer_submit (FpiUsbTransfer *transfer,
@@ -385,11 +384,6 @@ fpi_usb_transfer_submit (FpiUsbTransfer *transfer,
transfer->callback = callback;
transfer->user_data = user_data;
/* Grab a reference, this means that one can simply unref after submit and
* trust for the data to disappear without explicit management by the callback
* function. */
fpi_usb_transfer_ref (transfer);
log_transfer (transfer, TRUE, NULL);
switch (transfer->type)

View File

@@ -99,8 +99,6 @@ main (int argc, char **argv)
g_autoptr(GArray) drivers = g_array_new (FALSE, FALSE, sizeof (GType));
guint i;
g_print ("%p\n", drivers);
g_print ("%p\n", fpi_get_driver_types);
fpi_get_driver_types (drivers);
printed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

View File

@@ -162,73 +162,73 @@ endif
other_sources = []
fp_enums = gnome.mkenums_simple('fp-enums',
sources: libfprint_public_headers,
install_header : true)
sources: libfprint_public_headers,
install_header : true)
fp_enums_h = fp_enums[1]
fpi_enums = gnome.mkenums_simple('fpi-enums',
sources: libfprint_private_headers,
install_header : true)
sources: libfprint_private_headers,
install_header : true)
fpi_enums_h = fpi_enums[1]
drivers_sources += configure_file(input: 'empty_file',
output: 'fp-drivers.c',
capture: true,
command: [
'echo',
drivers_type_list + '\n\n' + drivers_type_func
])
output: 'fp-drivers.c',
capture: true,
command: [
'echo',
drivers_type_list + '\n\n' + drivers_type_func
])
mapfile = 'libfprint.ver'
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
deps = [ mathlib_dep, glib_dep, gusb_dep, nss_dep, imaging_dep, gio_dep ]
libfprint = library('fprint',
libfprint_sources + fp_enums + fpi_enums +
drivers_sources + nbis_sources + other_sources,
soversion: soversion,
version: libversion,
c_args: common_cflags + drivers_cflags,
include_directories: [
root_inc,
include_directories('nbis/include'),
],
link_args : vflag,
link_depends : mapfile,
dependencies: deps,
install: true)
libfprint_sources + fp_enums + fpi_enums +
drivers_sources + nbis_sources + other_sources,
soversion: soversion,
version: libversion,
c_args: common_cflags + drivers_cflags,
include_directories: [
root_inc,
include_directories('nbis/include'),
],
link_args : vflag,
link_depends : mapfile,
dependencies: deps,
install: true)
libfprint_dep = declare_dependency(link_with: libfprint,
sources: [ fp_enums_h ],
include_directories: root_inc,
dependencies: [glib_dep, gusb_dep, gio_dep])
sources: [ fp_enums_h ],
include_directories: root_inc,
dependencies: [ glib_dep, gusb_dep, gio_dep ])
install_headers(['fprint.h'] + libfprint_public_headers, subdir: 'libfprint')
udev_rules = executable('fprint-list-udev-rules',
'fprint-list-udev-rules.c',
include_directories: [
root_inc,
],
dependencies: [ deps, libfprint_dep ],
install: false)
'fprint-list-udev-rules.c',
include_directories: [
root_inc,
],
dependencies: [ deps, libfprint_dep ],
install: false)
if get_option('udev_rules')
custom_target('udev-rules',
output: '60-fprint-autosuspend.rules',
capture: true,
command: [ udev_rules ],
install: true,
install_dir: udev_rules_dir)
output: '60-fprint-autosuspend.rules',
capture: true,
command: [ udev_rules ],
install: true,
install_dir: udev_rules_dir)
endif
supported_devices = executable('fprint-list-supported-devices',
'fprint-list-supported-devices.c',
include_directories: [
root_inc,
],
dependencies: [ deps, libfprint_dep ],
install: false)
'fprint-list-supported-devices.c',
include_directories: [
root_inc,
],
dependencies: [ deps, libfprint_dep ],
install: false)
if get_option('introspection')
@@ -256,8 +256,7 @@ if get_option('introspection')
'GObject-2.0',
'GUsb-1.0',
],
install : true
)
install : true)
libfprint_gir = libfprint_girtarget[0]
libfprint_typelib = libfprint_girtarget[1]
endif

View File

@@ -1,12 +1,12 @@
project('libfprint', [ 'c', 'cpp' ],
version: '1.90.0',
license: 'LGPLv2.1+',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
'c_std=c99',
],
meson_version: '>= 0.46.0')
version: '1.90.0',
license: 'LGPLv2.1+',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
'c_std=c99',
],
meson_version: '>= 0.46.0')
gnome = import('gnome')
@@ -18,7 +18,10 @@ libfprint_conf = configuration_data()
cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
host_system = host_machine.system()
glib_min_version = '2.56'
glib_version_def = 'GLIB_VERSION_@0@_@1@'.format(
glib_min_version.split('.')[0], glib_min_version.split('.')[1])
common_cflags = cc.get_supported_arguments([
'-fgnu89-inline',
'-std=gnu99',
@@ -30,8 +33,8 @@ common_cflags = cc.get_supported_arguments([
'-Werror-implicit-function-declaration',
'-Wno-pointer-sign',
'-Wshadow',
'-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_50',
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_50',
'-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def,
'-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def,
])
# maintaining compatibility with the previous libtool versioning
@@ -43,15 +46,36 @@ revision = 0
libversion = '@0@.@1@.@2@'.format(soversion, current, revision)
# Dependencies
glib_dep = dependency('glib-2.0', version: '>= 2.50')
gio_dep = dependency('gio-unix-2.0', version: '>= 2.44.0')
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
gusb_dep = dependency('gusb', version: '>= 0.3.0')
mathlib_dep = cc.find_library('m', required: false)
# Drivers
drivers = get_option('drivers').split(',')
virtual_drivers = [ 'virtual_image' ]
default_drivers = [ 'upektc_img', 'vfs5011', 'aes3500', 'aes4000', 'aes1610', 'aes1660', 'aes2660', 'aes2501', 'aes2550', 'vfs101', 'vfs301', 'vfs0050', 'etes603', 'vcom5s', 'synaptics', 'elan', 'uru4000', 'upektc', 'upeksonly', 'upekts' ]
default_drivers = [
'upektc_img',
'vfs5011',
'aes3500',
'aes4000',
'aes1610',
'aes1660',
'aes2660',
'aes2501',
'aes2550',
'vfs101',
'vfs301',
'vfs0050',
'etes603',
'vcom5s',
'synaptics',
'elan',
'uru4000',
'upektc',
'upeksonly',
'upekts',
]
all_drivers = default_drivers + virtual_drivers
@@ -139,11 +163,10 @@ endif
pkgconfig = import('pkgconfig')
pkgconfig.generate(
name: 'libfprint',
description: 'Generic C API for fingerprint reader access',
version: meson.project_version(),
libraries: libfprint,
subdirs: 'libfprint',
filebase: 'libfprint2',
install_dir: join_paths(get_option('libdir'), 'pkgconfig'),
)
name: 'libfprint',
description: 'Generic C API for fingerprint reader access',
version: meson.project_version(),
libraries: libfprint,
subdirs: 'libfprint',
filebase: 'libfprint2',
install_dir: join_paths(get_option('libdir'), 'pkgconfig'))

View File

@@ -16,8 +16,7 @@ envs.set('NO_AT_BRIDGE', '1')
if get_option('introspection')
if 'virtual_image' in drivers
test(
'virtual-image',
test('virtual-image',
find_program('virtual-image.py'),
args: '--verbose',
env: envs,
@@ -25,25 +24,45 @@ if get_option('introspection')
)
endif
if 'vfs5011' in drivers
test(
'vfs5011',
find_program('umockdev-test.py'),
args: join_paths(meson.current_source_dir(), 'vfs5011'),
env: envs,
timeout: 10,
depends: libfprint_typelib,
)
endif
drivers_tests = [
'vfs5011',
'synaptics',
]
if 'synaptics' in drivers
test(
'synaptics',
foreach driver_test: drivers_tests
test(driver_test,
find_program('umockdev-test.py'),
args: join_paths(meson.current_source_dir(), 'synaptics'),
args: join_paths(meson.current_source_dir(), driver_test),
env: envs,
suite: ['drivers'],
timeout: 10,
depends: libfprint_typelib,
)
endif
endforeach
endif
gdb = find_program('gdb', required: false)
if gdb.found()
add_test_setup('gdb',
timeout_multiplier: 1000,
env: [
'LIBFPRINT_TEST_WRAPPER=@0@ --args'.format(
gdb.path())
])
endif
valgrind = find_program('valgrind', required: false)
if valgrind.found()
glib_share = glib_dep.get_pkgconfig_variable('prefix') / 'share' / glib_dep.name()
glib_suppressions = glib_share + '/valgrind/glib.supp'
python_suppressions = '@0@/@1@'.format(meson.source_root(),
files('valgrind-python.supp')[0])
add_test_setup('valgrind',
timeout_multiplier: 10,
env: [
'G_SLICE=always-malloc',
('LIBFPRINT_TEST_WRAPPER=@0@ --tool=memcheck --leak-check=full ' +
'--suppressions=@1@ --suppressions=@2@').format(
valgrind.path(), glib_suppressions, python_suppressions)
])
endif

View File

@@ -48,20 +48,28 @@ def cmp_pngs(png_a, png_b):
for x in range(img_a.get_width()):
for y in range(img_a.get_height()):
assert(data_a[y * stride + x * 4] == data_b[y * stride + x * 4])
# RGB24 format is endian dependent, using +1 means we test either
# the G or B component, which works on any endian for the greyscale
# test.
assert(data_a[y * stride + x * 4 + 1] == data_b[y * stride + x * 4 + 1])
def capture():
ioctl = os.path.join(ddir, "capture.ioctl")
def get_umockdev_runner(ioctl_basename):
ioctl = os.path.join(ddir, "{}.ioctl".format(ioctl_basename))
device = os.path.join(ddir, "device")
dev = open(ioctl).readline().strip()
assert dev.startswith('@DEV ')
dev = dev[5:]
subprocess.check_call(['umockdev-run', '-d', device,
'-i', "%s=%s" % (dev, ioctl),
'--',
'%s' % os.path.join(edir, "capture.py"),
'%s' % os.path.join(tmpdir, "capture.png")])
umockdev = ['umockdev-run', '-d', device,
'-i', "%s=%s" % (dev, ioctl),
'--']
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
return umockdev + (wrapper.split(' ') if wrapper else []) + [sys.executable]
def capture():
subprocess.check_call(get_umockdev_runner("capture") +
['%s' % os.path.join(edir, "capture.py"),
'%s' % os.path.join(tmpdir, "capture.png")])
assert os.path.isfile(os.path.join(tmpdir, "capture.png"))
if os.path.isfile(os.path.join(ddir, "capture.png")):
@@ -69,16 +77,8 @@ def capture():
cmp_pngs(os.path.join(tmpdir, "capture.png"), os.path.join(ddir, "capture.png"))
def custom():
ioctl = os.path.join(ddir, "custom.ioctl")
device = os.path.join(ddir, "device")
dev = open(ioctl).readline().strip()
assert dev.startswith('@DEV ')
dev = dev[5:]
subprocess.check_call(['umockdev-run', '-d', device,
'-i', "%s=%s" % (dev, ioctl),
'--',
'%s' % os.path.join(ddir, "custom.py")])
subprocess.check_call(get_umockdev_runner("custom") +
['%s' % os.path.join(ddir, "custom.py")])
try:
if os.path.exists(os.path.join(ddir, "capture.ioctl")):

View File

@@ -0,0 +1,55 @@
{
ignore_py_cond
Memcheck:Cond
...
fun:Py*
}
{
ignore__py_cond
Memcheck:Cond
...
fun:_Py*
}
{
ignore_py_value8
Memcheck:Value8
...
fun:Py*
}
{
ignore__py_value8
Memcheck:Value8
...
fun:_Py*
}
{
ignore_py_addr4
Memcheck:Addr4
...
fun:Py*
}
{
ignore__py_addr4
Memcheck:Addr4
...
fun:_Py*
}
{
ignore_py_leaks
Memcheck:Leak
...
fun:Py*
}
{
ignore__py_leaks
Memcheck:Leak
...
fun:_Py*
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -10,11 +10,20 @@ import sys
import unittest
import socket
import struct
import subprocess
import shutil
import glob
import cairo
import tempfile
# Re-run the test with the passed wrapper if set
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
if wrapper:
wrap_cmd = wrapper.split(' ') + [sys.executable, os.path.abspath(__file__)] + \
sys.argv[1:]
os.unsetenv('LIBFPRINT_TEST_WRAPPER')
sys.exit(subprocess.check_call(wrap_cmd))
class Connection:
def __init__(self, addr):
@@ -274,7 +283,6 @@ class VirtualImage(unittest.TestCase):
ctx.iteration(True)
assert(not self._verify_match)
# avoid writing to stderr
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))